├── .gitignore
├── portraits
├── Aldo.png
├── Bilp.png
├── Cid.png
├── Flit.png
├── Ken.png
├── Lion.png
├── Maat.png
├── Naji.png
├── Odin.png
├── Zeid.png
├── Altana.png
├── Annika.png
├── Apururu.png
├── Aquila.png
├── Arciela.png
├── Areuhat.png
├── Atomos.png
├── August.png
├── Ayame.png
├── Bahamut.png
├── Balamor.png
├── Brygid.png
├── Cassard.png
├── Curilla.png
├── Cynthia.png
├── Eamonn.png
├── Elivira.png
├── Emeline.png
├── Fenrir.png
├── Gadalar.png
├── Garuda.png
├── Gessho.png
├── Ghatsad.png
├── Gowam.png
├── Gumbah.png
├── Hades.png
├── Hilda.png
├── Ifrit.png
├── Ingrid.png
├── Iroha.png
├── Joachim.png
├── Kagero.png
├── Kipligg.png
├── Klara.png
├── Kumhau.png
├── Laila.png
├── Larzos.png
├── Levil.png
├── Luzaf.png
├── Margret.png
├── Marin.png
├── Mayakov.png
├── Melvien.png
├── Mnejing.png
├── Moogle.png
├── Morimar.png
├── Mutihb.png
├── Nyline.png
├── Oggbi.png
├── Olgald.png
├── Ovjang.png
├── Phoenix.png
├── Pieuje.png
├── Portia.png
├── Prishe.png
├── Qultada.png
├── Rahal.png
├── Ramuh.png
├── Razfahd.png
├── Rholont.png
├── Riautte.png
├── Shiva.png
├── Siren.png
├── Svenja.png
├── Tenzen.png
├── Teodor.png
├── Tiana.png
├── Titan.png
├── Trion.png
├── Ulmia.png
├── Verena.png
├── Volker.png
├── Wasuhd.png
├── Wyatt.png
├── Yazquhl.png
├── Ygnas.png
├── Zazarg.png
├── Zogbog.png
├── Zweeha.png
├── Abquhbah.png
├── Alaixion.png
├── Alexander.png
├── Altennia.png
├── Amchuchu.png
├── Andreine.png
├── Berghent.png
├── Cait Sith.png
├── Carbuncle.png
├── Chalvava.png
├── Cherukiki.png
├── Cornelia.png
├── Cyranuce.png
├── Darrcuiln.png
├── Degenhard.png
├── Diabolos.png
├── Fairaure.png
├── Fremilla.png
├── Fusilton.png
├── Gilgamesh.png
├── Gissenne.png
├── Gratzigg.png
├── Grav'iton.png
├── Grennith.png
├── Haudrale.png
├── Hildebert.png
├── Illisory.png
├── Iroha Red.png
├── Jayramus.png
├── Klythios.png
├── Koru-Moru.png
├── Kupofried.png
├── Laila (S).png
├── Leviathan.png
├── Lilisette.png
├── Machegue.png
├── Mathilde.png
├── Monberaux.png
├── Najelith.png
├── Nashmeira.png
├── Noillurie.png
├── Pollimio.png
├── Ragelise.png
├── Rainemard.png
├── Reginald.png
├── Rosulatia.png
├── Rukususu.png
├── Sajj'aka.png
├── Selh'teus.png
├── Sempurne.png
├── Shamonde.png
├── Shantotto.png
├── Susuroon.png
├── Valeriano.png
├── Vestillet.png
├── Vortimere.png
├── Yve'noile.png
├── Alphonimile.png
├── Ark Angel EV.png
├── Ark Angel GK.png
├── Ark Angel HM.png
├── Ark Angel MR.png
├── Ark Angel TT.png
├── Atori-Tutori.png
├── Chacharoon.png
├── D. Shantotto.png
├── Despachiaire.png
├── Eald'narche.png
├── Esha'ntarl.png
├── Estienneux.png
├── Excenmille.png
├── Ghyo Molkot.png
├── Gumbah (S).png
├── Ikhi Askamot.png
├── Iron Eater.png
├── Iruki-Waraki.png
├── Kam'lanaut.png
├── King Destin.png
├── Lady Lilith.png
├── Lhe Lhangavo.png
├── Maximilian.png
├── Mildaurion.png
├── Musto-Rusto.png
├── Nag'molada.png
├── Nanaa Mihgo.png
├── Nomad Moogle.png
├── Perih Vashai.png
├── Phillieulais.png
├── Prince Trion.png
├── Rhea Myuliah.png
├── Roh Latteh.png
├── Romaa Mihgo.png
├── Rongelouts.png
├── Shikaree Z.png
├── Shla Kheefid.png
├── The Keeper.png
├── Valaineral.png
├── Volker (S).png
├── Yoran-Oran.png
├── Young Aldo.png
├── Zonpa-Zippa.png
├── Ajido-Marujido.png
├── Cait Sith Aon.png
├── Cait Sith Coig.png
├── Cait Sith Dha.png
├── Cait Sith Naoi.png
├── Cait Sith Ochd.png
├── Cait Sith Sia.png
├── Cait Sith Tri.png
├── Chero-Machero.png
├── Dark Messenger.png
├── Excenmille (S).png
├── Karaha-Baruha.png
├── King Ranperre.png
├── King of Hearts.png
├── Kukki-Chebukki.png
├── Kupofried (S).png
├── Lehko Habhoka.png
├── Makki-Chebukki.png
├── Mathilde's Son.png
├── Mihli Aliapoh.png
├── Mufeh Hajrrha.png
├── Naja Salaheem.png
├── Nhev Befrathi.png
├── Ploh Trishbahk.png
├── Prince Pieuje.png
├── Rongelouts (S).png
├── Semih Lafihna.png
├── The Star Sybil.png
├── Tosuka-Porika.png
├── Tuffle-Buffle.png
├── Vhim Puralghi.png
├── Cait Sith Ceithir.png
├── Cait Sith Deich.png
├── Cait Sith Prime.png
├── Cait Sith Seachd.png
├── Cloud of Darkness.png
├── Jakoh Wahcondalo.png
├── Kuyin Hathdenna.png
├── Lilith Ascended.png
├── Maximilian Berger.png
├── Peladi Shalmohr.png
├── Perih Vashai (S).png
├── Portentous Woman.png
├── President Karst.png
├── Princess Claidie.png
├── The Shadow Lord.png
├── Ajido-Marujido (S).png
├── The Shadow Lord (S).png
└── Rongelouts N Distaud.png
├── themes
├── ffxi
│ ├── balloon.png
│ ├── name-bg.png
│ ├── system.png
│ ├── portrait-bg.png
│ ├── advance-prompt.png
│ ├── portrait-frame.png
│ └── theme.xml
├── default
│ ├── balloon.png
│ ├── name-bg.png
│ ├── system.png
│ ├── portrait-bg.png
│ ├── advance-prompt.png
│ ├── portrait-frame.png
│ └── theme.xml
├── ffvii-r
│ ├── balloon.png
│ ├── name-bg.png
│ ├── system.png
│ ├── portrait-bg.png
│ ├── advance-prompt.png
│ ├── portrait-frame.png
│ └── theme.xml
└── snes-ff
│ ├── balloon.png
│ ├── name-bg.png
│ ├── system.png
│ ├── advance-prompt.png
│ └── theme.xml
├── docs
├── AltanaView-posing.png
├── AltanaView-image-size.png
├── AltanaView-set-background.png
├── Portrait-Creation.md
└── Yuki-Notes.txt
├── defaults.lua
├── readme.txt
├── theme.lua
├── ui.lua
└── Balloon.lua
/.gitignore:
--------------------------------------------------------------------------------
1 | data/
2 | .vscode/
3 | *.bmp
4 | *.kra
5 | *.png~
--------------------------------------------------------------------------------
/portraits/Aldo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Aldo.png
--------------------------------------------------------------------------------
/portraits/Bilp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Bilp.png
--------------------------------------------------------------------------------
/portraits/Cid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cid.png
--------------------------------------------------------------------------------
/portraits/Flit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Flit.png
--------------------------------------------------------------------------------
/portraits/Ken.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ken.png
--------------------------------------------------------------------------------
/portraits/Lion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lion.png
--------------------------------------------------------------------------------
/portraits/Maat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Maat.png
--------------------------------------------------------------------------------
/portraits/Naji.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Naji.png
--------------------------------------------------------------------------------
/portraits/Odin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Odin.png
--------------------------------------------------------------------------------
/portraits/Zeid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Zeid.png
--------------------------------------------------------------------------------
/portraits/Altana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Altana.png
--------------------------------------------------------------------------------
/portraits/Annika.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Annika.png
--------------------------------------------------------------------------------
/portraits/Apururu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Apururu.png
--------------------------------------------------------------------------------
/portraits/Aquila.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Aquila.png
--------------------------------------------------------------------------------
/portraits/Arciela.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Arciela.png
--------------------------------------------------------------------------------
/portraits/Areuhat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Areuhat.png
--------------------------------------------------------------------------------
/portraits/Atomos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Atomos.png
--------------------------------------------------------------------------------
/portraits/August.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/August.png
--------------------------------------------------------------------------------
/portraits/Ayame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ayame.png
--------------------------------------------------------------------------------
/portraits/Bahamut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Bahamut.png
--------------------------------------------------------------------------------
/portraits/Balamor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Balamor.png
--------------------------------------------------------------------------------
/portraits/Brygid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Brygid.png
--------------------------------------------------------------------------------
/portraits/Cassard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cassard.png
--------------------------------------------------------------------------------
/portraits/Curilla.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Curilla.png
--------------------------------------------------------------------------------
/portraits/Cynthia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cynthia.png
--------------------------------------------------------------------------------
/portraits/Eamonn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Eamonn.png
--------------------------------------------------------------------------------
/portraits/Elivira.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Elivira.png
--------------------------------------------------------------------------------
/portraits/Emeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Emeline.png
--------------------------------------------------------------------------------
/portraits/Fenrir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Fenrir.png
--------------------------------------------------------------------------------
/portraits/Gadalar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gadalar.png
--------------------------------------------------------------------------------
/portraits/Garuda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Garuda.png
--------------------------------------------------------------------------------
/portraits/Gessho.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gessho.png
--------------------------------------------------------------------------------
/portraits/Ghatsad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ghatsad.png
--------------------------------------------------------------------------------
/portraits/Gowam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gowam.png
--------------------------------------------------------------------------------
/portraits/Gumbah.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gumbah.png
--------------------------------------------------------------------------------
/portraits/Hades.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Hades.png
--------------------------------------------------------------------------------
/portraits/Hilda.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Hilda.png
--------------------------------------------------------------------------------
/portraits/Ifrit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ifrit.png
--------------------------------------------------------------------------------
/portraits/Ingrid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ingrid.png
--------------------------------------------------------------------------------
/portraits/Iroha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Iroha.png
--------------------------------------------------------------------------------
/portraits/Joachim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Joachim.png
--------------------------------------------------------------------------------
/portraits/Kagero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kagero.png
--------------------------------------------------------------------------------
/portraits/Kipligg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kipligg.png
--------------------------------------------------------------------------------
/portraits/Klara.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Klara.png
--------------------------------------------------------------------------------
/portraits/Kumhau.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kumhau.png
--------------------------------------------------------------------------------
/portraits/Laila.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Laila.png
--------------------------------------------------------------------------------
/portraits/Larzos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Larzos.png
--------------------------------------------------------------------------------
/portraits/Levil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Levil.png
--------------------------------------------------------------------------------
/portraits/Luzaf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Luzaf.png
--------------------------------------------------------------------------------
/portraits/Margret.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Margret.png
--------------------------------------------------------------------------------
/portraits/Marin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Marin.png
--------------------------------------------------------------------------------
/portraits/Mayakov.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mayakov.png
--------------------------------------------------------------------------------
/portraits/Melvien.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Melvien.png
--------------------------------------------------------------------------------
/portraits/Mnejing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mnejing.png
--------------------------------------------------------------------------------
/portraits/Moogle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Moogle.png
--------------------------------------------------------------------------------
/portraits/Morimar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Morimar.png
--------------------------------------------------------------------------------
/portraits/Mutihb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mutihb.png
--------------------------------------------------------------------------------
/portraits/Nyline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nyline.png
--------------------------------------------------------------------------------
/portraits/Oggbi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Oggbi.png
--------------------------------------------------------------------------------
/portraits/Olgald.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Olgald.png
--------------------------------------------------------------------------------
/portraits/Ovjang.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ovjang.png
--------------------------------------------------------------------------------
/portraits/Phoenix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Phoenix.png
--------------------------------------------------------------------------------
/portraits/Pieuje.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Pieuje.png
--------------------------------------------------------------------------------
/portraits/Portia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Portia.png
--------------------------------------------------------------------------------
/portraits/Prishe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Prishe.png
--------------------------------------------------------------------------------
/portraits/Qultada.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Qultada.png
--------------------------------------------------------------------------------
/portraits/Rahal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rahal.png
--------------------------------------------------------------------------------
/portraits/Ramuh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ramuh.png
--------------------------------------------------------------------------------
/portraits/Razfahd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Razfahd.png
--------------------------------------------------------------------------------
/portraits/Rholont.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rholont.png
--------------------------------------------------------------------------------
/portraits/Riautte.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Riautte.png
--------------------------------------------------------------------------------
/portraits/Shiva.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Shiva.png
--------------------------------------------------------------------------------
/portraits/Siren.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Siren.png
--------------------------------------------------------------------------------
/portraits/Svenja.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Svenja.png
--------------------------------------------------------------------------------
/portraits/Tenzen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Tenzen.png
--------------------------------------------------------------------------------
/portraits/Teodor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Teodor.png
--------------------------------------------------------------------------------
/portraits/Tiana.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Tiana.png
--------------------------------------------------------------------------------
/portraits/Titan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Titan.png
--------------------------------------------------------------------------------
/portraits/Trion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Trion.png
--------------------------------------------------------------------------------
/portraits/Ulmia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ulmia.png
--------------------------------------------------------------------------------
/portraits/Verena.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Verena.png
--------------------------------------------------------------------------------
/portraits/Volker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Volker.png
--------------------------------------------------------------------------------
/portraits/Wasuhd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Wasuhd.png
--------------------------------------------------------------------------------
/portraits/Wyatt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Wyatt.png
--------------------------------------------------------------------------------
/portraits/Yazquhl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Yazquhl.png
--------------------------------------------------------------------------------
/portraits/Ygnas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ygnas.png
--------------------------------------------------------------------------------
/portraits/Zazarg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Zazarg.png
--------------------------------------------------------------------------------
/portraits/Zogbog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Zogbog.png
--------------------------------------------------------------------------------
/portraits/Zweeha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Zweeha.png
--------------------------------------------------------------------------------
/portraits/Abquhbah.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Abquhbah.png
--------------------------------------------------------------------------------
/portraits/Alaixion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Alaixion.png
--------------------------------------------------------------------------------
/portraits/Alexander.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Alexander.png
--------------------------------------------------------------------------------
/portraits/Altennia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Altennia.png
--------------------------------------------------------------------------------
/portraits/Amchuchu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Amchuchu.png
--------------------------------------------------------------------------------
/portraits/Andreine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Andreine.png
--------------------------------------------------------------------------------
/portraits/Berghent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Berghent.png
--------------------------------------------------------------------------------
/portraits/Cait Sith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith.png
--------------------------------------------------------------------------------
/portraits/Carbuncle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Carbuncle.png
--------------------------------------------------------------------------------
/portraits/Chalvava.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Chalvava.png
--------------------------------------------------------------------------------
/portraits/Cherukiki.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cherukiki.png
--------------------------------------------------------------------------------
/portraits/Cornelia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cornelia.png
--------------------------------------------------------------------------------
/portraits/Cyranuce.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cyranuce.png
--------------------------------------------------------------------------------
/portraits/Darrcuiln.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Darrcuiln.png
--------------------------------------------------------------------------------
/portraits/Degenhard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Degenhard.png
--------------------------------------------------------------------------------
/portraits/Diabolos.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Diabolos.png
--------------------------------------------------------------------------------
/portraits/Fairaure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Fairaure.png
--------------------------------------------------------------------------------
/portraits/Fremilla.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Fremilla.png
--------------------------------------------------------------------------------
/portraits/Fusilton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Fusilton.png
--------------------------------------------------------------------------------
/portraits/Gilgamesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gilgamesh.png
--------------------------------------------------------------------------------
/portraits/Gissenne.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gissenne.png
--------------------------------------------------------------------------------
/portraits/Gratzigg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gratzigg.png
--------------------------------------------------------------------------------
/portraits/Grav'iton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Grav'iton.png
--------------------------------------------------------------------------------
/portraits/Grennith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Grennith.png
--------------------------------------------------------------------------------
/portraits/Haudrale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Haudrale.png
--------------------------------------------------------------------------------
/portraits/Hildebert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Hildebert.png
--------------------------------------------------------------------------------
/portraits/Illisory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Illisory.png
--------------------------------------------------------------------------------
/portraits/Iroha Red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Iroha Red.png
--------------------------------------------------------------------------------
/portraits/Jayramus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Jayramus.png
--------------------------------------------------------------------------------
/portraits/Klythios.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Klythios.png
--------------------------------------------------------------------------------
/portraits/Koru-Moru.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Koru-Moru.png
--------------------------------------------------------------------------------
/portraits/Kupofried.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kupofried.png
--------------------------------------------------------------------------------
/portraits/Laila (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Laila (S).png
--------------------------------------------------------------------------------
/portraits/Leviathan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Leviathan.png
--------------------------------------------------------------------------------
/portraits/Lilisette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lilisette.png
--------------------------------------------------------------------------------
/portraits/Machegue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Machegue.png
--------------------------------------------------------------------------------
/portraits/Mathilde.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mathilde.png
--------------------------------------------------------------------------------
/portraits/Monberaux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Monberaux.png
--------------------------------------------------------------------------------
/portraits/Najelith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Najelith.png
--------------------------------------------------------------------------------
/portraits/Nashmeira.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nashmeira.png
--------------------------------------------------------------------------------
/portraits/Noillurie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Noillurie.png
--------------------------------------------------------------------------------
/portraits/Pollimio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Pollimio.png
--------------------------------------------------------------------------------
/portraits/Ragelise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ragelise.png
--------------------------------------------------------------------------------
/portraits/Rainemard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rainemard.png
--------------------------------------------------------------------------------
/portraits/Reginald.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Reginald.png
--------------------------------------------------------------------------------
/portraits/Rosulatia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rosulatia.png
--------------------------------------------------------------------------------
/portraits/Rukususu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rukususu.png
--------------------------------------------------------------------------------
/portraits/Sajj'aka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Sajj'aka.png
--------------------------------------------------------------------------------
/portraits/Selh'teus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Selh'teus.png
--------------------------------------------------------------------------------
/portraits/Sempurne.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Sempurne.png
--------------------------------------------------------------------------------
/portraits/Shamonde.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Shamonde.png
--------------------------------------------------------------------------------
/portraits/Shantotto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Shantotto.png
--------------------------------------------------------------------------------
/portraits/Susuroon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Susuroon.png
--------------------------------------------------------------------------------
/portraits/Valeriano.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Valeriano.png
--------------------------------------------------------------------------------
/portraits/Vestillet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Vestillet.png
--------------------------------------------------------------------------------
/portraits/Vortimere.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Vortimere.png
--------------------------------------------------------------------------------
/portraits/Yve'noile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Yve'noile.png
--------------------------------------------------------------------------------
/themes/ffxi/balloon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/balloon.png
--------------------------------------------------------------------------------
/themes/ffxi/name-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/name-bg.png
--------------------------------------------------------------------------------
/themes/ffxi/system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/system.png
--------------------------------------------------------------------------------
/docs/AltanaView-posing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/docs/AltanaView-posing.png
--------------------------------------------------------------------------------
/portraits/Alphonimile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Alphonimile.png
--------------------------------------------------------------------------------
/portraits/Ark Angel EV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ark Angel EV.png
--------------------------------------------------------------------------------
/portraits/Ark Angel GK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ark Angel GK.png
--------------------------------------------------------------------------------
/portraits/Ark Angel HM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ark Angel HM.png
--------------------------------------------------------------------------------
/portraits/Ark Angel MR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ark Angel MR.png
--------------------------------------------------------------------------------
/portraits/Ark Angel TT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ark Angel TT.png
--------------------------------------------------------------------------------
/portraits/Atori-Tutori.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Atori-Tutori.png
--------------------------------------------------------------------------------
/portraits/Chacharoon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Chacharoon.png
--------------------------------------------------------------------------------
/portraits/D. Shantotto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/D. Shantotto.png
--------------------------------------------------------------------------------
/portraits/Despachiaire.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Despachiaire.png
--------------------------------------------------------------------------------
/portraits/Eald'narche.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Eald'narche.png
--------------------------------------------------------------------------------
/portraits/Esha'ntarl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Esha'ntarl.png
--------------------------------------------------------------------------------
/portraits/Estienneux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Estienneux.png
--------------------------------------------------------------------------------
/portraits/Excenmille.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Excenmille.png
--------------------------------------------------------------------------------
/portraits/Ghyo Molkot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ghyo Molkot.png
--------------------------------------------------------------------------------
/portraits/Gumbah (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Gumbah (S).png
--------------------------------------------------------------------------------
/portraits/Ikhi Askamot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ikhi Askamot.png
--------------------------------------------------------------------------------
/portraits/Iron Eater.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Iron Eater.png
--------------------------------------------------------------------------------
/portraits/Iruki-Waraki.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Iruki-Waraki.png
--------------------------------------------------------------------------------
/portraits/Kam'lanaut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kam'lanaut.png
--------------------------------------------------------------------------------
/portraits/King Destin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/King Destin.png
--------------------------------------------------------------------------------
/portraits/Lady Lilith.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lady Lilith.png
--------------------------------------------------------------------------------
/portraits/Lhe Lhangavo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lhe Lhangavo.png
--------------------------------------------------------------------------------
/portraits/Maximilian.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Maximilian.png
--------------------------------------------------------------------------------
/portraits/Mildaurion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mildaurion.png
--------------------------------------------------------------------------------
/portraits/Musto-Rusto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Musto-Rusto.png
--------------------------------------------------------------------------------
/portraits/Nag'molada.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nag'molada.png
--------------------------------------------------------------------------------
/portraits/Nanaa Mihgo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nanaa Mihgo.png
--------------------------------------------------------------------------------
/portraits/Nomad Moogle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nomad Moogle.png
--------------------------------------------------------------------------------
/portraits/Perih Vashai.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Perih Vashai.png
--------------------------------------------------------------------------------
/portraits/Phillieulais.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Phillieulais.png
--------------------------------------------------------------------------------
/portraits/Prince Trion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Prince Trion.png
--------------------------------------------------------------------------------
/portraits/Rhea Myuliah.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rhea Myuliah.png
--------------------------------------------------------------------------------
/portraits/Roh Latteh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Roh Latteh.png
--------------------------------------------------------------------------------
/portraits/Romaa Mihgo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Romaa Mihgo.png
--------------------------------------------------------------------------------
/portraits/Rongelouts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rongelouts.png
--------------------------------------------------------------------------------
/portraits/Shikaree Z.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Shikaree Z.png
--------------------------------------------------------------------------------
/portraits/Shla Kheefid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Shla Kheefid.png
--------------------------------------------------------------------------------
/portraits/The Keeper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/The Keeper.png
--------------------------------------------------------------------------------
/portraits/Valaineral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Valaineral.png
--------------------------------------------------------------------------------
/portraits/Volker (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Volker (S).png
--------------------------------------------------------------------------------
/portraits/Yoran-Oran.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Yoran-Oran.png
--------------------------------------------------------------------------------
/portraits/Young Aldo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Young Aldo.png
--------------------------------------------------------------------------------
/portraits/Zonpa-Zippa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Zonpa-Zippa.png
--------------------------------------------------------------------------------
/themes/default/balloon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/balloon.png
--------------------------------------------------------------------------------
/themes/default/name-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/name-bg.png
--------------------------------------------------------------------------------
/themes/default/system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/system.png
--------------------------------------------------------------------------------
/themes/ffvii-r/balloon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/balloon.png
--------------------------------------------------------------------------------
/themes/ffvii-r/name-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/name-bg.png
--------------------------------------------------------------------------------
/themes/ffvii-r/system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/system.png
--------------------------------------------------------------------------------
/themes/snes-ff/balloon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/snes-ff/balloon.png
--------------------------------------------------------------------------------
/themes/snes-ff/name-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/snes-ff/name-bg.png
--------------------------------------------------------------------------------
/themes/snes-ff/system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/snes-ff/system.png
--------------------------------------------------------------------------------
/portraits/Ajido-Marujido.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ajido-Marujido.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Aon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Aon.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Coig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Coig.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Dha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Dha.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Naoi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Naoi.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Ochd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Ochd.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Sia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Sia.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Tri.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Tri.png
--------------------------------------------------------------------------------
/portraits/Chero-Machero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Chero-Machero.png
--------------------------------------------------------------------------------
/portraits/Dark Messenger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Dark Messenger.png
--------------------------------------------------------------------------------
/portraits/Excenmille (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Excenmille (S).png
--------------------------------------------------------------------------------
/portraits/Karaha-Baruha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Karaha-Baruha.png
--------------------------------------------------------------------------------
/portraits/King Ranperre.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/King Ranperre.png
--------------------------------------------------------------------------------
/portraits/King of Hearts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/King of Hearts.png
--------------------------------------------------------------------------------
/portraits/Kukki-Chebukki.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kukki-Chebukki.png
--------------------------------------------------------------------------------
/portraits/Kupofried (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kupofried (S).png
--------------------------------------------------------------------------------
/portraits/Lehko Habhoka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lehko Habhoka.png
--------------------------------------------------------------------------------
/portraits/Makki-Chebukki.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Makki-Chebukki.png
--------------------------------------------------------------------------------
/portraits/Mathilde's Son.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mathilde's Son.png
--------------------------------------------------------------------------------
/portraits/Mihli Aliapoh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mihli Aliapoh.png
--------------------------------------------------------------------------------
/portraits/Mufeh Hajrrha.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Mufeh Hajrrha.png
--------------------------------------------------------------------------------
/portraits/Naja Salaheem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Naja Salaheem.png
--------------------------------------------------------------------------------
/portraits/Nhev Befrathi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Nhev Befrathi.png
--------------------------------------------------------------------------------
/portraits/Ploh Trishbahk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ploh Trishbahk.png
--------------------------------------------------------------------------------
/portraits/Prince Pieuje.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Prince Pieuje.png
--------------------------------------------------------------------------------
/portraits/Rongelouts (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rongelouts (S).png
--------------------------------------------------------------------------------
/portraits/Semih Lafihna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Semih Lafihna.png
--------------------------------------------------------------------------------
/portraits/The Star Sybil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/The Star Sybil.png
--------------------------------------------------------------------------------
/portraits/Tosuka-Porika.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Tosuka-Porika.png
--------------------------------------------------------------------------------
/portraits/Tuffle-Buffle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Tuffle-Buffle.png
--------------------------------------------------------------------------------
/portraits/Vhim Puralghi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Vhim Puralghi.png
--------------------------------------------------------------------------------
/themes/ffxi/portrait-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/portrait-bg.png
--------------------------------------------------------------------------------
/docs/AltanaView-image-size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/docs/AltanaView-image-size.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Ceithir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Ceithir.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Deich.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Deich.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Prime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Prime.png
--------------------------------------------------------------------------------
/portraits/Cait Sith Seachd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cait Sith Seachd.png
--------------------------------------------------------------------------------
/portraits/Cloud of Darkness.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Cloud of Darkness.png
--------------------------------------------------------------------------------
/portraits/Jakoh Wahcondalo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Jakoh Wahcondalo.png
--------------------------------------------------------------------------------
/portraits/Kuyin Hathdenna.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Kuyin Hathdenna.png
--------------------------------------------------------------------------------
/portraits/Lilith Ascended.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Lilith Ascended.png
--------------------------------------------------------------------------------
/portraits/Maximilian Berger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Maximilian Berger.png
--------------------------------------------------------------------------------
/portraits/Peladi Shalmohr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Peladi Shalmohr.png
--------------------------------------------------------------------------------
/portraits/Perih Vashai (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Perih Vashai (S).png
--------------------------------------------------------------------------------
/portraits/Portentous Woman.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Portentous Woman.png
--------------------------------------------------------------------------------
/portraits/President Karst.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/President Karst.png
--------------------------------------------------------------------------------
/portraits/Princess Claidie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Princess Claidie.png
--------------------------------------------------------------------------------
/portraits/The Shadow Lord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/The Shadow Lord.png
--------------------------------------------------------------------------------
/themes/default/portrait-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/portrait-bg.png
--------------------------------------------------------------------------------
/themes/ffvii-r/portrait-bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/portrait-bg.png
--------------------------------------------------------------------------------
/themes/ffxi/advance-prompt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/advance-prompt.png
--------------------------------------------------------------------------------
/themes/ffxi/portrait-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffxi/portrait-frame.png
--------------------------------------------------------------------------------
/portraits/Ajido-Marujido (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Ajido-Marujido (S).png
--------------------------------------------------------------------------------
/portraits/The Shadow Lord (S).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/The Shadow Lord (S).png
--------------------------------------------------------------------------------
/themes/default/advance-prompt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/advance-prompt.png
--------------------------------------------------------------------------------
/themes/default/portrait-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/default/portrait-frame.png
--------------------------------------------------------------------------------
/themes/ffvii-r/advance-prompt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/advance-prompt.png
--------------------------------------------------------------------------------
/themes/ffvii-r/portrait-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/ffvii-r/portrait-frame.png
--------------------------------------------------------------------------------
/themes/snes-ff/advance-prompt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/themes/snes-ff/advance-prompt.png
--------------------------------------------------------------------------------
/docs/AltanaView-set-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/docs/AltanaView-set-background.png
--------------------------------------------------------------------------------
/portraits/Rongelouts N Distaud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StarlitGhost/Balloon/HEAD/portraits/Rongelouts N Distaud.png
--------------------------------------------------------------------------------
/defaults.lua:
--------------------------------------------------------------------------------
1 | local defaults = {}
2 |
3 | defaults.DisplayMode = 2
4 | defaults.MovementCloses = false
5 | defaults.NoPromptCloseDelay = 10
6 | defaults.AnimatePrompt = true
7 | defaults.TextSpeed = 10
8 | defaults.Theme = 'default'
9 | defaults.Scale = 1.0
10 | defaults.ShowPortraits = true
11 |
12 | local windower_settings = windower.get_windower_settings()
13 | defaults.Position = {}
14 | defaults.Position.X = windower_settings.ui_x_res / 2
15 | defaults.Position.Y = windower_settings.ui_y_res - 258
16 |
17 | return defaults
--------------------------------------------------------------------------------
/docs/Portrait-Creation.md:
--------------------------------------------------------------------------------
1 | # Character Portrait Creation
2 |
3 | This is how I made all the portraits in my portrait pack, but you could do this in many different ways if you're more comfortable with other tools.
4 |
5 | However you make your portraits, I suggest making them 256x256 pixels to match with other packs people might make. Themes can scale them however they like, but it's good to use a common base size.
6 |
7 | ## AltanaView
8 | Make sure the background is set to 0,255,0 (neon green).
9 |
10 | 
11 |
12 | Adjust the frame size and do `File -> Save Image...` repeatedly until it saves at 256x256 pixels - I wish AltanaView just showed the dimensions in the window D:
13 |
14 | 
15 |
16 | Load up the NPC you'd like to create a portrait of, and move them around to get a good portrait pose.
17 | `File -> Pause` helps if their animations move them around a lot.
18 |
19 | 
20 |
21 | `File -> Save Image...` and name the file with the NPC's name, eg: Iroha.bmp
22 |
23 | ## Converting to transparent PNGs with ImageMagick
24 | ### Linux/WSL
25 | You'll need ImageMagick installed on your Linux distro for this.
26 |
27 | Open up a terminal and navigate to the directory where you saved your portraits.
28 |
29 | Convert them to png, replacing neon green with transparency:
30 | ```sh
31 | find ./ -maxdepth 1 -name "*.bmp" -type f -exec sh -c 'convert "$1" -fuzz 5% -channel rgba -fill none -opaque "#00FF00" "${1%bmp}png"' sh {} \;
32 | ```
33 | Optionally remove all bmp files after converting:
34 | ```sh
35 | rm *.bmp
36 | ```
37 | You're done!
38 |
39 | ### Windows
40 | _todo instructions_
--------------------------------------------------------------------------------
/themes/ffxi/theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Meiryo
6 | Meiryo
7 | 13
8 | 360
9 | 43
10 | -8
11 | -18
12 | 30
13 | -13
14 |
15 | 255
16 | 255
17 | 245
18 | 235
19 |
20 |
21 | 200
22 | 0
23 | 0
24 | 0
25 | 2
26 |
27 |
28 |
29 | Meiryo
30 | Meiryo
31 | 10
32 | 81
33 | 610
34 | 128
35 | 10
36 | -8
37 |
38 |
39 | 255
40 | 255
41 | 255
42 | 255
43 |
44 | 255,50,255
45 | 100,255,100
46 | 100,150,255
47 | 255,140,0
48 |
49 | 200
50 | 0
51 | 0
52 | 0
53 | 1
54 |
55 |
56 |
57 |
58 | 26
59 | 16
60 | 575
61 | 105
62 |
63 |
64 | 580
65 | 100
66 |
67 |
68 | 96
69 | 96
70 | 0
71 | -96
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/themes/snes-ff/theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | DePixel
6 | Meiryo
7 | 9
8 | 254
9 | 43
10 | 15
11 | -30
12 | 25
13 | -24
14 |
15 | 255
16 | 255
17 | 255
18 | 255
19 |
20 |
21 | 200
22 | 0
23 | 0
24 | 0
25 | 2
26 |
27 |
28 |
29 | DePixel
30 | Meiryo
31 | 8
32 | 75
33 | 660
34 | 142
35 | 22
36 | -5
37 |
38 |
39 | 255
40 | 255
41 | 255
42 | 255
43 |
44 | 255,50,255
45 | 100,255,100
46 | 100,150,255
47 | 255,140,0
48 |
49 |
50 |
51 | 255
52 | 255
53 | 255
54 | 255
55 |
56 | 255,50,255
57 | 100,255,100
58 | 100,150,255
59 | 255,140,0
60 |
61 |
62 |
63 | 30
64 | 20
65 | 620
66 | 120
67 |
68 |
69 | 620
70 | 110
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/themes/ffvii-r/theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Libre Franklin Medium
6 | Meiryo
7 | 13
8 | 200
9 | 2
10 | 8
11 | -1
12 | 2
13 | -28
14 |
15 | 255
16 | 255
17 | 255
18 | 255
19 |
20 |
21 | 150
22 | 0
23 | 0
24 | 0
25 | 1.5
26 |
27 |
28 |
29 | Libre Franklin Medium
30 | Meiryo
31 | 13
32 | 75
33 | 800
34 | 150
35 | 50
36 | -18
37 |
38 |
39 | 255
40 | 255
41 | 255
42 | 255
43 |
44 | 255,50,255
45 | 100,255,100
46 | 100,150,255
47 | 255,140,0
48 | 125,175,255
49 |
50 | 150
51 | 0
52 | 0
53 | 0
54 | 1.5
55 |
56 |
57 |
58 |
59 | 36
60 | 36
61 | 750
62 | 0
63 |
64 |
65 | 750
66 | 0
67 |
68 |
69 | 96
70 | 96
71 | 0
72 | -95
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/themes/default/theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Meiryo
6 | Meiryo
7 | 12
8 | 360
9 | 43
10 | 10
11 | -23
12 | 45
13 | -15
14 |
15 | 255
16 | 255
17 | 255
18 | 255
19 |
20 |
21 | 200
22 | 0
23 | 0
24 | 0
25 | 2
26 |
27 |
28 |
29 | Meiryo
30 | Meiryo
31 | 10
32 | 81
33 | 647
34 | 127
35 | 45
36 | -8
37 |
38 |
39 | 255
40 | 0
41 | 0
42 | 0
43 |
44 | 177,26,177
45 | 84,155,17
46 | 97,127,217
47 | 173,72,0
48 |
49 |
50 |
51 | 255
52 | 255
53 | 255
54 | 255
55 |
56 | 255,50,255
57 | 100,255,100
58 | 100,150,255
59 | 255,140,0
60 |
61 |
62 |
63 | 13
64 | 21
65 | 600
66 | 90
67 |
68 |
69 | 580
70 | 100
71 |
72 | 255
73 | 255
74 | 255
75 | 255
76 |
77 |
78 | 150
79 | 0
80 | 0
81 | 0
82 | 1.5
83 |
84 |
85 |
86 | 96
87 | 96
88 | 33
89 | 17
90 | 64
91 | 135
92 | -8
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/docs/Yuki-Notes.txt:
--------------------------------------------------------------------------------
1 | Balloon ver 0.8
2 | ---------------
3 |
4 | I saw this addon about 18 months ago (Jan. 2020) and intermittently made modifications to it as it looked amazing in the Youtube video linked below, but it didn't play well with the English client.
5 |
6 | https://www.youtube.com/watch?v=VhEvdX9xwpw
7 |
8 | After some digging I eventually found the author's webpage:
9 |
10 | http://handomadex.blog.fc2.com/
11 |
12 | ...With the Balloon addon release page:
13 |
14 | http://handomadex.blog.fc2.com/blog-entry-354.html
15 |
16 | Having never used Lua it was extremely challenging learning about string handling, events and other arcane (to me) topics to understand the code and add features successfully. Thanks to (among others) Kenshi, Rubenator, Arcon, Chaia from the Windower Discord for their help and suggestions and answers to some of my inane questions.
17 |
18 | Thanks most of all to Hando for making a wonderful add-on that really enhances the game if you're playing through the story.
19 |
20 | -----
21 |
22 | The code I've added or modified just about works. I'm terrible at commenting code, and even worse at keeping revisions. This was brought to its current state on and off over a period of 12 months or so with frequent gaps in development. There will be bugs. I've caught the worst I think, but a couple that I know about and will hopefully get to:
23 |
24 | - If you rescale your UI in Windower or FFXI config, the balloon may disappear. //bl reset to set to default position, scaling is taken into account. (not really a bug but heyho)
25 | - Won't work terribly well with a gamepad - there's no way to read a gamepad button from Windower. Basically this boils down to some balloons staying on screen when they should have disappeared - use the enter key on the keyboard.
26 |
27 | To-do list:
28 |
29 | - Move parameters into settings.xml including font choice, font size, number of characters on a line.
30 | - Make the FFXIDB minimap go away during a cutscene.
31 | - Same for enemybar.
32 | - Add an advancement prompt for balloons that require it (possibly animated).
33 |
34 | Feedback is welcome using the details in readme.txt
35 |
36 | --
37 | Yuki
38 | August 2021
39 |
40 | -----------------------------------------------------
41 |
42 | Balloon ver 0.8
43 | ---------------
44 |
45 | このアドオンは約18か月前(2020年1月)に見たもので、下にリンクされているYouTubeビデオで見栄えがするため、断続的に変更を加えましたが、英語のクライアントではうまく機能しませんでした。
46 |
47 | https://www.youtube.com/watch?v=VhEvdX9xwpw
48 |
49 | 少し掘り下げた後、私は最終的に著者のウェブページを見つけました:
50 |
51 | http://handomadex.blog.fc2.com/
52 |
53 | ... Balloonアドオンリリースページの場合:
54 |
55 | http://handomadex.blog.fc2.com/blog-entry-354.html
56 |
57 | Luaを使用したことがないので、コードを理解して機能を正常に追加するために、文字列の処理、イベント、およびその他の難解な(私にとって)トピックについて学ぶことは非常に困難でした。 Windower DiscordのKenshi、Rubenator、Arcon、Chaiaの助けと提案、そして私の非常識な質問への回答に(とりわけ)感謝します。
58 |
59 | ストーリーをプレイしている場合にゲームを本当に強化する素晴らしいアドオンを作成してくれたHandoに何よりも感謝します。
60 |
61 | -----
62 |
63 | 私が追加または変更したコードは、ほぼ機能します。私はコードにコメントするのがひどく、改訂を維持するのがさらに悪いです。これは、開発に頻繁なギャップがあり、12か月ほどの期間にわたってオンとオフの現在の状態になりました。バグがあります。私は私が思う最悪の事態を捕らえましたが、私が知っている、そしてうまくいけば次のようなカップルがいます。
64 |
65 | -WindowerまたはFFXI構成でUIを再スケーリングすると、バルーンが消える場合があります。 // blをリセットしてデフォルトの位置に設定し、スケーリングが考慮されます。 (実際にはバグではありませんが、ちょっと)
66 | -ゲームパッドではひどくうまく機能しません-Windowerからゲームパッドボタンを読み取る方法はありません。基本的に、これは、バルーンが消えるはずのときに画面に表示されたままになるいくつかのバルーンに要約されます。キーボードのEnterキーを使用します。
67 |
68 | やることリスト:
69 |
70 | -フォントの選択、フォントサイズ、行の文字数などのパラメータをsettings.xmlに移動します。
71 | -カットシーン中にFFXIDBミニマップを非表示にします。
72 | -敵バーについても同じです。
73 | -それを必要とする(おそらくアニメーション化された)バルーンの前進プロンプトを追加します。
74 |
75 | readme.txtの詳細を使用してフィードバックを歓迎します
76 |
77 | -
78 | Yuki
79 | 2021年8月
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | Windower4 非公式アドオン Balloon
2 |
3 | ■機能
4 | 通常のNPCのセリフを吹き出し表示します。
5 |
6 | ■コマンド Balloon
7 | //Bl 0
8 | 通常のモードになります。吹き出し無し。ログ表示。
9 | //Bl 1
10 | 吹き出し表示。ログ非表示。
11 | //Bl 2
12 | 吹き出し表示。ログ表示。
13 | //Bl reset
14 | 表示位置初期化。
15 | //Bl help
16 | ヘルプ表示
17 |
18 | ■補足
19 | 表示位置は吹き出しが表示されている間にマウスで調整が可能です。
20 | 現在ログ非表示であっても、ボタン待ちの関係で空白1行分ログが進んでしまいます。
21 |
22 | デフォルトのフォントはSegoeUIになりました。
23 |
24 | [ver 0.8以降のバージョン履歴は、英語のテキストから機械翻訳されています。 読みづらい場合はごめんなさい。]
25 | ------------------------------------------------------------------------
26 | ■更新履歴
27 | ver 0.1 とりあえず完成。
28 | ver 0.2 UIスケール設定に対応。マウスで位置調整に対応。
29 | ver 0.3 吹き出しに表示されるゴミを出ないように。
30 | ver 0.4 さらにゴミ取りを行いました。デフォルトのテキストをしねきゃぷしょんからMS ゴシックへ変更しました。
31 | ver 0.5 吹き出し位置を変更した時に位置が保存されない不具合の修正。
32 | ver 0.6 さらにゴミ文字を削除(ご協力eyes様)。色がついた文字に対応。メッセージの位置微調整。
33 | 対応メッセージを追加。キャラクターが移動すると強制的に吹き出しが閉じる処理を追加。内部処理を変更。
34 | ver 0.7 英語サポートを追加するためのYukiによる最初の変更。 翻訳されたヘルプテキスト。
35 | キャラクターをロックしないNPCダイアログが5秒間画面に表示されたまま、移動できるようにする機能が追加されました。
36 | 上記は、進行を促さないダイアログラインを持つカットシーンで機能するはずです。
37 | 追加のイベントタイプが追加されました-インタラクションなしでバックグラウンドで発生するNPCダイアログもバルーンに表示されるようになりました。
38 | デフォルトのフォントがSegoeUIに変更されました(実行方法:Luaを編集せずにこのユーザーを構成可能にします)。
39 | Kenshiが提供する文字列チョッピングコード(Kenshiに感謝します!)
40 | ver 0.8 25/8/21英語クライアント(Yuki)の初公開。
41 | 文字列チョッピングコードを交換して、HandoとKenshiのオリジナル作品をミックスし、カラーコードなどへの置き換えを容易にしました。
42 | 同等のテキストの代わりに要素記号(Synergy Engineerと話す場合など)を追加しました。
43 | 多くの条件付きデバッグ出力を追加しました-バックグラウンドで何が起こっているかを確認したい場合は、// bl debug1または// bl debug2を使用してください。出力はコンソールウィンドウにあります。
44 | バルーンが表示されるとすぐに閉じていた(おそらく)バグを修正しました。
45 |
46 | ■作者
47 | 反動
48 |
49 |
50 | ------------------------------------------------------------------------
51 |
52 | Windower4 unofficial add-on Balloon
53 |
54 | ■ Function
55 | The lines of a normal NPC are displayed in a balloon.
56 |
57 | ■ Command Balloon
58 | //Bl 0
59 | It will be in normal mode. No balloon. Log display.
60 | //Bl 1
61 | Balloon display. Log hidden.
62 | //Bl 2
63 | Balloon display. Log display.
64 | //Bl reset
65 | Display position initialization.
66 | //Bl theme
67 | Loads the specified theme folder found under themes/
68 | //Bl scale
69 | Scales the size of the balloon by a decimal (eg: 1.5)
70 | //Bl delay
71 | Delay before closing promptless balloons.
72 | //Bl move_closes
73 | Toggles closing balloons on movement.
74 | //Bl animate
75 | Toggle advancement prompt animation.
76 | //Bl portrait
77 | Toggle character portraits.
78 | //Bl help
79 | Help display
80 |
81 | ■ Supplement
82 | The display position can be adjusted with the mouse while the balloon is displayed.
83 | Even if the log is currently hidden, the log will advance by one blank line due to waiting for the button.
84 |
85 | The default font is now Segoe UI for English, and Meiryo for Japanese.
86 |
87 | [Most of this English text is machine translated up to ver 0.6.]
88 | -------------------------------------------------- ----------------------
89 | ■ Update history
90 | ver 0.1 Completed for the time being.
91 | ver 0.2 Supports UI scale setting. Supports position adjustment with the mouse.
92 | ver 0.3 Don't let the dust displayed in the balloon come out.
93 | ver 0.4 We also removed dust. Changed the default text from Shinkyapushon to MS Gothic.
94 | ver 0.5 Fixed a bug that the position is not saved when the balloon position is changed.
95 | ver 0.6 Furthermore, garbage characters are deleted (cooperation eyes). Corresponds to colored characters. Fine-tune the position of the message.
96 | Added a corresponding message. Added a process to forcibly close the balloon when the character moves. Changed internal processing.
97 | ver 0.7 Initial changes by Yuki to add English language support. Help text translated.
98 | Added feature where NPC dialogue that doesn't lock your character stays on screen for 5 seconds while still allowing you to move.
99 | Above should work with cutscenes that have a dialogue line that doesn't prompt for advancement.
100 | Added additional event types - NPC dialogue that happens in the background with no interaction should now display in a balloon too.
101 | Default font changed to Segoe UI (To do: make this user configurable without editing the Lua.)
102 | String chopping code provided by Kenshi (Thanks Kenshi!)
103 | ver 0.8 25/8/21 First public release of English client (Yuki).
104 | Swapped out string chopping code to be a mix of original work by Hando and Kenshi to make substituting in colour codes and similar easier.
105 | Added substitution of elemental symbols (e.g. when you talk to Synergy Engineer) for text equivalents.
106 | Added lots of conditional debugging output - if you want to see what's happening in the background use //bl debug 1 or //bl debug 2. Output is to the console window.
107 | Fixed (possibly) bug that was closing balloon as soon as it was displayed.
108 | ver 0.9 30/3/22 Ghosty's first modifications.
109 | Added a bunch of FFXIV-like features; animated advancement prompt, background for names, dark balloon with light text for system messages.
110 | Added the ability to load custom balloons based on NPC names (make a folder called character_balloons and create eg: Iroha.png).
111 | Added settings and commands for soft maximum line length, promptless close delay, prompt animation, and closing by movement.
112 | Added a command to generate test balloons.
113 | ver 0.9.1 27/5/22 Better word wrapping.
114 | Rewrote the word wrapping function to obey a strict character count, maximum line length is now an actual maximum.
115 | Improved ellipses and dash handling (no more "......" becoming "... ...").
116 | Better Japanese language support, by making it switch fonts automatically when first loaded [English: Segoe UI, Japanese: Meiryo] (the font can still be changed in settings.xml afterwards).
117 | ver 0.10 30/5/22 Theme support.
118 | Rewrote a large chunk of the addon to support multiple themes, and live-loading of those themes.
119 | Added FFXI and SNES FF themes.
120 | Moved line length setting to each individual theme.xml
121 | Per-character balloons still work, they now go under eg: themes//characters/Iroha.png
122 | ver 0.11 31/5/22 Scaling.
123 | Added a scale command to increase/decrease the size of the balloon by a decimal multiplier, eg: 1.5
124 | ver 0.11.1 2/6/22 Scaling fix.
125 | Fixed image scaling when the balloon image changes.
126 | ver 0.11.2 3/6/22 FFVII-R Subtitle Theme.
127 | Added a new theme based on the subtitles in FFVII Remake.
128 | ver 0.12 8/6/22 Animated text display.
129 | Added animated text display.
130 | Added a visible countdown timer for prompt-less balloons.
131 | Made the scroll lock key hide the balloon, like it does the vanilla UI.
132 | A *lot* of code cleanup.
133 | ver 0.13 13/6/22 Character portraits.
134 | Added character portraits for most of the main story NPCs.
135 | Toggleable globally with //bl portrait.
136 | Themes can choose to include support for them or not.
137 | Themes can also have a slightly different layout with/without portraits.
138 |
139 | Send any feedback/questions to Ghosty in the #unofficial-addons channel on the Windower Discord.
140 | Or open an issue on the GitHub repo at https://github.com/StarlitGhost/Balloon
141 |
142 | ■ Author
143 | Hando
144 | ■ Modified by
145 | Yuki
146 | Ghosty
--------------------------------------------------------------------------------
/theme.lua:
--------------------------------------------------------------------------------
1 | local theme = {}
2 |
3 | theme.apply = function(theme_settings)
4 | local options = {}
5 |
6 | options.balloon_background = windower.addon_path .. 'themes/' .. theme_settings.name .. '/balloon.png'
7 | options.system_background = windower.addon_path .. 'themes/' .. theme_settings.name .. '/system.png'
8 | options.portrait_background = windower.addon_path .. 'themes/' .. theme_settings.name .. '/portrait-bg.png'
9 | options.portrait_frame = windower.addon_path .. 'themes/' .. theme_settings.name .. '/portrait-frame.png'
10 | options.name_background = windower.addon_path .. 'themes/' .. theme_settings.name .. '/name-bg.png'
11 | options.prompt_image = windower.addon_path .. 'themes/' .. theme_settings.name .. '/advance-prompt.png'
12 |
13 | options.message = {}
14 | options.message.width = theme_settings.message.width
15 | options.message.height = theme_settings.message.height
16 | options.message.offset_x = theme_settings.message.textoffsetx
17 | options.message.offset_y = theme_settings.message.textoffsety
18 | options.message.max_length = theme_settings.message.maxlength or 75
19 | local message_languages = {English=theme_settings.message.fontenglish, Japanese=theme_settings.message.fontjapanese}
20 | options.message.font = message_languages[windower.ffxi.get_info().language]
21 | options.message.font_size = theme_settings.message.size
22 | options.message.font_color = {}
23 | options.message.font_color.alpha = theme_settings.message.dialogue.color.alpha
24 | options.message.font_color.red = theme_settings.message.dialogue.color.red
25 | options.message.font_color.green = theme_settings.message.dialogue.color.green
26 | options.message.font_color.blue = theme_settings.message.dialogue.color.blue
27 |
28 | options.message.dialogue = {}
29 | options.message.dialogue.alpha = theme_settings.message.dialogue.color.alpha
30 | options.message.dialogue.red = theme_settings.message.dialogue.color.red
31 | options.message.dialogue.green = theme_settings.message.dialogue.color.green
32 | options.message.dialogue.blue = theme_settings.message.dialogue.color.blue
33 | options.message.dialogue.items = theme_settings.message.dialogue.items
34 | options.message.dialogue.keyitems = theme_settings.message.dialogue.keyitems
35 | options.message.dialogue.gear = theme_settings.message.dialogue.gear
36 | options.message.dialogue.roe = theme_settings.message.dialogue.roe
37 | options.message.dialogue.emote = theme_settings.message.dialogue.emote
38 | options.message.stroke = {}
39 | options.message.dialogue.stroke = {}
40 | if theme_settings.message.dialogue.stroke then
41 | options.message.stroke.width = theme_settings.message.dialogue.stroke.width
42 | options.message.stroke.alpha = theme_settings.message.dialogue.stroke.alpha
43 | options.message.stroke.red = theme_settings.message.dialogue.stroke.red
44 | options.message.stroke.green = theme_settings.message.dialogue.stroke.green
45 | options.message.stroke.blue = theme_settings.message.dialogue.stroke.blue
46 | options.message.dialogue.stroke.width = theme_settings.message.dialogue.stroke.width
47 | options.message.dialogue.stroke.alpha = theme_settings.message.dialogue.stroke.alpha
48 | options.message.dialogue.stroke.red = theme_settings.message.dialogue.stroke.red
49 | options.message.dialogue.stroke.green = theme_settings.message.dialogue.stroke.green
50 | options.message.dialogue.stroke.blue = theme_settings.message.dialogue.stroke.blue
51 | end
52 |
53 | options.message.system = {}
54 | if theme_settings.message.system then
55 | options.message.system.alpha = theme_settings.message.system.color.alpha
56 | options.message.system.red = theme_settings.message.system.color.red
57 | options.message.system.green = theme_settings.message.system.color.green
58 | options.message.system.blue = theme_settings.message.system.color.blue
59 | options.message.system.items = theme_settings.message.system.items
60 | options.message.system.keyitems = theme_settings.message.system.keyitems
61 | options.message.system.gear = theme_settings.message.system.gear
62 | options.message.system.roe = theme_settings.message.system.roe
63 | options.message.system.emote = theme_settings.message.system.emote
64 | options.message.system.stroke = {}
65 | if theme_settings.message.system.stroke then
66 | options.message.system.stroke.width = theme_settings.message.system.stroke.width
67 | options.message.system.stroke.alpha = theme_settings.message.system.stroke.alpha
68 | options.message.system.stroke.red = theme_settings.message.system.stroke.red
69 | options.message.system.stroke.green = theme_settings.message.system.stroke.green
70 | options.message.system.stroke.blue = theme_settings.message.system.stroke.blue
71 | end
72 | else
73 | -- use dialogue settings if there are no system settings
74 | options.message.system = options.message.dialogue
75 | end
76 |
77 | options.name = {}
78 | options.name.width = theme_settings.npcname.width
79 | options.name.height = theme_settings.npcname.height
80 | options.name.offset_x = theme_settings.npcname.textoffsetx
81 | options.name.offset_y = theme_settings.npcname.textoffsety
82 | options.name.background_offset_x = theme_settings.npcname.offsetx
83 | options.name.background_offset_y = theme_settings.npcname.offsety
84 | local name_languages = {English=theme_settings.npcname.fontenglish, Japanese=theme_settings.npcname.fontjapanese}
85 | options.name.font = name_languages[windower.ffxi.get_info().language]
86 | options.name.font_size = theme_settings.npcname.size
87 | options.name.font_color = {}
88 | options.name.font_color.alpha = theme_settings.npcname.color.alpha
89 | options.name.font_color.red = theme_settings.npcname.color.red
90 | options.name.font_color.green = theme_settings.npcname.color.green
91 | options.name.font_color.blue = theme_settings.npcname.color.blue
92 | options.name.stroke = {}
93 | if theme_settings.npcname.stroke then
94 | options.name.stroke.width = theme_settings.npcname.stroke.width
95 | options.name.stroke.alpha = theme_settings.npcname.stroke.alpha
96 | options.name.stroke.red = theme_settings.npcname.stroke.red
97 | options.name.stroke.green = theme_settings.npcname.stroke.green
98 | options.name.stroke.blue = theme_settings.npcname.stroke.blue
99 | end
100 |
101 | if theme_settings.portrait then
102 | options.portrait = {}
103 | options.portrait.width = theme_settings.portrait.width
104 | options.portrait.height = theme_settings.portrait.height
105 | options.portrait.offset_x = theme_settings.portrait.offsetx
106 | options.portrait.offset_y = theme_settings.portrait.offsety
107 | options.portrait.max_length = theme_settings.portrait.maxlength
108 | options.portrait.message_offset_x = theme_settings.portrait.messagetextoffsetx
109 | options.portrait.message_offset_y = theme_settings.portrait.messagetextoffsety
110 | end
111 |
112 | if theme_settings.prompt then
113 | options.prompt = {}
114 | options.prompt.width = theme_settings.prompt.width
115 | options.prompt.height = theme_settings.prompt.height
116 | options.prompt.offset_x = theme_settings.prompt.offsetx
117 | options.prompt.offset_y = theme_settings.prompt.offsety
118 | end
119 |
120 | options.timer = {}
121 | if theme_settings.timer then
122 | options.timer.offset_x = theme_settings.timer.textoffsetx or theme_settings.prompt.offsetx
123 | options.timer.offset_y = theme_settings.timer.textoffsety or theme_settings.prompt.offsety
124 | local timer_languages = {English=theme_settings.timer.fontenglish or theme_settings.message.fontenglish,
125 | Japanese=theme_settings.timer.fontjapanese or theme_settings.message.fontjapanese}
126 | options.timer.font = timer_languages[windower.ffxi.get_info().language]
127 | options.timer.font_size = theme_settings.timer.size or theme_settings.message.size
128 |
129 | options.timer.font_color = {}
130 | if theme_settings.timer.color then
131 | options.timer.font_color.alpha = theme_settings.timer.color.alpha
132 | options.timer.font_color.red = theme_settings.timer.color.red
133 | options.timer.font_color.green = theme_settings.timer.color.green
134 | options.timer.font_color.blue = theme_settings.timer.color.blue
135 | else
136 | options.timer.font_color = options.message.font_color
137 | end
138 | options.timer.stroke = {}
139 | if theme_settings.timer.stroke then
140 | options.timer.stroke.width = theme_settings.timer.stroke.width
141 | options.timer.stroke.alpha = theme_settings.timer.stroke.alpha
142 | options.timer.stroke.red = theme_settings.timer.stroke.red
143 | options.timer.stroke.green = theme_settings.timer.stroke.green
144 | options.timer.stroke.blue = theme_settings.timer.stroke.blue
145 | else
146 | options.timer.stroke = options.message.stroke
147 | end
148 | else
149 | -- use prompt position and message font settings, if no timer settings exist in the theme
150 | options.timer.offset_x = theme_settings.prompt.offsetx
151 | options.timer.offset_y = theme_settings.prompt.offsety
152 | options.timer.font = options.message.font
153 | options.timer.font_size = options.message.font_size
154 | options.timer.font_color = options.message.font_color
155 | options.timer.stroke = options.message.stroke
156 | end
157 |
158 | return options
159 | end
160 |
161 | return theme
--------------------------------------------------------------------------------
/ui.lua:
--------------------------------------------------------------------------------
1 | local ui = {}
2 |
3 | local text_setup = {
4 | flags = {
5 | draggable = false
6 | },
7 | padding = 2
8 | }
9 |
10 | ui.message_background = images.new()
11 | ui.portrait_background = images.new()
12 | ui.portrait = images.new()
13 | ui.portrait_frame = images.new()
14 | ui.name_background = images.new()
15 | ui.prompt = images.new()
16 |
17 | ui.message_text = texts.new(text_setup)
18 | ui.name_text = texts.new(text_setup)
19 | ui.timer_text = texts.new(text_setup)
20 |
21 | ui._hidden = true
22 | ui._current_text = ''
23 | ui._chars_shown = 0
24 | ui._has_portrait = false
25 |
26 | ui._dialogue_settings = {}
27 | ui._system_settings = {}
28 | ui._type = {}
29 |
30 | ui._theme = 'default'
31 | ui._scale = 1.0
32 | ui._global_show_portraits = true
33 | ui._theme_options = nil
34 |
35 | local function setup_image(image, path)
36 | image:path(path)
37 | image:repeat_xy(1, 1)
38 | image:draggable(false)
39 | image:fit(false) -- this does the opposite of what you'd expect, and also doesn't adjust :size() to account for it
40 | end
41 |
42 | local function setup_text(text, text_options)
43 | text:bg_alpha(0)
44 | text:bg_visible(false)
45 | text:font(text_options.font, 'meiryo', 'segoe ui', 'sans-serif')
46 | text:size(text_options.font_size)
47 | text:alpha(text_options.font_color.alpha)
48 | text:color(text_options.font_color.red, text_options.font_color.green, text_options.font_color.blue)
49 | text:stroke_transparency(text_options.stroke.alpha or 0)
50 | text:stroke_color(text_options.stroke.red or 0, text_options.stroke.green or 0, text_options.stroke.blue or 0)
51 | text:stroke_width(text_options.stroke.width or 0)
52 | end
53 |
54 | function ui:load(settings, theme_options)
55 | self._theme = settings.Theme
56 | self._scale = settings.Scale
57 | self._global_show_portraits = settings.ShowPortraits
58 | self._theme_options = theme_options
59 |
60 | self._dialogue_settings.path = theme_options.balloon_background
61 | self._dialogue_settings.color = {}
62 | self._dialogue_settings.color.alpha = theme_options.message.dialogue.alpha
63 | self._dialogue_settings.color.red = theme_options.message.dialogue.red
64 | self._dialogue_settings.color.green = theme_options.message.dialogue.green
65 | self._dialogue_settings.color.blue = theme_options.message.dialogue.blue
66 | self._dialogue_settings.items = theme_options.message.dialogue.items
67 | self._dialogue_settings.keyitems = theme_options.message.dialogue.keyitems
68 | self._dialogue_settings.gear = theme_options.message.dialogue.gear
69 | self._dialogue_settings.roe = theme_options.message.dialogue.roe
70 | self._dialogue_settings.emote = theme_options.message.dialogue.emote or '125,175,255'
71 | self._dialogue_settings.stroke = {}
72 | self._dialogue_settings.stroke.width = theme_options.message.dialogue.stroke.width
73 | self._dialogue_settings.stroke.alpha = theme_options.message.dialogue.stroke.alpha
74 | self._dialogue_settings.stroke.red = theme_options.message.dialogue.stroke.red
75 | self._dialogue_settings.stroke.green = theme_options.message.dialogue.stroke.green
76 | self._dialogue_settings.stroke.blue = theme_options.message.dialogue.stroke.blue
77 |
78 | self._system_settings.path = theme_options.system_background
79 | self._system_settings.color = {}
80 | self._system_settings.color.alpha = theme_options.message.system.alpha
81 | self._system_settings.color.red = theme_options.message.system.red
82 | self._system_settings.color.green = theme_options.message.system.green
83 | self._system_settings.color.blue = theme_options.message.system.blue
84 | self._system_settings.items = theme_options.message.system.items
85 | self._system_settings.keyitems = theme_options.message.system.keyitems
86 | self._system_settings.gear = theme_options.message.system.gear
87 | self._system_settings.roe = theme_options.message.system.roe
88 | self._system_settings.emote = theme_options.message.system.emote or '125,175,255'
89 | self._system_settings.stroke = {}
90 | self._system_settings.stroke.width = theme_options.message.system.stroke.width
91 | self._system_settings.stroke.alpha = theme_options.message.system.stroke.alpha
92 | self._system_settings.stroke.red = theme_options.message.system.stroke.red
93 | self._system_settings.stroke.green = theme_options.message.system.stroke.green
94 | self._system_settings.stroke.blue = theme_options.message.system.stroke.blue
95 |
96 | self._type = self._dialogue_settings
97 |
98 | setup_image(self.message_background, self._type.path)
99 | if theme_options.portrait then
100 | setup_image(self.portrait_background, theme_options.portrait_background)
101 | setup_image(self.portrait, nil)
102 | setup_image(self.portrait_frame, theme_options.portrait_frame)
103 | end
104 | setup_image(self.name_background, theme_options.name_background)
105 | if theme_options.prompt then
106 | setup_image(self.prompt, theme_options.prompt_image)
107 | end
108 |
109 | setup_text(self.message_text, theme_options.message)
110 | setup_text(self.name_text, theme_options.name)
111 | if theme_options.timer then
112 | setup_text(self.timer_text, theme_options.timer)
113 | end
114 |
115 | self:position(settings.Position.X, settings.Position.Y)
116 |
117 | self.message_background:draggable(true)
118 | end
119 |
120 | function ui:scale(scale)
121 | self._scale = scale
122 | self:position()
123 | end
124 |
125 | function ui:position(x_pos, y_pos)
126 | local center_offset_x = self._theme_options.message.width / 2
127 | local center_offset_y = self._theme_options.message.height / 2
128 | x_pos = x_pos or self.message_background:pos_x() + center_offset_x * self._scale
129 | y_pos = y_pos or self.message_background:pos_y() + center_offset_y * self._scale
130 | local x = x_pos - center_offset_x * self._scale
131 | local y = y_pos - center_offset_y * self._scale
132 | local name_bg_offset_x = self._theme_options.name.background_offset_x * self._scale
133 | local name_bg_offset_y = self._theme_options.name.background_offset_y * self._scale
134 | local message_text_offset_x = self._theme_options.message.offset_x * self._scale
135 | local message_text_offset_y = self._theme_options.message.offset_y * self._scale
136 | if self._has_portrait and self._theme_options.portrait then
137 | if self._theme_options.portrait.message_offset_x then
138 | message_text_offset_x = self._theme_options.portrait.message_offset_x * self._scale
139 | end
140 | if self._theme_options.portrait.message_offset_y then
141 | message_text_offset_y = self._theme_options.portrait.message_offset_y * self._scale
142 | end
143 | end
144 | local name_text_offset_x = self._theme_options.name.offset_x * self._scale
145 | local name_text_offset_y = self._theme_options.name.offset_y * self._scale
146 |
147 | self.message_background:pos(x, y)
148 | self.message_background:size(self._theme_options.message.width * self._scale, self._theme_options.message.height * self._scale)
149 | if self._theme_options.portrait then
150 | local portrait_offset_x = self._theme_options.portrait.offset_x * self._scale
151 | local portrait_offset_y = self._theme_options.portrait.offset_y * self._scale
152 | self.portrait_background:pos(x + portrait_offset_x, y + portrait_offset_y)
153 | self.portrait_background:size(self._theme_options.portrait.width * self._scale, self._theme_options.portrait.height * self._scale)
154 | self.portrait:pos(x + portrait_offset_x, y + portrait_offset_y)
155 | self.portrait:size(self._theme_options.portrait.width * self._scale, self._theme_options.portrait.height * self._scale)
156 | self.portrait_frame:pos(x + portrait_offset_x, y + portrait_offset_y)
157 | self.portrait_frame:size(self._theme_options.portrait.width * self._scale, self._theme_options.portrait.height * self._scale)
158 | end
159 | self.name_background:pos(x + name_bg_offset_x, y + name_bg_offset_y)
160 | self.name_background:size(self._theme_options.name.width * self._scale, self._theme_options.name.height * self._scale)
161 | if self._theme_options.prompt then
162 | local prompt_offset_x = self._theme_options.prompt.offset_x * self._scale
163 | local prompt_offset_y = self._theme_options.prompt.offset_y * self._scale
164 | self.prompt:pos(x + prompt_offset_x, y + prompt_offset_y)
165 | self.prompt:size(self._theme_options.prompt.width * self._scale, self._theme_options.prompt.height * self._scale)
166 | end
167 |
168 | self.message_text:pos(x + message_text_offset_x, y + message_text_offset_y)
169 | self.message_text:size(self._theme_options.message.font_size * self._scale)
170 | self.name_text:pos(x + name_text_offset_x, y + name_text_offset_y)
171 | self.name_text:size(self._theme_options.name.font_size * self._scale)
172 | if self._theme_options.timer then
173 | local timer_text_offset_x = self._theme_options.timer.offset_x * self._scale
174 | local timer_text_offset_y = self._theme_options.timer.offset_y * self._scale
175 | self.timer_text:pos(x + timer_text_offset_x, y + timer_text_offset_y)
176 | self.timer_text:size(self._theme_options.timer.font_size * self._scale)
177 | end
178 | end
179 |
180 | function ui:hide()
181 | self.message_background:hide()
182 | self.name_background:hide()
183 | self.portrait_background:hide()
184 | self.portrait:hide()
185 | self.portrait_frame:hide()
186 | self.prompt:hide()
187 |
188 | self.message_text:hide()
189 | self.name_text:hide()
190 | self.timer_text:hide()
191 |
192 | self._hidden = true
193 | end
194 |
195 | function ui:show(timed)
196 | self.message_background:show()
197 | self.message_text:show()
198 |
199 | if not S{'', ' '}[self.name_text:text()] then
200 | self.name_background:show()
201 | self.name_text:show()
202 |
203 | if self._has_portrait then
204 | self.portrait_background:show()
205 | self.portrait:show()
206 | self.portrait_frame:show()
207 | else
208 | self.portrait_background:hide()
209 | self.portrait:hide()
210 | self.portrait_frame:hide()
211 | end
212 | else
213 | self.name_background:hide()
214 | self.name_text:hide()
215 |
216 | self.portrait_background:hide()
217 | self.portrait:hide()
218 | self.portrait_frame:hide()
219 | end
220 |
221 | if not timed then
222 | self.prompt:show()
223 | self.timer_text:hide()
224 | else
225 | self.timer_text:show()
226 | self.prompt:hide()
227 | end
228 |
229 | self._hidden = false
230 | end
231 |
232 | function ui:set_type(type)
233 | local types = {
234 | --[190] = self._system_settings, -- system text (always a duplicate of 151?)
235 | [150] = self._dialogue_settings, -- npc text
236 | [151] = self._system_settings, -- system text
237 | [142] = self._dialogue_settings, -- battle text
238 | [144] = self._dialogue_settings, -- prompt-less npc text
239 | [146] = self._system_settings, -- "You hear something moving to the east..."
240 | [15] = self._system_settings, -- cutscene emote
241 | }
242 | self._type = types[type]
243 |
244 | self:update_message_bg(self._type.path)
245 | self.message_text:alpha(self._type.color.alpha)
246 | if type == 15 then
247 | local emote_col = self._system_settings.emote:split(',')
248 | self.message_text:color(tonumber(emote_col[1]), tonumber(emote_col[2]), tonumber(emote_col[3]))
249 | else
250 | self.message_text:color(self._type.color.red, self._type.color.green, self._type.color.blue)
251 | end
252 | self.message_text:stroke_transparency(self._type.stroke.alpha)
253 | self.message_text:stroke_color(self._type.stroke.red, self._type.stroke.green, self._type.stroke.blue)
254 | self.message_text:stroke_width(self._type.stroke.width)
255 | end
256 |
257 | function ui:set_character(name)
258 | self.name_text:text(' '..name)
259 |
260 | local info = windower.ffxi.get_info()
261 | local zone_name = res.zones[info.zone].en
262 | local s = false
263 | if zone_name:endswith('[S]') then
264 | s = true
265 | end
266 |
267 | if self._global_show_portraits and self._theme_options.portrait then
268 | local theme_portrait = (windower.addon_path..'themes/'..self._theme..'/portraits/%s.png'):format(name)
269 | local theme_portrait_s = (windower.addon_path..'themes/'..self._theme..'/portraits/%s (S).png'):format(name)
270 | local portrait = (windower.addon_path..'portraits/%s.png'):format(name)
271 | local portrait_s = (windower.addon_path..'portraits/%s (S).png'):format(name)
272 | if s and windower.file_exists(theme_portrait_s) then
273 | self.portrait:path(theme_portrait_s)
274 | self._has_portrait = true
275 | elseif s and windower.file_exists(portrait_s) then
276 | self.portrait:path(portrait_s)
277 | self._has_portrait = true
278 | elseif windower.file_exists(theme_portrait) then
279 | self.portrait:path(theme_portrait)
280 | self._has_portrait = true
281 | elseif windower.file_exists(portrait) then
282 | self.portrait:path(portrait)
283 | self._has_portrait = true
284 | else
285 | self._has_portrait = false
286 | end
287 | else
288 | self._has_portrait = false
289 | end
290 |
291 | -- set a custom balloon based on npc name, if an image for them exists
292 | local fname = windower.addon_path..'themes/'..self._theme..('/characters/%s.png'):format(name)
293 | if windower.file_exists(fname) then
294 | self:update_message_bg(fname)
295 | return true
296 | end
297 | return false
298 | end
299 |
300 | function ui:update_message_bg(path)
301 | if path ~= self.message_background:path() then
302 | self.message_background:path(path)
303 | end
304 | end
305 |
306 | local function Tokenize(str)
307 | local result = {}
308 | for word in str:gmatch("%S+") do
309 | result[#result+1] = word
310 | end
311 | return result
312 | end
313 |
314 | function ui:wrap_text(str)
315 | local line_length = self._theme_options.message.max_length+1
316 | if self._has_portrait and self._theme_options.portrait.max_length then
317 | line_length = self._theme_options.portrait.max_length+1
318 | end
319 | local length_left = line_length
320 | local result = {}
321 | local line = {}
322 |
323 | for _, word in ipairs(Tokenize(str)) do
324 | if #word+1 > length_left then
325 | table.insert(result, table.concat(line, ' '))
326 | line = {word}
327 | length_left = line_length - #word
328 | else
329 | table.insert(line, word)
330 | length_left = length_left - (#word + 1)
331 | end
332 | end
333 |
334 | table.insert(result, table.concat(line, ' '))
335 | local new_str = table.concat(result, '\n ')
336 |
337 | return new_str
338 | end
339 |
340 | function ui:set_message(message)
341 | self._current_text = message
342 | self._chars_shown = 0
343 | self.message_text:text('')
344 |
345 | -- this is here to update the layout depending if there's a portrait or not
346 | self:position()
347 | end
348 |
349 | local function smooth_sawtooth(time, frequency)
350 | local x = time * frequency
351 | return(-math.sin(x-math.sin(x)/2))
352 | end
353 |
354 | function ui:animate_prompt(frame_count)
355 | if not self._theme_options.prompt then return end
356 |
357 | local amplitude = 2.5
358 | local bounceOffset = smooth_sawtooth(frame_count/60, 6) * amplitude
359 |
360 | local pos_y = self.message_background:pos_y() + (self._theme_options.prompt.offset_y + bounceOffset) * self._scale
361 | self.prompt:pos_y(pos_y)
362 | end
363 |
364 | function ui:animate_text_display(chars_per_frame)
365 | if self._chars_shown >= #self._current_text then return end
366 |
367 | self._chars_shown = self._chars_shown + (chars_per_frame == 0 and 1000 or chars_per_frame)
368 | self.message_text:text(self._current_text:sub(0,self._chars_shown))
369 | end
370 |
371 | function ui:hidden()
372 | return self._hidden
373 | end
374 |
375 | return ui
--------------------------------------------------------------------------------
/Balloon.lua:
--------------------------------------------------------------------------------
1 | -- Copyright 2018, Hando
2 | -- Copyright 2021, Yuki
3 | -- Copyright 2022, Ghosty
4 | -- All rights reserved.
5 |
6 | -- Redistribution and use in source and binary forms, with or without
7 | -- modification, are permitted provided that the following conditions are met:
8 |
9 | -- * Redistributions of source code must retain the above copyright
10 | -- notice, this list of conditions and the following disclaimer.
11 | -- * Redistributions in binary form must reproduce the above copyright
12 | -- notice, this list of conditions and the following disclaimer in the
13 | -- documentation and/or other materials provided with the distribution.
14 | -- * Neither the name of Balloon nor the
15 | -- names of its contributors may be used to endorse or promote products
16 | -- derived from this software without specific prior written permission.
17 |
18 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | -- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | -- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | -- DISCLAIMED. IN NO EVENT SHALL Hando BE LIABLE FOR ANY
22 | -- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | -- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | -- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 | -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | -- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | --
30 | _addon.author = 'Originally by Hando, English support added by Yuki & Kenshi, themes added by Ghosty'
31 | _addon.name = 'Balloon'
32 | _addon.version = '0.13'
33 | _addon.commands = {'balloon','bl'}
34 |
35 | require('luau')
36 | chars = require('chat.chars')
37 | chars.cldquo = string.char(0x87, 0xB2)
38 | chars.crdquo = string.char(0x87, 0xB3)
39 | texts = require('texts')
40 | images = require('images')
41 |
42 | local defaults = require('defaults')
43 | local settings = {}
44 |
45 | local theme = require('theme')
46 | local theme_options = {}
47 |
48 | local ui = require('ui')
49 |
50 | local MODE = {}
51 | MODE.MESSAGE = 150
52 | MODE.SYSTEM = 151
53 | MODE.TIMED_MESSAGE = 144
54 | MODE.TIMED_BATTLE = 142
55 | MODE.CUTSCENE_EMOTE = 15
56 |
57 | local ENTER_KEY = 28
58 | local SCROLL_LOCK_KEY = 70
59 |
60 | local ZONE_OUT_PACKET = 0x0B
61 | local LEAVE_CONVERSATION_PACKET = 0x52
62 |
63 | -- 0x31-0x33 and 0x37 all appear the same
64 | local PROMPT_CHARS = string.char(0x7F,0x31)
65 | -- the 0x01 in this is the number of seconds before the prompt continues itself
66 | -- 0x34-0x36 seem to do the same thing
67 | local AUTO_PROMPT_CHARS = string.char(0x7F,0x34,0x01)
68 |
69 | local balloon = {}
70 | balloon.initialized = false
71 | balloon.debug = 'off'
72 | balloon.moving = false
73 | balloon.old_x = "0"
74 | balloon.old_y = "0"
75 | balloon.on = false
76 | balloon.keydown = false
77 | balloon.mouse_on = false
78 | balloon.waiting_to_close = false
79 | balloon.frame_count = 0
80 | balloon.prev_path = nil
81 | balloon.close_timer = 0
82 | balloon.timer_running = false
83 | balloon.last_text = ''
84 | balloon.last_mode = 0
85 | balloon.movement_thread = nil
86 |
87 | -------------------------------------------------------------------------------
88 |
89 | function initialize()
90 | settings = config.load(defaults)
91 | config.save(settings)
92 |
93 | apply_theme()
94 |
95 | --スレッド開始 (Thread start)
96 | timer:schedule(0)
97 | if settings.MovementCloses then
98 | balloon.movement_thread = moving_check:schedule(0)
99 | end
100 |
101 | balloon.initialized = true
102 | end
103 |
104 | function apply_theme()
105 | local theme_path = 'themes/' .. settings.Theme .. '/theme.xml'
106 | local theme_settings = config.load(theme_path, {['name']=settings.Theme})
107 | theme_options = theme.apply(theme_settings)
108 |
109 | ui:load(settings, theme_options)
110 | if balloon.on then
111 | process_balloon(balloon.last_text, balloon.last_mode)
112 | end
113 | end
114 |
115 | function open(timed)
116 | if not balloon.initialized then
117 | initialize()
118 | end
119 |
120 | if timed then
121 | balloon.close_timer = settings.NoPromptCloseDelay
122 | ui.timer_text:text(''..balloon.close_timer)
123 | end
124 |
125 | ui:show(timed)
126 |
127 | balloon.waiting_to_close = timed
128 | balloon.on = true
129 | end
130 |
131 | function close()
132 | ui:hide()
133 |
134 | balloon.on = false
135 | balloon.waiting_to_close = false
136 | end
137 |
138 | function timer()
139 | -- from Aelmar's npcbox https://www.ffxiah.com/forum/topic/56227/balloon-story-addon/2/#3627878
140 | -- thanks for letting me use bits from it, Aelmar!
141 | if balloon.timer_running then return end
142 | balloon.timer_running = true
143 | while true do
144 | if balloon.waiting_to_close then
145 | if balloon.close_timer == 0 then
146 | close()
147 | end
148 | if balloon.close_timer > 0 then
149 | ui.timer_text:text(balloon.close_timer..'')
150 | end
151 | if balloon.close_timer >= 0 then
152 | balloon.close_timer = balloon.close_timer - 1
153 | end
154 | end
155 | coroutine.sleep(1)
156 | end
157 | end
158 |
159 | windower.register_event('load',function()
160 | if windower.ffxi.get_info().logged_in then
161 | initialize()
162 | end
163 | end)
164 |
165 | windower.register_event('login',function()
166 | -- re-load settings and theme 10 seconds after login,
167 | -- so per-character settings are picked up properly
168 | initialize:schedule(10)
169 | end)
170 |
171 | function moving_check()
172 | local p = windower.ffxi.get_player()
173 | if p == nil then return end
174 |
175 | local me,x,y
176 |
177 | while true do
178 | me = windower.ffxi.get_mob_by_id(p.id)
179 | if me ~= nil then
180 | x = string.format("%6d",me.x)
181 | y = string.format("%6d",me.y)
182 | --if x ~= old_x and y ~= old_y then
183 | if (tonumber(x) < tonumber(balloon.old_x) - 1 or tonumber(x) > tonumber(balloon.old_x) + 1) or (tonumber(y) < tonumber(balloon.old_y) - 1 or tonumber(y) > tonumber(balloon.old_y) + 1) then
184 | balloon.moving = true
185 | balloon.old_y = y
186 | balloon.old_x = x
187 | else
188 | balloon.moving = false
189 | end
190 | end
191 | --wait
192 | balloon.waiting_to_close = true
193 | coroutine.sleep(settings.NoPromptCloseDelay)
194 | if balloon.moving and settings.MovementCloses and balloon.waiting_to_close then
195 | close()
196 | end
197 | end
198 |
199 | end
200 |
201 | windower.register_event('incoming chunk',function(id,original,modified,injected,blocked)
202 | if S{'chunk', 'all'}[balloon.debug] then print("Chunk: " .. '0x%02X':format(id) .. " original: " .. original) end
203 |
204 | --会話中かの確認 (Check if you have left a conversation)
205 | if S{LEAVE_CONVERSATION_PACKET, ZONE_OUT_PACKET}[id] then
206 | close()
207 | end
208 | end)
209 |
210 | windower.register_event('incoming text',function(original,modified,mode,modified_mode,blocked)
211 | -- print debug info
212 | if S{'codes', 'mode', 'all'}[balloon.debug] then print("Mode: " .. mode .. " Text: " .. original) end
213 |
214 | -- skip text modes that aren't NPC speech
215 | if not S{MODE.MESSAGE, MODE.SYSTEM, MODE.TIMED_BATTLE, MODE.TIMED_MESSAGE}[mode] then return end
216 |
217 | -- blank prompt line that auto-continues itself,
218 | -- usually used to clear a space for a scene change?
219 | if original:endswith(AUTO_PROMPT_CHARS) then
220 | close()
221 | return
222 | end
223 |
224 | -- print debug info
225 | if S{'codes', 'all'}[balloon.debug] then print("codes: " .. codes(original)) end
226 |
227 | local result = original
228 | if settings.DisplayMode >= 1 then
229 | result = process_balloon(original, mode)
230 | end
231 | return(result)
232 |
233 | end)
234 |
235 | function process_balloon(npc_text, mode)
236 | if not balloon.initialized then
237 | initialize()
238 | end
239 |
240 | balloon.last_text = npc_text
241 | balloon.last_mode = mode
242 |
243 | -- detect whether messages have a prompt button
244 | local timed = true
245 | if S{MODE.MESSAGE, MODE.SYSTEM}[mode] and npc_text:sub(-#PROMPT_CHARS) == PROMPT_CHARS then
246 | timed = false
247 | end
248 |
249 | -- 発言者名の抽出 (Speaker name extraction)
250 | local start,_end = npc_text:find(".- : ")
251 | local npc_prefix = ""
252 | if start ~= nil then
253 | if _end < 32 and start > 0 then npc_prefix = npc_text:sub(start,_end) end
254 | end
255 | local npc_name = npc_prefix:sub(0,#npc_prefix-2)
256 | npc_name = string.trim(npc_name)
257 |
258 | if not ui:set_character(npc_name) then
259 | ui:set_type(mode)
260 | end
261 |
262 | -- mode 1, blank log lines and visible balloon
263 | if settings.DisplayMode == 1 then
264 | if npc_prefix == "" then
265 | result = "" .. "\n"
266 | else
267 | result = npc_text:sub(#npc_text-1,#npc_text)
268 | end
269 | -- mode 2, visible log and balloon
270 | elseif settings.DisplayMode == 2 then
271 | -- pass through the original message for the log
272 | result = npc_text
273 | end
274 |
275 | -- 発言 (Remark)
276 | local mes = SubCharactersPreShift(npc_text)
277 | mes = windower.from_shift_jis(mes)
278 | mes = SubCharactersPostShift(mes)
279 |
280 | -- strip the NPC name from the start of the message
281 | if npc_prefix ~= "" then
282 | mes = mes:gsub(npc_prefix:gsub("-","--"),"") --タルタル等対応 (Correspondence such as tartar)
283 | end
284 |
285 | if S{'process', 'all'}[balloon.debug] then print("Pre-process: " .. mes) end
286 | if S{'codes', 'all'}[balloon.debug] then print("codes: " .. codes(mes)) end
287 |
288 | --strip the default color code from the start of messages,
289 | --it causes the first part of the message to get cut off somehow
290 | local default_color = string.char(0x1E,0x01)
291 | if string.sub(mes, 1, #default_color) == default_color then
292 | mes = string.sub(mes, #default_color + 1)
293 | end
294 |
295 | -- split by newlines
296 | local mess = split(mes,string.char(0x07))
297 |
298 | local message = ""
299 | for k,v in ipairs(mess) do
300 | v = string.gsub(v, string.char(0x1E,0x01), "[BL_c1]") --color code 1 (black/reset)
301 | v = string.gsub(v, string.char(0x1E,0x02), "[BL_c2]") --color code 2 (green/regular items)
302 | v = string.gsub(v, string.char(0x1E,0x03), "[BL_c3]") --color code 3 (blue/key items)
303 | v = string.gsub(v, string.char(0x1E,0x04), "[BL_c4]") --color code 4 (blue/???)
304 | v = string.gsub(v, string.char(0x1E,0x05), "[BL_c5]") --color code 5 (magenta/equipment?)
305 | v = string.gsub(v, string.char(0x1E,0x06), "[BL_c6]") --color code 6 (cyan/???)
306 | v = string.gsub(v, string.char(0x1E,0x07), "[BL_c7]") --color code 7 (yellow/???)
307 | v = string.gsub(v, string.char(0x1E,0x08), "[BL_c8]") --color code 8 (orange/RoE objectives?)
308 | v = string.gsub(v, string.char(0x1F,0x0F), "") --cutscene emote color code (handled by the message type instead)
309 | v = string.gsub(v, PROMPT_CHARS, "")
310 | -- these are the auto-prompt characters
311 | v = string.gsub(v, string.char(0x7F,0x34), "")
312 | v = string.gsub(v, string.char(0x7F,0x35), "")
313 | v = string.gsub(v, string.char(0x7F,0x36), "")
314 | -- these are often the timings for the auto-prompt
315 | v = string.gsub(v, string.char(0x01), "")
316 | v = string.gsub(v, string.char(0x02), "")
317 | v = string.gsub(v, string.char(0x03), "")
318 | v = string.gsub(v, string.char(0x04), "")
319 | v = string.gsub(v, string.char(0x05), "")
320 | v = string.gsub(v, string.char(0x06), "")
321 | v = string.gsub(v, "^?([%w%.'(<“])", "%1")
322 | v = string.gsub(v, '(%w)(%.%.%.+)([%w“])', "%1%2 %3") --add a space after elipses to allow better line splitting
323 | v = string.gsub(v, '([%w”])%-%-([%w%p])', "%1-- %2") --same for double dashes
324 |
325 | v = ui:wrap_text(v)
326 |
327 | v = " " .. v
328 | v = string.gsub(v, "%[BL_c1]", "\\cr")
329 | v = string.gsub(v, "%[BL_c2]", "\\cs("..ui._type.items..")")
330 | v = string.gsub(v, "%[BL_c3]", "\\cs("..ui._type.keyitems..")")
331 | v = string.gsub(v, "%[BL_c4]", "\\cs("..ui._type.keyitems..")")
332 | v = string.gsub(v, "%[BL_c5]", "\\cs("..ui._type.gear..")")
333 | v = string.gsub(v, "%[BL_c6]", "\\cs(0,159,173)")
334 | v = string.gsub(v, "%[BL_c7]", "\\cs(156,149,19)")
335 | v = string.gsub(v, "%[BL_c8]", "\\cs("..ui._type.roe..")")
336 | --TODO: theme settings for these element colors
337 | v = string.gsub(v, "%[BL_Fire]", "\\cs(255,0,0)Fire \\cr")
338 | v = string.gsub(v, "%[BL_Ice]", "\\cs(0,255,255)Ice \\cr")
339 | v = string.gsub(v, "%[BL_Wind]", "\\cs(0,255,0)Wind \\cr")
340 | v = string.gsub(v, "%[BL_Earth]", "\\cs(153,76,0)Earth \\cr")
341 | v = string.gsub(v, "%[BL_Lightning]", "\\cs(127,0,255)Lightning \\cr")
342 | v = string.gsub(v, "%[BL_Water]", "\\cs(0,76,153)Water \\cr")
343 | v = string.gsub(v, "%[BL_Light]", "\\cs(224,224,224)Light \\cr")
344 | v = string.gsub(v, "%[BL_Dark]", "\\cs(82,82,82)Dark \\cr")
345 | message = message .. ('\n%s'):format(v)
346 | end
347 | if S{'process', 'all'}[balloon.debug] then print("Final: " .. message) end
348 |
349 | ui:set_message(message)
350 | open(timed)
351 |
352 | return(result)
353 | end
354 |
355 | -- parses a string into char[hex bytecode]
356 | function codes(str)
357 | return (str:gsub('.', function (c)
358 | return string.format('%s[%02X]', c, string.byte(c))
359 | end))
360 | end
361 |
362 | function SubCharactersPreShift(str)
363 | local new_str = str
364 | if S{'chars', 'all'}[balloon.debug] then print("Pre-charsub pre-shift: " .. new_str) end
365 | new_str = string.gsub(new_str, string.char(0x81, 0x40), ' ') -- tab
366 | new_str = string.gsub(new_str, string.char(0x81, 0xF4), '[BL_note]') -- musical note
367 | new_str = string.gsub(new_str, chars.bstar, '[BL_bstar]') -- empty star
368 | new_str = string.gsub(new_str, chars.wstar, '[BL_wstar]') -- full star
369 | new_str = string.gsub(new_str, chars.wave, '[BL_wave]') -- wide tilde
370 | new_str = string.gsub(new_str, chars.cldquo, '[BL_cldquote]') -- centered left double quote
371 | new_str = string.gsub(new_str, chars.crdquo, '[BL_crdquote]') -- centered right double quote
372 | new_str = string.gsub(new_str, string.char(0x88, 0x69), '[BL_e_acute]') -- acute accented e
373 |
374 | -- element symbols
375 | new_str = string.gsub(new_str, string.char(0xEF,0x1F), "[BL_Fire]")
376 | new_str = string.gsub(new_str, string.char(0xEF,0x20), "[BL_Ice]")
377 | new_str = string.gsub(new_str, string.char(0xEF,0x21), "[BL_Wind]")
378 | new_str = string.gsub(new_str, string.char(0xEF,0x22), "[BL_Earth]")
379 | new_str = string.gsub(new_str, string.char(0xEF,0x23), "[BL_Lightning]")
380 | -- extra 0x25 in these two to escape the characters
381 | new_str = string.gsub(new_str, string.char(0xEF,0x25,0x24), "[BL_Water]")
382 | new_str = string.gsub(new_str, string.char(0xEF,0x25,0x25), "[BL_Light]")
383 | new_str = string.gsub(new_str, string.char(0xEF,0x26), "[BL_Dark]")
384 | if S{'chars', 'all'}[balloon.debug] then print("Post-charsub pre-shift: " .. new_str) end
385 | return new_str
386 | end
387 |
388 | function SubCharactersPostShift(str)
389 | local new_str = str
390 | if S{'chars', 'all'}[balloon.debug] then print("Pre-charsub post-shift: " .. new_str) end
391 | new_str = string.gsub(new_str, '%[BL_note]', '♪')
392 | new_str = string.gsub(new_str, '%[BL_bstar]', '☆')
393 | new_str = string.gsub(new_str, '%[BL_wstar]', '★')
394 | new_str = string.gsub(new_str, '%[BL_wave]', '~')
395 | new_str = string.gsub(new_str, '%[BL_cldquote]', '“')
396 | new_str = string.gsub(new_str, '%[BL_crdquote]', '”')
397 | new_str = string.gsub(new_str, '%[BL_e_acute]', 'é')
398 | if S{'chars', 'all'}[balloon.debug] then print("Post-charsub post-shift: " .. new_str) end
399 | return new_str
400 | end
401 |
402 | function split(str, delim)
403 | -- Eliminate bad cases...
404 | if string.find(str, delim) == nil then
405 | return { str }
406 | end
407 |
408 | local result = {}
409 | local pat = "(.-)" .. delim .. "()"
410 | local lastPos
411 | for part, pos in string.gfind(str, pat) do
412 | table.insert(result, part)
413 | lastPos = pos
414 | end
415 | table.insert(result, string.sub(str, lastPos))
416 | return result
417 | end
418 |
419 | windower.register_event("addon command", function(command, ...)
420 | local args = L{ ... }
421 |
422 | if command == 'help' then
423 | local t = {}
424 | t[#t+1] = "Balloon(Bl)" .. "Ver." .._addon.version
425 | t[#t+1] = " <コマンド> ()"
426 | t[#t+1] = " //Balloon 0 :吹き出し非表示&ログ表示 (Hiding balloon & displaying log)"
427 | t[#t+1] = " //Balloon 1 :吹き出し表示&ログ非表示 (Show balloon & hide log)"
428 | t[#t+1] = " //Balloon 2 :吹き出し表示&ログ表示 (Balloon display & log display)"
429 | t[#t+1] = " //Balloon reset :吹き出し位置初期化 (Initialize balloon position)"
430 | t[#t+1] = " //Balloon theme - loads the specified theme"
431 | t[#t+1] = " //Balloon scale - scales the size of the balloon by a decimal (eg: 1.5)"
432 | t[#t+1] = " //Balloon delay - delay before closing promptless balloons"
433 | t[#t+1] = " //Balloon text_speed - speed that text is displayed, in characters per frame"
434 | t[#t+1] = " //Balloon animate - toggle the advancement prompt indicator bouncing"
435 | t[#t+1] = " //Balloon portrait - toggle the display of character portraits, if the theme has settings for them"
436 | t[#t+1] = " //Balloon move_closes - toggle balloon auto-close on player movement"
437 | t[#t+1] = " //Balloon debug off/all/mode/codes/chunk/process/wrap/chars/elements - enable debug modes"
438 | t[#t+1] = " //Balloon test : - display a test balloon"
439 | t[#t+1] = " "
440 | for tk,tv in pairs(t) do
441 | windower.add_to_chat(207, windower.to_shift_jis(tv))
442 | end
443 |
444 | elseif command == '1' then
445 | settings.DisplayMode = 1
446 | log("モード (mode) 1 :吹き出し表示&ログ非表示 (Show balloon & hide log)")
447 |
448 | elseif command == '0' then
449 | settings.DisplayMode = 0
450 | log("モード (mode) 0 :吹き出し非表示&ログ表示 (Hiding balloon & displaying log)")
451 |
452 | elseif command == '2' then
453 | settings.DisplayMode = 2
454 | log("モード (mode) 2 :吹き出し表示&ログ表示 (Balloon display & log display)")
455 |
456 | elseif command == 'reset' then
457 | settings.Position.X = defaults.Position.X
458 | settings.Position.Y = defaults.Position.Y
459 | ui:position(settings.Position.X, settings.Position.Y)
460 | log("Balloon位置リセットしました。 (Balloon position reset.)")
461 |
462 | elseif command == 'theme' then
463 | if not args:empty() then
464 | local tp = 'themes/'..args[1]..'/theme.xml'
465 | if not windower.file_exists(windower.addon_path..tp) then
466 | log("theme.xml not found under %s":format(tp))
467 | return
468 | end
469 |
470 | local old_theme = settings.Theme
471 | settings.Theme = args[1]
472 | apply_theme()
473 | log("changed theme from '%s' to '%s'":format(old_theme, settings.Theme))
474 | else
475 | log("current theme is '%s' (default: %s)":format(settings.Theme, defaults.Theme))
476 | end
477 |
478 | elseif command == 'scale' then
479 | local old_scale = settings.Scale
480 | if not args:empty() then
481 | settings.Scale = tonumber(args[1])
482 | ui:scale(settings.Scale)
483 | log("scale changed from %.2f to %.2f":format(old_scale, settings.Scale))
484 | else
485 | log("current scale is %.2f (default: %.2f)":format(settings.Scale, defaults.Scale))
486 | end
487 |
488 | elseif command == 'delay' then
489 | local old_delay = settings.NoPromptCloseDelay
490 | if not args:empty() then
491 | settings.NoPromptCloseDelay = tonumber(args[1])
492 | log("promptless close delay changed from %d to %d":format(old_delay, settings.NoPromptCloseDelay))
493 | else
494 | log("current promptless close delay is %d (default: %d)":format(old_delay, defaults.NoPromptCloseDelay))
495 | end
496 |
497 | elseif command == 'text_speed' then
498 | local old_speed = settings.TextSpeed
499 | if not args:empty() then
500 | settings.TextSpeed = tonumber(args[1])
501 | log("text speed changed from %d to %d":format(old_speed, settings.TextSpeed))
502 | else
503 | log("current text speed is %d (default: %d)":format(settings.TextSpeed, defaults.TextSpeed))
504 | end
505 |
506 | elseif command == 'animate' then
507 | settings.AnimatePrompt = not settings.AnimatePrompt
508 | ui:position()
509 | log("animated text advance prompt - " .. (settings.AnimatePrompt and "on" or "off"))
510 |
511 | elseif command == 'portrait' then
512 | settings.ShowPortraits = not settings.ShowPortraits
513 | apply_theme()
514 | log("portrait display - " .. (settings.ShowPortraits and "on" or "off"))
515 |
516 | elseif command == 'move_closes' then
517 | settings.MovementCloses = not settings.MovementCloses
518 | if settings.MovementCloses then
519 | balloon.movement_thread = moving_check:schedule(0)
520 | else
521 | if balloon.movement_thread ~= nil and coroutine.status(balloon.movement_thread) ~= 'dead' then
522 | coroutine.close(balloon.movement_thread)
523 | end
524 | end
525 |
526 | log("close balloons on player movement - " .. (settings.MovementCloses and "on" or "off"))
527 |
528 | elseif command == 'debug' then
529 | if not args:empty() then
530 | balloon.debug = args[1]
531 | else
532 | balloon.debug = (balloon.debug == 'off' and 'all' or 'off')
533 | end
534 | log("set debug mode " .. balloon.debug)
535 |
536 | elseif command == 'test' then
537 | process_balloon(args:concat(' '), 150)
538 |
539 | end
540 |
541 | config.save(settings)
542 | end)
543 |
544 | windower.register_event("prerender",function()
545 | -- animate our text advance indicator bouncing up and down
546 | balloon.frame_count = balloon.frame_count + 1
547 | if balloon.frame_count > 60*math.pi*2 then balloon.frame_count = balloon.frame_count - 60*math.pi*2 end
548 |
549 | if balloon.on then
550 | if settings.AnimatePrompt then
551 | ui:animate_prompt(balloon.frame_count)
552 | end
553 | ui:animate_text_display(settings.TextSpeed)
554 | end
555 | end)
556 |
557 | windower.register_event('keyboard',function(key_id,pressed,flags,blocked)
558 | if windower.ffxi.get_info().chat_open or blocked then return end
559 | if balloon.on == true then
560 | if key_id == ENTER_KEY and pressed and not balloon.keydown then
561 | balloon.keydown = true
562 | close()
563 | end
564 | if key_id == SCROLL_LOCK_KEY and pressed and not balloon.keydown then
565 | balloon.keydown = true
566 | if not ui:hidden() then
567 | ui:hide()
568 | else
569 | ui:show()
570 | end
571 | end
572 | end
573 | if S{ENTER_KEY, SCROLL_LOCK_KEY}[key_id] and not pressed then balloon.keydown = false end
574 | end)
575 |
576 | windower.register_event("mouse",function(type,x,y,delta,blocked)
577 | if not ui.message_background:hover(x, y) then return false end
578 |
579 | -- press
580 | if type == 1 then
581 | balloon.mouse_on = true
582 | end
583 | -- release
584 | if type == 2 then
585 | balloon.mouse_on = false
586 | config.save(settings)
587 | end
588 | if balloon.mouse_on == true then
589 | update_position()
590 | end
591 | end)
592 |
593 | function update_position()
594 | settings.Position.X = ui.message_background:pos_x() + ui.message_background:width() / 2
595 | settings.Position.Y = ui.message_background:pos_y() + ui.message_background:height() / 2
596 |
597 | ui:position(settings.Position.X, settings.Position.Y)
598 | end
599 |
--------------------------------------------------------------------------------