├── .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 | ![AltanaView background color setting](AltanaView-set-background.png) 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 | ![AltanaView image size](AltanaView-image-size.png) 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 | ![AltanaView posing](AltanaView-posing.png) 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 | --------------------------------------------------------------------------------