diff --git a/ExtendedLore.md b/ExtendedLore.md index 103643077..af9bcd787 100644 --- a/ExtendedLore.md +++ b/ExtendedLore.md @@ -625,16 +625,12 @@ in my games here (though I'm avoiding spoilers for Doom Eternal, at least) - 2150~2151: The fight against the last remaining Demons on Earth continues. Doom Eternal happens. After defeating |BIG SPOILER HERE| contact with him is lost completely. -- 2156: Akari Labs succeeds in creating safe teleportation. The reaction from - the UAC on social media is legendary. +- 2156: Akari Labs succeeds in creating safe teleportation. - 2160: Demonic forces are discovered on several old UAC bases, having been resurrected by a "Mother Demon". Seeing as the Slayer is nowhere to be found, the Doom marine is re-commissioned to stop this madness, he succeeds, but in a last transmission states that he will "stay in Hell to make sure no demon ever comes out again". -- 2164: The remains of the Doom marine are found during a routine UAC - expedition, the Slayer is seen standing right next to them, as if paying - respects to a fellow warrior. - 2170: A group of monks discover a mansion haunted by demons, become trapped. The Doom Slayer heads in to "fix things". A mysterious figure is seen leaving the mansion afterwards. @@ -668,7 +664,7 @@ in my games here (though I'm avoiding spoilers for Doom Eternal, at least) entry into FTL travel. - 2200: Earth joins the X'Animen Coalition, now known as the "United Aligned Worlds". -- 2201: The UAC files for bankruptcy. +- 2207: All damage from the Hell Invasion of 2148 is finally repaired. - 2214: The Vortex Rikers crashes on planet Na Pali, Unreal begins. - 2215: The NEG is formed in anticipation of the coming Skaarj invasion. - 2216: The Seven Day Siege happens, the Skaarj are defeated. diff --git a/FuturePlans.md b/FuturePlans.md index 696cb9915..ab345dfe9 100644 --- a/FuturePlans.md +++ b/FuturePlans.md @@ -16,7 +16,6 @@ after the first release. - Radio - Pong minigame - Selling items at the store -* Fanart on the intermission screen * 4komas on the intermission screen * Actually make a fancy titlemap * Mod trailer diff --git a/TODO.md b/TODO.md index 68d842ea0..ae0c3038f 100644 --- a/TODO.md +++ b/TODO.md @@ -14,7 +14,6 @@ Extra things: - A background with a bit more flair than just the fuzz shader. - Some sort of flyby featuring the Demolitionist booting up, closeups of weapons/items etc. - - Money cheat? - Dual wielding Explodium Gun? - Japanese localization - Keen replacement (need ideas) diff --git a/graphics/HUDMockup.xcf b/graphics/HUDMockup.xcf deleted file mode 100644 index 1318e7f52..000000000 Binary files a/graphics/HUDMockup.xcf and /dev/null differ diff --git a/graphics/InterMockup.xcf b/graphics/InterMockup.xcf deleted file mode 100644 index 1554970da..000000000 Binary files a/graphics/InterMockup.xcf and /dev/null differ diff --git a/graphics/KBaseMockup.xcf b/graphics/KBaseMockup.xcf deleted file mode 100644 index dedb2221e..000000000 Binary files a/graphics/KBaseMockup.xcf and /dev/null differ diff --git a/language.def b/language.def index b315012cd..4f0c84f82 100644 --- a/language.def +++ b/language.def @@ -178,8 +178,8 @@ SWWM_HELPTXT = "\cx----------------------\c-\n" "\n" "\cfArrow Keys:\c- Navigate\n" -"\cfEnter:\c- Use selected item\n" -"\cfBackspace:\c- Drop selected item\n" +"\cfEnter/Left Click:\c- Use selected item\n" +"\cfBackspace/Right Click:\c- Drop selected item\n" "\n" "\cxKeychain Tab - Controls\c-\n" "\cx---------------------\c-\n" @@ -191,7 +191,7 @@ SWWM_HELPTXT = "\n" "\cfUp/Down:\c- Scroll through entries\n" "\cfLeft/Right:\c- Switch category\n" -"\cfEnter:\c- Open entry\n" +"\cfEnter/Left Click:\c- Open entry\n" "\n" "\cxLibrary Tab - Controls (Entry Open)\c-\n" "\cx---------------------------------\c-\n" @@ -203,21 +203,21 @@ SWWM_HELPTXT = "\cx------------------\c-\n" "\n" "\cfArrow Keys:\c- Navigate\n" -"\cfEnter:\c- Buy\n" -//"\cfBackspace:\c- Sell\n" +"\cfEnter/Left Click:\c- Buy\n" +//"\cfBackspace/Right Click:\c- Sell\n" "\n" "\cxTrading Tab - Controls (Main)\c-\n" "\cx---------------------------\c-\n" "\n" "\cfUp/Down:\c- Navigate\n" -"\cfEnter:\c- Select recipient\n" +"\cfEnter/Left Click:\c- Select recipient\n" "\cfBackspace:\c- History\n" "\n" "\cxTrading Tab - Controls (Trade)\c-\n" "\cx----------------------------\c-\n" "\n" "\cfArrow Keys:\c- Navigate\n" -"\cfEnter:\c- Send item\n" +"\cfEnter/Left Click:\c- Send item\n" "\cfBackspace:\c- Return\n" "\n" "\cxTrading Tab - Controls (History)\c-\n" @@ -313,6 +313,19 @@ SWWM_LORETXT_ANARUKON2 = "Addendum: The Anarukon are the humanoid race with the highest ratio of individuals who don't conform to the sex or gender binaries according to a recent census. Approximately 40% of the population falls under the \"intersex\" classification, and only 30% of the total population could be considered \"cisgender\". A study by Mosse Anderken traced this to a mutation in the Anarukon genome that appeared many years after the creation of the empire.\n" "\n" "Saya's Note: You know... I met Andreki once, after my wedding with Kirin-kun. I seriously thought she was just a little kid, god damn that was embarrassing... I also met some of her relatives, like this witchy looking lady... her aunt I think? I couldn't stare at her for too long, it made me anxious. T-there was also uhhh... her mom, really hardcore looking badass gutsy warrior mommy, another aunt who apparently likes to go around in a creepy costume and uses a voice changer to sound all evil, she was the most fun to talk to. I also met the GOD in all caps himself, the \"Father of Eternity\"... oh boy the tension when he was looking at me... but it was fine because turns out he's a real softly lol. Ahhh... it was so fun finally getting to meet these people after having only ever read about them, and oh boy don't even get me started on what it's like to be married to one, huhu. Finally, an immortal cutie just for me... and hot daaaamn he's a big cutie... and a beast in bed, uheheheheheh~"; +SWWM_LORETAG_ARC = "ARC"; +SWWM_LORETAB_ARC = "People"; +SWWM_LOREREL_ARC = "UAC;Hayden;Saya"; +SWWM_LORETXT_ARC = +"Name: Armored Response Coalition\n" +"Classification: Military Resistance Group\n" +"Location: Earth\n" +"\n" +"Summary: A group established following the downfall of the UAC, created by its former CEO Samuel Hayden as a means to unite all armed forces within the parts of Earth that were ravaged by Hell's armies, in order to fight back. They also assisted with evacuation efforts.\n" +"\n" +"Addendum: Following the end of the invasion, they have shifted their objective to attempt to repair all damage the planet has suffered. There are no clear estimates for how long this process may take, possibly centuries.\n" +"\n" +"Saya's Note: Y'know, about those \"repairs\", I've been trying to get some things in there to speed it all up. Look, maybe it's time for mankind to get its shit together and forgive the Nukuri, don't you think?"; SWWM_LORETAG_ARGENT = "Argent Energy"; SWWM_LORETAB_ARGENT = "Lore"; SWWM_LOREREL_ARGENT = "UAC;Hell;Saya;Nukuri;NokronKiny"; @@ -334,9 +347,9 @@ SWWM_LORETXT_ASHLEY = "Nationality: British\n" "Date Of Birth: 1887-10-31\n" "\n" -"Summary: Ashley was born in 1887 in London, to Yrikha Yanikov and Maxwell A. Knox. She has two younger siblings, Viola and Adrian, and a single son, Christopher. Ashley is most known for being the lead guitarist and singer of \"The Black Rat's Coven\", a Gothic Rock band composed entirely of witches that has toured all across the world. She is also a masterful painter and sculptor, with some of her works selling for millions.\n" +"Summary: Ashley is the oldest of the three children of Yrikha Yanikov and Maxwell A. Knox, the others being Adrian, an experienced soldier and veteran of both WW1 and WW2, and Viola, an apprentice witch. She was born in 1887 in London, but spent most of her childhood in Cornwall after her mother had to flee due to accusations of witchcraft. Ashley is most known for being the lead guitarist and singer of \"The Black Rat's Coven\", a Gothic Rock band composed entirely of witches that has toured all across the world. She is also a masterful painter and sculptor, with some of her works selling for millions.\n" "\n" -"Addendum: Shortly after the birth of her son in 1989, Ashley divorced her then-husband Fredrik Steiner. Many years later, during a concert in Japan in 2020, she met Yui Miyamoto, whom she married only a few days after the fact. Ashley regrets not having noticed sooner that she prefers women.\n" +"Addendum: Shortly after the birth of her only son, Christopher, in 1989, Ashley divorced her then-husband Fredrik Steiner. Many years later, during a concert in Japan in 2020, she met Yui Miyamoto, whom she married only a few days after the fact. Ashley regrets not having noticed sooner that she prefers women.\n" "\n" "Saya's Note: Bless this lesbian, amen. Ohhh... Ashley-san is simply amazing, I absolutely love her music, and it's really cool that we get invited to her concerts and stuff whenever. Also she hugged me once and HNNN that felt just amazinggggg!!! Ahhhh.... soft witch tiddy... ♥"; SWWM_LORETAG_BELT = "Utility Belt"; @@ -504,7 +517,7 @@ SWWM_LORETXT_DEVANIKNA = "Addendum: These people are fond of adventuring and slaying beasts, many clan members having quite a lot of tales to tell of their exploits. Deneva Unissix, older sister of Misa Unissix, is currently one of the most well known warriors, having been the one to finally defeat Mero The Destructor, a mighty, hulking golem built by the Shadow Prince Kuro Noroko who for centuries had spread terror across Ixxeney.\n" "\n" "Saya's Note: Misa's people are cool af. They kinda make me think of this one old JRPG series I played many many years ago, it had to do with people of dragon blood too... uh... forgot what it was called... oh well. Cool Dragon warriors, fuck yeah."; -SWWM_LORETAG_DISPLAY = "CuteEmotion Display"; +SWWM_LORETAG_DISPLAY = "CuteEmotion"; SWWM_LORETAB_DISPLAY = "Item"; SWWM_LOREREL_DISPLAY = "AkariLabs;Demolitionist;Ibuki;Saya"; SWWM_LORETXT_DISPLAY = @@ -530,14 +543,14 @@ SWWM_LORETXT_DOOMGUY = "Saya's Note: Sorry about the lack of info here, those UAC goons really keep it well-guarded. At least I heard he likes bunnies, so if the worst happens just pretend to be one and he might not shoot you on sight."; SWWM_LORETAG_DOOMSLAYER = "Doom Slayer"; SWWM_LORETAB_DOOMSLAYER = "People"; -SWWM_LOREREL_DOOMSLAYER = "Hell;UAC;Doomguy;Saya;Yui;Ashley"; +SWWM_LOREREL_DOOMSLAYER = "Hell;UAC;Doomguy;Saya;Yui;Ashley;Sentinels"; SWWM_LORETXT_DOOMSLAYER = "Full Name: Unknown\n" "Codename: Doom Slayer\n" "Nationality: Unknown\n" "Date of Birth: Unknown\n" "\n" -"Summary: The Slayer is a living legend for all of humanity. A single man who put the final nail in the coffin for the Demon invasion on Earth. Initially found by the UAC, encased in a massive stone sarcophagus, this man jumped straight into action in 2149, during an invasion on Mars City, and ever since then never stopped killing demons wherever he went. The UAC has attempted to turn him to their side, several times, but he answers to no one and always works independently.\n" +"Summary: The Slayer is a living legend for all of humanity. A single man who put the final nail in the coffin for the Demon invasion on Earth. Initially found by the UAC, encased in a massive stone sarcophagus, this man jumped straight into action in 2149, during an invasion on Mars City, and ever since then never stopped killing demons wherever he went. The UAC had attempted to turn him to their side, several times, but he answers to no one and always works independently. He appears to be related to some alien species known as the \"Sentinels\", though not much is known about them, or if he even is one of them.\n" "\n" "Addendum: The Slayer has a side most people don't know about. He's an avid collector, and has been witnessed picking up several things during his time in Earth, including various literary and film works, videogames, collectable figurines, musical instruments, etc. He apparently loves rabbits, too, a trait shared with the Doom Marine.\n" "\n" @@ -724,7 +737,7 @@ SWWM_LORETXT_HAMMERSPACEEMBIGGENER = "Saya's Note: Is that even a real word?"; SWWM_LORETAG_HAYDEN = "Hayden, Samuel"; SWWM_LORETAB_HAYDEN = "People"; -SWWM_LOREREL_HAYDEN = "UAC;Argent;Hell;Saya"; +SWWM_LOREREL_HAYDEN = "UAC;Argent;Hell;Saya;ARC"; SWWM_LORETXT_HAYDEN = "Full Name: Samuel Hayden\n" "Nationality: American\n" @@ -735,6 +748,16 @@ SWWM_LORETXT_HAYDEN = "Addendum: In 2127, in an attempt to save himself from an incurable cancer, he transferred his consciousness to a robotic body.\n" "\n" "Saya's Note: \"Philanthropist\" my butt. This guy is the most obnoxious, pedantic, assholish, snobbish, rich-bastard-asshole of an asshole of a stinking piece of junk robot that has ever walked the Earth, or Mars, or Hell. The fucker even has me blocked on Twitter because he KNOWS what I think of him and his stupid-ass UAC, and all the bullshit he's done for the \"betterment of mankind\" has only brought us pain and suffering. If I could I'd just... go there and kick his shiny metal ass, and show him what I think of him going around using Demon Cummies to solve the energy crisis."; +SWWM_LORETXT_HAYDEN2 = +"Full Name: Samuel Hayden\n" +"Nationality: American\n" +"Date Of Birth: 2019, exact date unknown\n" +"\n" +"Summary: A self-appointed \"intellectual and philanthropist\" from a rich family, recruited into the UAC due to his achievements at the Global Science Council. His discovery of Argent Energy led to him taking the position of CEO. In 2145 he led the first manned expedition to Hell, only a year after the initial contact. Following the \"Doom Episodes\" of 2148, he left the UAC, by then already corrupted by Hell's influence, to form the ARC.\n" +"\n" +"Addendum: In 2127, in an attempt to save himself from an incurable cancer, he transferred his consciousness to a robotic body.\n" +"\n" +"Saya's Note: You know, I'm glad he tried to do something GOOD after all the countless fuckups from the UAC. At least he put some effort into compensating for all that shit, shame he got his ass kicked in the process."; SWWM_LORETAG_HEALTHGEOM = "Health Geodesics"; SWWM_LORETAB_HEALTHGEOM = "Item"; SWWM_LOREREL_HEALTHGEOM = "EngineTech;Saya;"; @@ -749,7 +772,7 @@ SWWM_LORETXT_HEALTHGEOM = "Saya's Note: I talked with the guy and you're allowed to use these, and any other things they have, so you're going to see them all over the place during your mission."; SWWM_LORETAG_HELL = "Hell"; SWWM_LORETAB_HELL = "Lore"; -SWWM_LOREREL_HELL = "Imanaki;UAC;Saya;Ellen;Doomslayer"; +SWWM_LOREREL_HELL = "Imanaki;UAC;Saya;Ellen;Doomslayer;Maykrs"; SWWM_LORETXT_HELL = "Name: Hell\n" "Classification: Nether realm\n" @@ -765,7 +788,7 @@ SWWM_LORETXT_HELL2 = "\n" "Summary: A vast world separate from our own, inhabited by creatures that could only be described as \"demons\". This Hell was first discovered through the various interdimensional travel experiments done by Imanaki Corp back in the early 21st century, although the UAC has put a lot of effort into hiding this fact and claiming to be the first to do so instead. Their response to the UAC walking right in and attempting to steal their precious resources was that of total annihilation. Starting from the first incidents on Mars and its moons, then a full-fledged invasion of Earth. Had it not been for the Doom Slayer's actions, humanity would have perished.\n" "\n" -"Addendum: The rulers of Hell at the time were not legitimately recognized by most of the population, as they had forcibly taken over when the true Royal Family gave them more power than they should. Hell used to be a much quieter place before their hostile takeover, relatively peaceful, even, apart from some rare incursions by other nations who saw them as enemies. The various generals of Hell's armies desired more power, to fight back those pesky invaders, and so Prince Akusei gave it to them, a terrible mistake he regrets to this day.\n" +"Addendum: The rulers of Hell at the time were not legitimately recognized by most of the population, as they had forcibly taken over when the true Royal Family gave them more power than they should. Hell used to be a much quieter place before their hostile takeover, relatively peaceful, even, apart from some rare incursions by other nations who saw them as enemies. The various generals of Hell's armies desired more power, to fight back those pesky invaders, and so Prince Akusei gave it to them, a terrible mistake he regrets to this day. After their defeat, more information has surfaced, including details of a collaboration with a species of \"angelic beings\" known as the Maykrs, having received even greater power in exchange for access to their Argent Energy supplies.\n" "\n" "Saya's Note: I know quite a lot about Hell's history thanks to Cytho-sama, Ellen-chan's grandfather. He tells us lots of stories about his life back there. It's intriguing that, in a way, they are not ALL bad, and I bet the good people in there also had it rough seeing what their armies did to us. Stuff like this... it's much more common than one may think. You can't really paint one whole nation as \"the enemy\", there are many innocent people in there who want none of it, who actively reject and denounce what's happening...\n"; SWWM_LORETAG_HELLBLAZER = "Hellblazer"; @@ -884,6 +907,19 @@ SWWM_LORETXT_KNOWLEDGEBASE = "Addendum: The quality of articles may vary, this depends entirely on how motivated the editor felt when writing them.\n" "\n" "Saya's Note: Taro is the one editing all this stuff, by the way. Sometimes I help, though, and leave some of my thoughts in footnotes like this one."; +SWWM_LORETAG_MAYKRS = "Maykrs"; +SWWM_LORETAB_MAYKRS = "Lore"; +SWWM_LOREREL_MAYKRS = "Hell;Doomslayer;Saya;SUSAN"; +SWWM_LORETXT_MAYKRS = +"Name: Maykrs\n" +"Classification: Alien Race\n" +"Location: Urdak\n" +"\n" +"Summary: A highly advanced alien species, originating from a far away realm. Said to be angelic in appearance, and wielding unbelievable power. There are no further details on them beyond what's loosely known from leaked documents.\n" +"\n" +"Addendum: Their involvement in the Hell invasion was discovered following the fall of Hell's military government by the Doom Slayer's hands. They were the ones who decided to invade Earth after the UAC began tapping into the Argent Energy that they depended on to survive, giving part of their power to Hell's armies.\n" +"\n" +"Saya's Note: Yeah, I think I remember something. This whole thing about \"angels\" and whatnot. It's like, the second time people have fallen for this shit, thinking that some random aliens are \"heavenly beings\" when they are just a bunch of assholes instead. I won't ask you to go hit the history books for this, so look up the related entry on \"SUSAN\"."; SWWM_LORETAG_MOTHLAMP = "Lämp"; SWWM_LORETAB_MOTHLAMP = "Item"; SWWM_LOREREL_MOTHLAMP = "Sankaideriha;Saya"; @@ -1235,6 +1271,18 @@ SWWM_LORETXT_SERPENTRIDERS = "Summary: A triad of evil sorcerers known all over these lands. All those who've dared fight against them haven't been very lucky. D'Sparil claimed the land of Parthoris, his many armies of undead having taken over the land before our arrival. Then in the land of Cronos there's Korax, a dark beast that taunts all those who challenge him. We haven't received much information on the third member, but this information will come eventually as we keep exploring these new worlds.\n" "\n" "Saya's Note: I'm sure you can wipe out all these idiots without any issue, they have no idea of how strong you are (or of what you are, now that I think of it, these worlds hardly seem to know much about our technology)."; +SWWM_LORETAG_SENTINELS = "Sentinels"; +SWWM_LORETAB_SENTINELS = "Lore"; +SWWM_LOREREL_SENTINELS = "Doomslayer;Hell;Saya"; +SWWM_LORETXT_SENTINELS = +"Name: Sentinels\n" +"Location: Unknown\n" +"\n" +"Summary: Also known by the name of \"Argenta\", they an alien species of formidable warriors, said to have traveled across the whole universe countless years ago, including Earth itself. There is not much information available about them, other than scattered bits of their lore.\n" +"\n" +"Addendum: Possible relation (hostile) with Hell, but we can't find exact details on the subject, most of the data has been lost.\n" +"\n" +"Saya's Note: Yeah, I'm stumped here. I would love to dig more into this, you think that maybe I could ask Slayer boi? He'd probably ignore me, I bet."; SWWM_LORETAG_SIDHE = "Sidhe"; SWWM_LORETAB_SIDHE = "Lore"; SWWM_LOREREL_SIDHE = "Parthoris;Saya"; @@ -1305,7 +1353,7 @@ SWWM_LORETXT_SPREADGUN = "Saya's Note: Shit looks impractical AF, especially that reload method. How the fuck no one has made a hole through their own palm pushing the barrel back in is beyond me."; SWWM_LORETAG_SUNKAEZE = "Sunkaeze"; SWWM_LORETAB_SUNKAEZE = "Lore"; -SWWM_LOREREL_SUNKAEZE = "XAnimen;DecadeMech;Gods;Yui"; +SWWM_LOREREL_SUNKAEZE = "XAnimen;DecadeMech;Gods;Yui;Saya"; SWWM_LORETXT_SUNKAEZE = "Name: Sunkaeze\n" "Classification: Dead Planet\n" @@ -1314,6 +1362,17 @@ SWWM_LORETXT_SUNKAEZE = "Summary: A completely barren planet, thought to be completely empty, until an expedition discovered the ruins of a facility belonging to the defunct Decade Mechanics, an ancient industrial group founded by the late mechanical demigod Maester Mekes.\n" "\n" "Saya's Note: Gods, demigods... all this stuff... One would hardly believe such things to exist but come on, after finding out that aliens are very real, it's hard to not believe in this stuff too. Hell, I MET one once... like I'm not even bullshitting you here, I met a LITERAL GOD. It happened when I was visiting Yui's girl: there was with this nerdy-looking lady that gave off this sort of \"aura\". Her name's Mykka, and she was really nice to talk to, even gave me some candy. Boy I wish I could just talk more about this stuff, but I don't want to fill these entries with unrelated info."; +SWWM_LORETAG_SUSAN = "S.U.S.A.N."; +SWWM_LORETAB_SUSAN = "Lore"; +SWWM_LOREREL_SUSAN = "Kereshnovka;Gods;Saya;Nukuri;Luna"; +SWWM_LORETXT_SUSAN = +"Name: Spear of Unmaking, Severance, Annihilation and Nullification\n" +"Classification: Weapon of Mass Destruction\n" +"Location: Kereshnovka\n" +"\n" +"Summary: An AI-controlled megastructure dozens of kilometers tall, created by a mysterious Qurensniv group called the \"Faculty of Illuminated Nobodies\". Having taken hundreds of years to build, it was finally activated in 2018, after which it took control of Russia's missile systems. Its presence on Earth, as a major threat, was what prompted the Nukuri to initiate the \"Luna Event\". Nukuri forces dispatched in 2021 neutralized the AI, however it was found to be impossible to destroy, so it just stood there, floating in the Arctic seas. In 2097, long after the White Scar incident, and with the Nukuri no longer available to defend the planet, an entity called \"Uruk'Anth\" appeared on Earth, announcing himself to be \"God\", and that it was his will for that machine to bring an end to the world, after humanity had proven to no longer be worthy of his blessing. SUSAN was reactivated, this time taking over the weapon sytems of several major world powers. Earth lived in fear for two long scary years, with the AI broadcasting a staggeringly slow countdown to \"World Purification\", until it was somehow deactivated again and destroyed.\n" +"\n" +"Saya's Note: Like, seriously. \"I am God and I say you must die\", he goes. Yeah, fuck that guy. No one knows, at all, what the fuck happened the second time. It's a mystery how it just... poofed like that, taking out the guy in the process, too."; SWWM_LORETAG_SYMNATEK = "Symnatek"; SWWM_LORETAB_SYMNATEK = "People"; SWWM_LOREREL_SYMNATEK = "Mixom;Saya"; @@ -1358,9 +1417,9 @@ SWWM_LORETXT_UAC2 = "Classification: Military Conglomerate, Research Foundation\n" "Location: Union States, Mars and Jupiter\n" "\n" -"Summary: Founded in 2015 by Thomas Kelliher, as a shell company of the Union Aerospace Armed Forces (UAAF). The UAC's rise to power began in 2025 with its famous Joint Mars Expeditions. Since the creation of \"Mars City\" and the various posts in Phobos and Deimos, the UAC has been effectively working outside of Earth law, which has caused endless controversy. Moreso after securing their position as the largest military body on Earth in the aftermath of World War 3. They were mainly responsible for the invasion from Hell which caused more than half of the planet to be almost entirely wiped out by Demonic forces. However, thanks to their retrieval of the Doom Slayer, the invasion was switfly dealt with. Ever since the incident, there have been no further statements from CEO Samuel Hayden, some suspect he may be dead.\n" +"Summary: Founded in 2015 by Thomas Kelliher, as a shell company of the Union Aerospace Armed Forces (UAAF). The UAC's rise to power began in 2025 with its famous Joint Mars Expeditions. Since the creation of \"Mars City\" and the various posts in Phobos and Deimos, the UAC has been effectively working outside of Earth law, which has caused endless controversy. Moreso after securing their position as the largest military body on Earth in the aftermath of World War 3. They were mainly responsible for the invasion from Hell which caused more than half of the planet to be almost entirely wiped out by Demonic forces. However, thanks to their retrieval of the Doom Slayer, the invasion was switfly dealt with. Ever since the incident, the company has been unable to recover, having lost most of its employees, along with former CEO Samuel Hayden.\n" "\n" -"Addendum: The company fell under demonic control during the invasion (although some say this had been the case long before the event), and is currently still putting itself back together. However there is not much hope for a full recovery, as most of its employees keep leaving.\n" +"Addendum: The company fell under demonic control during the invasion (although some say this had been the case long before the event), even having high ranking members of Hell's military government in charge of some of its divisions. After the invasion was dealt with, there's been attempts to get things back in order, though there isn't much hope for this to ever come to happen.\n" "\n" "Saya's Note: It's satisfying as all fuck to see this ugly-ass giant fall. Man, the whole thing with the invasion was just awful, you know. But I'm happy that we at least did our part in helping there, even if it was nothing compared to what Slayer boi did..."; SWWM_LORETAG_UNISSIX = "Unissix, Misa A."; diff --git a/language.es b/language.es index 12f037512..5eef07785 100644 --- a/language.es +++ b/language.es @@ -174,8 +174,8 @@ SWWM_HELPTXT = "\cx-------------------------------\c-\n" "\n" "\cfFlechas:\c- Navegar\n" -"\cfEnter:\c- Usar item seleccionado\n" -"\cfRetroceso:\c- Descartar item seleccionado\n" +"\cfEnter/Click Izdo.:\c- Usar item seleccionado\n" +"\cfRetroceso/Click Dcho.:\c- Descartar item seleccionado\n" "\n" "\cxPestaña de Llavero - Controles\c-\n" "\cx----------------------------\c-\n" @@ -187,7 +187,7 @@ SWWM_HELPTXT = "\n" "\cfArriba/Abajo:\c- Scroll por entradas\n" "\cfLeft/Right:\c- Cambiar categoría\n" -"\cfEnter:\c- Abrir entrada\n" +"\cfEnter/Click Izdo.:\c- Abrir entrada\n" "\n" "\cxPestaña de Biblioteca - Controles (Entrada Abierta)\c-\n" "\cx-------------------------------------------------\c-\n" @@ -199,21 +199,21 @@ SWWM_HELPTXT = "\cx---------------------------\c-\n" "\n" "\cfFlechas:\c- Navegar\n" -"\cfEnter:\c- Comprar\n" -//"\cfRetroceso:\c- Vender\n" +"\cfEnter/Click Izdo.:\c- Comprar\n" +//"\cfRetroceso/Click Dcho.:\c- Vender\n" "\n" "\cxPestaña de Intercambio - Controles (Principal)\c-\n" "\cx---------------------------\c-\n" "\n" "\cfArriba/Abajo:\c- Navegar\n" -"\cfEnter:\c- Elegir destinatario\n" +"\cfEnter/Click Izdo.:\c- Elegir destinatario\n" "\cfRetroceso:\c- Historial\n" "\n" "\cxPestaña de Intercambio - Controles (Intercambio)\c-\n" "\cx----------------------------\c-\n" "\n" "\cfFlechas:\c- Navegar\n" -"\cfEnter:\c- Enviar item\n" +"\cfEnter/Click Izdo.:\c- Enviar item\n" "\cfRetroceso:\c- Volver\n" "\n" "\cxPestaña de Intercambio - Controles (Historial)\c-\n" @@ -303,6 +303,16 @@ SWWM_LORETXT_ANARUKON2 = "Apéndice: Los Anarukon son una de las razas humanoides con la proporción más alta de individuos que no entran dentro del sexo o género binarios segun un reciente censo. Aproximadamente el 40% de la población se puede clasificar como \"intersexo\", y solo un 30% de la población total se puede considerar \"cisgénero\". Un estudio de Mosse Anderken pudo trazar esto a una mutación en el genoma Anarukon que apareció varios años despues de la creación del imperio.\n" "\n" "Nota de Saya: Sabes... conocí a Andreki una vez, despues de la boda con Kirin-kun. En serio que creía que era solo una niña, dios que vergüenza... También conocí a algunos de sus familiares, como la tipa esta que parece una bruja... su tía ¿creo? No pude mirarla mucho, me ponía los pelos de punta. T-también estaba hmmm... su madre, una guerrera super hardcore tipo Guts, pero en mami, luego otra tía a la que le mola ir por ahí con un disfraz que da mucho mal rollo y usa un alterador de voz para parecer un tío siniestro, me lo pasé de muerte hablando con ella, es majísima. También conocí al mismísimo DIOS en mayúsculas, el \"Padre de Eternidad\"... oh tío la tensión cuando me miraba... pero luego se me pasó, porque en persona es un blandengue. Ahhh... fue la rehostia conocer por fin a toda esta gente despues de solo haber leido sobre ellos, y oh dios no empecemos con lo que es haberme casado con uno, juju. Por fin, un guapetón inmortal solo para mí... y maaaaaadre es que es monísimo... y una fiera en la cama, ijijijijiji~"; +SWWM_LORETXT_ARC = +"Nombre: Coalición de Respuesta Armada (ARC)\n" +"Clasificación: Grupo de Resistencia Militar\n" +"Localización: Tierra\n" +"\n" +"Resumen: Un grupo establecido tras la caída de la UAC, creado por su anterior CEO Samuel Hayden a modo de unir todas las fuerzas armadas en las zonas terrestres afectadas por los ejércitos del Infierno, para contraatacar. También han asistido con los esfuerzos de evacuación.\n" +"\n" +"Apéndice: Tras finalizar la invasión, han cambiado su objetivo a intentar reparar el daño que el planeta ha sufrido. No hay estimaciones claras de cuanto puede que tarde este proceso, es posible que siglos.\n" +"\n" +"Nota de Saya: Oye, sobre eso de \"reparar\", he estado intentando unas cosillas, a ver si se puede acelerar esto. Mira, tal vez sea hora de que la humanidad espabile ya y perdone a los Nukuri, ¿no crees?"; SWWM_LORETAG_ARGENT = "Energía Argent"; SWWM_LORETXT_ARGENT = "Nombre: Energía Argent\n" @@ -319,9 +329,9 @@ SWWM_LORETXT_ASHLEY = "Nacionalidad: Británica\n" "Fecha de Nacimiento: 31 de Octubre de 1887\n" "\n" -"Resumen: Ashley nació en Londres en 1887, hija de Yrikha Yanikov y Maxwell A. Knox. Tiene dos hermanos menores, Viola y Adrian, y un único hijo, Christopher. Ashley es conocida mayormente por ser la guitarrista y cantante de \"The Black Rat's Coven\" (\"El Aquelarre de la Rata Negra\"), una banda de Rock Gótico compuesta íntegramente de brujas que ha estado de gira por todo el mundo. Tambien es una maestra en pintura y escultura, con algunas de sus obras vendiéndose por millones.\n" +"Resumen: Ashley es la mayor de los tres hijos de Yrikha Yanikov y Maxwell A. Knox, los otros siendo Adrian, un experimentado soldado veterano de la primera y segunda guerras mundiales, y Viola, una aprendiz de bruja. Nació en Londres en 1887, pero pasó la mayor parte de su infancia en Cornualles, despues de que su madre tuviera que darse a la fuga debido a acusaciones de brujería. Ashley es conocida mayormente por ser la guitarrista y cantante de \"The Black Rat's Coven\" (\"El Aquelarre de la Rata Negra\"), una banda de Rock Gótico compuesta íntegramente de brujas que ha estado de gira por todo el mundo. Tambien es una maestra en pintura y escultura, con algunas de sus obras vendiéndose por millones.\n" "\n" -"Apéndice: Poco después del nacimiento de su hijo en 1989, Ashley se divorció del que entonces era su marido, Fredrik Steiner. Muchos años después, durante un concierto en Japón en 2020, conoció a Yui Miyamoto, con quien se casó solo unos pocos días tras el suceso. Ashley lamenta no haberse dado cuenta antes de que prefiere estar con mujeres.\n" +"Apéndice: Poco después del nacimiento de su único hijo, Christopher, en 1989, Ashley se divorció del que entonces era su marido, Fredrik Steiner. Muchos años después, durante un concierto en Japón en 2020, conoció a Yui Miyamoto, con quien se casó solo unos pocos días tras el suceso. Ashley lamenta no haberse dado cuenta antes de que prefiere estar con mujeres.\n" "\n" "Nota de Saya: Bendita sea esta lesbiana, amen. Ohhh... Ashley-san es simplemente la mejor, adoro su música, y mola mucho que nos invite a sus conciertos y tal cuando toca. Ah y recuerdo que una vez me dió un abrazo y HNNN ¡¡¡dios es que fue LO MEJOR!!! Ahhhh... suaves pechotes de bruja... ♥"; SWWM_LORETAG_BELT = "Cinturón Útil"; @@ -459,7 +469,6 @@ SWWM_LORETXT_DEVANIKNA = "Apéndice: Esta gente adora las aventuras y matar bestias, todos los miembros de cada clan tienen muchas historias que contar sobre sus hazañas. Deneva Unissix, hermana mayor de Misa Unissix, es actualmente una de las guerreras más populares, habiendo finalmente derrotado a Mero el Destructor, un imponente y gigantesco golem construido por el Príncipe de las Sombras Kuro Noroko quien durante siglos había desatado el terror por todo Ixxeney.\n" "\n" "Nota de Saya: La gente de Misa mola un huevo. Casi que me hacen pensar en esta serie de JRPGs a la que jugaba hace un chorrón de años, también iba de gente con sangre de dragón... eh... pues no me acuerdo de como se llamaba... en fin. Molones guerreros de Dragones, toma ya."; -SWWM_LORETAG_DISPLAY = "Pantalla CuteEmotion"; SWWM_LORETXT_DISPLAY = "Designación: Pantalla CuteEmotion\n" "Fabricante: Akari Labs\n" @@ -484,7 +493,7 @@ SWWM_LORETXT_DOOMSLAYER = "Nacionalidad: Desconocido\n" "Fecha de Nacimiento: Desconocido\n" "\n" -"Resumen: El Slayer es una leyenda viviente para toda la humanidad. Un solo hombre que dió el golpe de gracia a la invasión demoníaca en la Tierra. Inicialmente encontrado por la UAC, encasquetado en un gigantesco sarcófago de piedra, este hombre saltó directamente a la acción en 2149, durante una invasión en Mars City, y desde entonces no ha parado de matar demonios por doquier. La UAC ha intentado que se ponga de su lado, varias veces, pero no responde a nadie y siempre trabaja por su cuenta.\n" +"Resumen: El Slayer es una leyenda viviente para toda la humanidad. Un solo hombre que dió el golpe de gracia a la invasión demoníaca en la Tierra. Inicialmente encontrado por la UAC, encasquetado en un gigantesco sarcófago de piedra, este hombre saltó directamente a la acción en 2149, durante una invasión en Mars City, y desde entonces no ha parado de matar demonios por doquier. La UAC ha intentado que se ponga de su lado, varias veces, pero no responde a nadie y siempre trabaja por su cuenta. Parece tener algun tipo de relación con una especie alienígena conocida como los \"Centinelas\", aunque no se sabe mucho de ellos, o si es uno de ellos.\n" "\n" "Apéndice: El Slayer tiene un lado que la mayoría de la gente desconoce. Es un colector nato, y testigos han confirmado verlo recoger varios objetos durante su estancia en la Tierra, incluyendo varias obras literarias y cinematográficas, videojuegos, figuras coleccionables, instrumentos musicales, etc. Aparentemente le encantan los conejos, tambien, un rasgo compartido con el Marine de Doom.\n" "\n" @@ -645,6 +654,16 @@ SWWM_LORETXT_HAYDEN = "Apéndice: En 2127, en un intento de salvarse de un cancer incurable, transmitió su consciencia a un cuerpo robótico.\n" "\n" "Nota de Saya: ¿\"Filántropo\"? Y una polla como la manga de un abrigo. Este tío es el mayor pedante capullo snob ricachón cerdo capitalista de mierda robot asqueroso montón de chatarra que jamás haya pisado la Tierra, o Marte, o el Infierno. El hijo de puta hasta me tiene bloqueada en Twitter porque SABE lo que pienso de él y de su estúpida UAC, y toda la mierda que está haciendo para \"mejorar la humanidad\" solo nos ha traido disgustos. Si pudiera es que... yo iba ahí y le daba una patada así en su brillante trasero metálico, y ya le enseñaba yo lo que pienso de que vaya por ahí usando Lefa de Demonio para resolver la crisis energética."; +SWWM_LORETXT_HAYDEN2 = +"Nombre Completo: Samuel Hayden\n" +"Nacionalidad: Americano\n" +"Fecha De Nacimiento: 2019, fecha exacta desconocida\n" +"\n" +"Resumen: Un autodeclarado \"intelectual y filántropo\" de una familia rica, reclutado por la UAC debido a sus logros en el Consejo Global de las Ciencias. Su descubrimiento de la Energía Argent lo llevó a tomar la posición de CEO. En 2145 lideró la primera expedición tripulada al Infierno, solamente un año despues del primer contacto. Tras los \"Episodios de Doom\" de 2148, abandonó la UAC, por entonces ya corrompida por la influencia del Infierno, para formar la ARC.\n" +"\n" +"Apéndice: En 2127, en un intento de salvarse de un cancer incurable, transmitió su consciencia a un cuerpo robótico.\n" +"\n" +"Nota de Saya: Sabes, me alegro de que intentara hacer algo BUENO despues de incontables jodiendas de la UAC. Al menos se ha esforzado por compensar toda esa mierda, una pena que le partieran el culo en el proceso."; SWWM_LORETAG_HEALTHGEOM = "Geodésico de Salud"; SWWM_LORETXT_HEALTHGEOM = "Designación: Geodésico de Salud\n" @@ -671,7 +690,7 @@ SWWM_LORETXT_HELL2 = "\n" "Resumen: Un vasto mundo separado del nuestro, habitado por criaturas que solo pueden ser descritas como \"demonios\". Este Infierno fue inicialmente descubierto a través de los muchos experimentos de viaje interdimensional de Imanaki Corp allá a principios del siglo 21, aunque la UAC se ha esforzado bastante en ocultar este hecho y pretender que ellos fueron los primeros en hacerlo. La respuesta a la UAC haciendo su entrada e intentando robar sus valiosos recursos fue la de aniquilación total. Empezando con los primeros incidentes en Marte y sus lunas, y más tarde una total invasión de la Tierra. Si no hubiera sido por las acciones del Doom Slayer, la humanidad habría perecido.\n" "\n" -"Apéndice: Los líderes del Infierno en aquel entonces no eran reconocidos de forma legítima por la mayoría de la poblacion, ya que habían tomado el mando por la fuerza cuando la Familia Real les dió más poder del que deberían. El Infierno solía ser un lugar más tranquilo antes de su hostil toma de poder, relativamente pacífico, incluso, aparte de alguna que otra incursión de otras naciones que los veían como enemigos. Los diversos generales de las armadas del Infierno deseaban más poder, para luchar contra estos molestos invasores, y así el Príncipe Akusei se lo dió, un terrible error que lamenta hasta este día.\n" +"Apéndice: Los líderes del Infierno en aquel entonces no eran reconocidos de forma legítima por la mayoría de la poblacion, ya que habían tomado el mando por la fuerza cuando la Familia Real les dió más poder del que deberían. El Infierno solía ser un lugar más tranquilo antes de su hostil toma de poder, relativamente pacífico, incluso, aparte de alguna que otra incursión de otras naciones que los veían como enemigos. Los diversos generales de las armadas del Infierno deseaban más poder, para luchar contra estos molestos invasores, y así el Príncipe Akusei se lo dió, un terrible error que lamenta hasta este día. Tras su derrota, más información ha aparecido, incluyendo detalles de una colaboración con una especie de \"entes angelicales\" conocidos como los Maykrs, habiendo recibido incluso mayor poder a cambio del acceso a sus suministros de Energía Argent.\n" "\n" "Nota de Saya: Sé bastante de la historia del Infierno gracias a Cytho-sama, el abuelo de Ellen-chan. Nos cuenta sus batallitas de cuando vivía allí. Es interesante, en cierto modo, que no son TODOS tan mala gente, y me apuesto a que la buena gente de ahí tambien lo tuvo crudo viendo lo que sus ejércitos nos hicieron. Cosas así... pasa más a menudo de lo que uno cree. No puedes ir pintando a toda una nación como \"el enemigo\", si hay mucha gente inocente por ahí que no quiere tomar parte de sus mierdas, que rechaza y denuncia activamente lo que está pasando..."; SWWM_LORETXT_HELLBLAZER = @@ -816,6 +835,16 @@ SWWM_LORETXT_MAIDBOT = "Apéndice: Hubo un tiempo en el que Maidbot fué adaptada a un \"cuerpo de combate\" experimental para asistir al Oni Rojo en su misión en los EEUU. Probó ser efectiva, pero no se sintió cómoda con su trabajo y prefirió volver a ser una chica normal después de todo.\n" "\n" "Nota de Saya: Sabes... todas mis maidbots, van completamente equipadas, ¿eh? Tú ya me entiendes... están capacitadas para el \"amor\". Maidbot no es una excepción, y deja que te diga... es como estár en el cielo cuando lo hacemos... ♥"; +SWWM_LORETXT_MAYKRS = +"Nombre: Maykrs\n" +"Clasificación: Raza Alienígena\n" +"Localización: Urdak\n" +"\n" +"Resumen: Una especie alienígena altamente avanzada, originaria de un mundo lejano. Se dice que tienen apariencia angélica, y poseen poderes increíbles. No hay más detalles al respecto aparte de lo poco que se sabe de documentos filtrados.\n" +"\n" +"Apéndice: Su intervención en la invasión del Infierno fue descubierta tras la caída del gobierno militar del Infierno a manos del Doom Slayer. Fueron los que decidieron invadir la Tierra después de que la UAC comenzara a aprovecharse de la Energía Argent de la que dependían para sobrevivir, ofreciendo parte de su poder a los ejércitos del Infierno.\n" +"\n" +"Nota de Saya: Sí, creo que recuerdo algo. Todo esto de los \"ángeles\" y tal. Casi que es ya como la segunda vez o así, que la gente se cree que un puñado de extraterrestres de por ahí son \"seres celestiales\" cuando en realidad no son mas que un puñado de capullos. No te voy a pedir que rebusques en libros de historia para eso, así que échale un ojo a la entrada relacionada de \"LANIR\"."; SWWM_LORETXT_MIXOM = "Nombre: Herramientas Mixom\n" "Clasificación: Fabricante de Material Industrial\n" @@ -1045,6 +1074,16 @@ SWWM_LORETXT_SERPENTRIDERS = "Resumen: Una tríada de malévolos hechiceros conocidos por todos estos lugares. Todos aquellos que se han atrevido a luchar contra ellos no han tenido mucha suerte. D'Sparil tomó la tierra de Parthoris, sus muchos ejércitos de no muertos habiendo tomado el control del lugar antes de que hubieramos llegado. Luego, en la tierra de Cronos está Korax, una bestia oscura que se burla de todos aquellos que lo desafían. No hemos recibido mucha información sobre el tercer miembro, pero ya nos vendrá a medida que exploramos estos mundos.\n" "\n" "Nota de Saya: Estoy segura de que puedes cargarte a estos idiotas sin problemas, no tienen ni idea de lo fuerte que eres (o de qué eres, ahora que lo pienso, estos mundos no parecen tener mucho conocimiento de nuestra tecnología)."; +SWWM_LORETAG_SENTINELS = "Centinelas"; +SWWM_LORETXT_SENTINELS = +"Nombre: Centinelas\n" +"Localización: Unknown\n" +"\n" +"Resumen: También conocidos por el nombre de \"Argenta\", son una especie alienígena de formidables guerreros, de quien se dice que han viajado por todo el universo hace incontables años, incluyendo la Tierra. No hay mucha información disponible sobre ellos, aparte de trozos desperdigados de lore.\n" +"\n" +"Apéndice: Posible relación (hostil) con el Infierno, pero no podemos encontrar detalles exactos al respecto, la mayoría de datos han sido perdidos.\n" +"\n" +"Nota de Saya: Sí, no sé que pensar. Me encantaría buscar más sobre esto, ¿crees que a lo mejor le puedo preguntar al tío Slayer ese? Probablemente me ignore, seguro."; SWWM_LORETXT_SIDHE = "Nombre: Sidhe\n" "Localización: Parthoris\n" @@ -1111,6 +1150,15 @@ SWWM_LORETXT_SUNKAEZE = "Resumen: Un planeta completamente árido, que se pensaba vacío, hasta que una expedición descubrió las ruinas de unas instalaciones pertenecientes a la extinta Decade Mechanics, un antiguo grupo industrial fundado por el difunto semidios mecánico Maestre Mekes.\n" "\n" "Nota de Saya: Dioses, semidioses... todo el rollo este... Uno casi que ni se creería que todo esto existe pero venga, después de darnos cuenta que los aliens son muy reales, es difícil no creer en todo esto también. Joder, si CONOZCO uno... no es coña, conozco a un DIOS DE VERDAD. La cosa pasó cuando visitaba a la chica de Yui: pues estaba esta chica con pinta de empollona que tenía como un \"aura\". Se llama Mykka, y es majísima y mola hablar con ella, hasta me dió caramelos y todo. Vamos es que podría seguir hablando de todo esto, pero es que no quiero llenar estas entradas de cosas que no vienen al caso."; +SWWM_LORETAG_SUSAN = "L.A.N.I.R."; +SWWM_LORETXT_SUSAN = +"Nombre: Lanza de Aniquilación, Nulificación, Inexistencia y Ruptura\n" +"Clasificación: Arma de Destrucción Masiva\n" +"Localización: Kereshnovka\n" +"\n" +"Resumen: Una megaestructura controlada po IA que mide docenas de kilómetros, creada por un misterioso grupo Qurensniv llamado \"Facultad de Iluminados Ningunos\". Habiendo tardado cientos de años en construirse, fue activada finalmente en 2018, tomando luego el control de los sistemas de misiles de Rusia. Su presencia en la Tierra, como una amenaza mayor, fue lo que hizo que los Nukuri iniciaran el \"Evento Luna\". Fuerzas Nukuri desplegadas en 2021 neutralizaron la IA, sin embargo probó ser imposible de destruír, así que se mantuvo inactiva, flotando por los mares del Ártico. En 2097, mucho después del incidente de la Cicatriz Blanca, y con los Nukuri ya no disponibles para defender el planeta, una entidad llamada \"Uruk'Anth\" apareción en la Tierra, anunciando ser \"Dios\", y que es su voluntad que esta máquina traiga consigo el fin del mundo, despues de que la humanidad haya demostrado no ser digna de su bendición. SUSAN fue reactivada, esta ve tomando el control de todos los sistemas de armamento de varias superpotencias mundiales. La Tierra vivió dos largos años de terror, con la IA emitiendo una tremendamente lenta cuenta atras hacia la \"Purificación Mundial\", hasta que fue de algún modo desactivada de nuevo y destruída.\n" +"\n" +"Nota de Saya: Como que en serio. \"Soy Dios y digo que debeis morir\", dice. Sí, que se joda el tío ese. Nadie sabe, para nada, como puñetas pasó lo de la segunda vez. Es un misterio como justo... revienta la cosa esa, llevándose con ella al tío ese, también."; SWWM_LORETXT_SYMNATEK = "Nombre: Symnatek\n" "Clasificación: Fabricante de Material Industrial\n" @@ -1146,9 +1194,9 @@ SWWM_LORETXT_UAC2 = "Clasificación: Union Militar, Fundación de Investigación\n" "Localización: Unión de Estados, Marte y Júpiter\n" "\n" -"Resumen: Fundada en 2015 por Thomas Kelliher, como una compañía pariente de la Union Aerospace Armed Forces (UAAF). El ascenso al poder de la UAC comenzó en 2025 con sus famosas Expediciones Conjuntas a Marte. Desde la creación de \"Mars City\" y los muchos puestos en Fobos y Deimos, la UAC efectivamente ha estado trabajando fuera de la ley de la Tierra, lo cual ha causado interminables controversias. Aun más despues de haber conseguido asegurar su posición como el mayor cuerpo militar de la Tierra tras la Tercera Guerra Mundial. Fueron los responsables principales de la invasión del Infierno que causó que media Tierra fuera devastada casi totalmente por fuerzas Demoníacas. Sin embargo, gracias a que hubieran traído al Doom Slayer, la invasión fue fácilmente eliminada. Desde el incidente, no ha habido ningún comunicado más de Samuel Hayden, algunos sospechan que esté muerto.\n" +"Resumen: Fundada en 2015 por Thomas Kelliher, como una compañía pariente de la Union Aerospace Armed Forces (UAAF). El ascenso al poder de la UAC comenzó en 2025 con sus famosas Expediciones Conjuntas a Marte. Desde la creación de \"Mars City\" y los muchos puestos en Fobos y Deimos, la UAC efectivamente ha estado trabajando fuera de la ley de la Tierra, lo cual ha causado interminables controversias. Aun más despues de haber conseguido asegurar su posición como el mayor cuerpo militar de la Tierra tras la Tercera Guerra Mundial. Fueron los responsables principales de la invasión del Infierno que causó que media Tierra fuera devastada casi totalmente por fuerzas Demoníacas. Sin embargo, gracias a que hubieran traído al Doom Slayer, la invasión fue fácilmente eliminada. Desde el incidente, la compañía no ha podido recuperarse, habiendo perdido la mayoría de sus empleados, junto con el antiguo CEO Samuel Hayden.\n" "\n" -"Apéndice: La compañía cayó en el control de los demonios durante la invasión (aunque algunos dicen que esto pudo ser el caso mucho antes del evento), y actualmente sigue recuperándose. Sin embargo no hay muchas esperanzas por una recuperación completa, ya que muchos de sus empleados siguen marchándose.\n" +"Apéndice: La compañía cayó en el control de los demonios durante la invasión (aunque algunos dicen que esto pudo ser el caso mucho antes del evento), hasta el punto de haber tenido a miembros de alto rango en el gobierno militar del Infierno a cargo de algunas divisiones. Tras haber terminado la invasión, ha habido intentos de que todo vuelva al orden, aunque no hay muchas esperanzas de que esto llege a ocurrir.\n" "\n" "Nota de Saya: Si es que me da un gusto de cojones ver caer a este asqueroso gigante. Tía, todo lo de la invasión fue horrible, sabes. Pero me alegro de que al menos hubieramos podido ayudar, aunque no fuera nada comparado con lo que el tal Slayer hizo..."; SWWM_LORETXT_UNISSIX = diff --git a/sndinfo.txt b/sndinfo.txt index 97ad7188f..bec83917e 100644 --- a/sndinfo.txt +++ b/sndinfo.txt @@ -602,6 +602,7 @@ misc/spawn sounds/CORK.ogg misc/teleport sounds/general/teleport.ogg misc/chat sounds/menu/chatsnd.ogg misc/chat2 sounds/menu/chatsnd.ogg +Chat sounds/menu/chatsnd.ogg // hexen what the fuck misc/sundowner sounds/SUNDOWNER.ogg misc/emone sounds/EMONE.ogg diff --git a/zscript.txt b/zscript.txt index 82252eb7b..3eae7d48f 100644 --- a/zscript.txt +++ b/zscript.txt @@ -20,6 +20,7 @@ version "4.3" #include "zscript/swwm_inventory.zsc" #include "zscript/swwm_hud.zsc" #include "zscript/swwm_menu.zsc" +#include "zscript/swwm_options.zsc" #include "zscript/swwm_title.zsc" #include "zscript/swwm_inter.zsc" // items diff --git a/zscript/dlc/swwm_hammertime.zsc b/zscript/dlc/swwm_hammertime.zsc index 28844dbf7..0e8e968e3 100644 --- a/zscript/dlc/swwm_hammertime.zsc +++ b/zscript/dlc/swwm_hammertime.zsc @@ -1,4 +1,4 @@ -// Symnatek Reinforced Combat Hammer (from UnSX 5) +// Itamex Reinforced Combat Hammer (from UnSX 5) // Slot 1, spawns shared with Pusher Class ItamexHammer : SWWMWeapon diff --git a/zscript/swwm_common.zsc b/zscript/swwm_common.zsc index c224bb728..c35a3bd9d 100644 --- a/zscript/swwm_common.zsc +++ b/zscript/swwm_common.zsc @@ -257,6 +257,9 @@ Class SWWMLoreLibrary : Thinker if ( !(gameinfo.gametype&GAME_Raven) ) { if ( ref ~== "Doomslayer" ) return true; // not witnessed + if ( ref ~== "Sentinels" ) return true; // not known + if ( ref ~== "Maykrs" ) return true; // ditto + if ( ref ~== "ARC" ) return true; // didn't exist yet } if ( !(gameinfo.gametype&GAME_Hexen) ) { @@ -272,6 +275,8 @@ Class SWWMLoreLibrary : Thinker { if ( text ~== "SWWM_LORETXT_UAC" ) text = "SWWM_LORETXT_UAC2"; // uac ded + else if ( text ~== "SWWM_LORETXT_HAYDEN" ) + text = "SWWM_LORETXT_HAYDEN2"; // hayden "ded" else if ( text ~== "SWWM_LORETXT_HELL" ) text = "SWWM_LORETXT_HELL2"; // invasion was a thing of the past else if ( text ~== "SWWM_LORETXT_NANA" ) diff --git a/zscript/swwm_menu.zsc b/zscript/swwm_menu.zsc index f7128f309..fd34342ab 100644 --- a/zscript/swwm_menu.zsc +++ b/zscript/swwm_menu.zsc @@ -59,6 +59,9 @@ Class SWWMKnowledgeBaseMenu : GenericMenu int kcode; // crimey clock stuff int c_year, c_month, c_day, c_hour, c_minute; + // mouse stuff + Vector2 curmouse; + bool isrclick; // returns MPlus if we're playing in Japanese, otherwise returns the requested font Font LangFont( Font req ) @@ -243,6 +246,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu MenuSound("misc/secret"); curtab = TAB_SECRET; sel0 = sel1 = sel2 = 0; + ofs0 = ofs1 = ofs2 = 0; sub = false; } default: @@ -332,24 +336,28 @@ Class SWWMKnowledgeBaseMenu : GenericMenu else { MenuSound("menu/demoscroll"); - ofs0 = ++sel0; - if ( sel0 >= lorelist.Size() ) - ofs0 = sel0 = 0; + if ( sel0 >= lorelist.Size()-1 ) ofs0 = sel0 = 0; + else + { + sel0++; + // update ofs so selection stays on-screen + int ofs = max(ofs0-26,0); + if ( sel0 < ofs ) ofs0 = sel0+26; + else if ( sel0 > ofs+26 ) ofs0 = sel0; + } } } - else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 1) ) + else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 1) ) { MenuSound("menu/demoscroll"); ofs0 = ++sel0; - if ( sel0 >= invlist.Size() ) - ofs0 = sel0 = 0; + if ( sel0 >= invlist.Size() ) ofs0 = sel0 = 0; } else if ( (curtab == TAB_STORE) && (storelist.Size() > 1) ) { MenuSound("menu/demoscroll"); ofs0 = ++sel0; - if ( sel0 >= storelist.Size() ) - ofs0 = sel0 = 0; + if ( sel0 >= storelist.Size() ) ofs0 = sel0 = 0; } else if ( curtab == TAB_TRADING ) { @@ -358,44 +366,26 @@ Class SWWMKnowledgeBaseMenu : GenericMenu // scroll through player list MenuSound("menu/demoscroll"); ofs0 = ++sel0; - if ( sel0 >= playerlist.Size() ) - ofs0 = sel0 = 0; + if ( sel0 >= playerlist.Size() ) ofs0 = sel0 = 0; } - else if ( sub ) + else if ( sub && (sel0 == -1) && (sel1 < tradelib.ent.Size()-28) ) { - if ( (sel0 == -1) && (sel1 < tradelib.ent.Size()-28) ) - { - // scroll through trading history - MenuSound("menu/demoscroll"); - ofs1 = ++sel1; - } - else if ( invlist.Size() > 1 ) - { - // scroll through inventory - MenuSound("menu/demoscroll"); - ofs1 = ++sel1; - if ( sel1 >= invlist.Size() ) - ofs1 = sel1 = 0; - } + // scroll through trading history + MenuSound("menu/demoscroll"); + ofs1 = ++sel1; } } return true; case MKEY_UP: - if ( curtab == TAB_HELP ) + if ( (curtab == TAB_HELP) && (sel0 > 0) ) { - if ( sel0 > 0 ) - { - MenuSound("menu/demoscroll"); - ofs0 = --sel0; - } + MenuSound("menu/demoscroll"); + ofs0 = --sel0; } - else if ( curtab == TAB_MISSION ) + else if ( (curtab == TAB_MISSION) && (sel0 > 0) ) { - if ( sel0 > 0 ) - { - MenuSound("menu/demoscroll"); - ofs0 = --sel0; - } + MenuSound("menu/demoscroll"); + ofs0 = --sel0; } else if ( (curtab == TAB_CHAT) && (StatusBar is 'SWWMStatusBar') && (sel0 < SWWMStatusBar(StatusBar).FullHistory.Size()-1) ) { @@ -415,24 +405,28 @@ Class SWWMKnowledgeBaseMenu : GenericMenu else { MenuSound("menu/demoscroll"); - ofs0 = --sel0; - if ( sel0 < 0 ) - ofs0 = sel0 = lorelist.Size()-1; + if ( sel0 <= 0 ) ofs0 = sel0 = lorelist.Size()-1; + else + { + sel0--; + // update ofs so selection stays on-screen + int ofs = max(ofs0-26,0); + if ( sel0 < ofs ) ofs0 = sel0+26; + else if ( sel0 > ofs+26 ) ofs0 = sel0; + } } } - else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 1) ) + else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 1) ) { MenuSound("menu/demoscroll"); ofs0 = --sel0; - if ( sel0 < 0 ) - ofs0 = sel0 = invlist.Size()-1; + if ( sel0 < 0 ) ofs0 = sel0 = invlist.Size()-1; } else if ( (curtab == TAB_STORE) && (storelist.Size() > 1) ) { MenuSound("menu/demoscroll"); ofs0 = --sel0; - if ( sel0 < 0 ) - ofs0 = sel0 = storelist.Size()-1; + if ( sel0 < 0 ) ofs0 = sel0 = storelist.Size()-1; } else if ( curtab == TAB_TRADING ) { @@ -441,30 +435,18 @@ Class SWWMKnowledgeBaseMenu : GenericMenu // scroll through player list MenuSound("menu/demoscroll"); ofs0 = --sel0; - if ( sel0 < 0 ) - ofs0 = sel0 = playerlist.Size()-1; + if ( sel0 < 0 ) ofs0 = sel0 = playerlist.Size()-1; } - else if ( sub ) + else if ( sub && (sel0 == -1) && (sel1 > 0) ) { - if ( (sel0 == -1) && (sel1 > 0) ) - { - // scroll through trading history - MenuSound("menu/demoscroll"); - ofs1 = --sel1; - } - else if ( invlist.Size() > 1 ) - { - // scroll through inventory - MenuSound("menu/demoscroll"); - ofs1 = --sel1; - if ( sel1 < 0 ) - ofs1 = sel1 = invlist.Size()-1; - } + // scroll through trading history + MenuSound("menu/demoscroll"); + ofs1 = --sel1; } } return true; case MKEY_RIGHT: - if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 21) ) + if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 21) ) { int oldsel = sel0; ofs0 = sel0 += 22; @@ -484,43 +466,26 @@ Class SWWMKnowledgeBaseMenu : GenericMenu ofs0 = sel0 = 0; sub = false; ofs1 = ++sel1; - if ( sel1 > LORE_LORE ) - ofs1 = sel1 = LORE_ITEM; + if ( sel1 > LORE_LORE ) ofs1 = sel1 = LORE_ITEM; } - else if ( curtab == TAB_TRADING ) + else if ( (curtab == TAB_TRADING) && !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen { - if ( !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen - { - int oldsel = sel0; - ofs0 = sel0 += 22; - if ( sel0 >= playerlist.Size() ) ofs0 = sel0 = playerlist.Size()-1; - if ( sel0 != oldsel ) MenuSound("menu/demoscroll"); - } - else if ( sub && (sel0 != -1) ) - { - int oldsel = sel1; - ofs1 = sel1 += 22; - if ( sel1 >= invlist.Size() ) ofs1 = sel1 = invlist.Size()-1; - if ( sel1 != oldsel ) MenuSound("menu/demoscroll"); - } + int oldsel = sel0; + ofs0 = sel0 += 22; + if ( sel0 >= playerlist.Size() ) ofs0 = sel0 = playerlist.Size()-1; + if ( sel0 != oldsel ) MenuSound("menu/demoscroll"); } return true; case MKEY_LEFT: - if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS)) && (invlist.Size() > 21) ) + if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 21) && (sel0-22 >= 0) ) { - if ( sel0-22 >= 0 ) - { - MenuSound("menu/demoscroll"); - ofs0 = sel0 -= 22; - } + MenuSound("menu/demoscroll"); + ofs0 = sel0 -= 22; } - else if ( (curtab == TAB_STORE) && (storelist.Size() > 21) ) + else if ( (curtab == TAB_STORE) && (storelist.Size() > 21) && (sel0-22 >= 0) ) { - if ( sel0-22 >= 0 ) - { - MenuSound("menu/demoscroll"); - ofs0 = sel0 -= 22; - } + MenuSound("menu/demoscroll"); + ofs0 = sel0 -= 22; } else if ( curtab == TAB_LIBRARY ) { @@ -528,27 +493,12 @@ Class SWWMKnowledgeBaseMenu : GenericMenu ofs0 = sel0 = 0; sub = false; ofs1 = --sel1; - if ( sel1 < LORE_ITEM ) - ofs1 = sel1 = LORE_LORE; + if ( sel1 < LORE_ITEM ) ofs1 = sel1 = LORE_LORE; } - else if ( curtab == TAB_TRADING ) + else if ( (curtab == TAB_TRADING) && !sub && (playerlist.Size() > 21) && (sel0-22 >= 0) ) // lol is this ever going to happen { - if ( !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen - { - if ( sel0-22 >= 0 ) - { - ofs0 = sel0 -= 22; - MenuSound("menu/demoscroll"); - } - } - else if ( sub && (sel0 != -1) ) - { - if ( sel1-22 >= 0 ) - { - ofs1 = sel1 -= 22; - MenuSound("menu/demoscroll"); - } - } + ofs0 = sel0 -= 22; + MenuSound("menu/demoscroll"); } return true; case MKEY_ENTER: @@ -671,6 +621,11 @@ Class SWWMKnowledgeBaseMenu : GenericMenu return Super.MenuEvent(mkey,fromcontroller); } + private int rnd( double num ) + { + return int(num+((num<0)?-.5:.5)); + } + override bool MouseEvent( int type, int mx, int my ) { bool res = Super.MouseEvent(type,mx,my); @@ -683,9 +638,10 @@ Class SWWMKnowledgeBaseMenu : GenericMenu int xx, yy, len; if ( type == MOUSE_Click ) { - if ( (mpos.x < 0) || (mpos.x >= 641) || (mpos.y < 0) || (mpos.y >= 401) ) return res; // outside window bounds, ignore + if ( (mpos.x < 0) || (mpos.x >= 641) || (mpos.y < 0) || (mpos.y >= 386) ) return res; // outside clickable area, ignore else if ( mpos.y < 14 ) { + if ( isrclick ) return res; // check which tab we're clicking static const string tabnames[] = { @@ -696,8 +652,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu xx = 0; for ( int i=0; i<8; i++ ) { - len = 8+fnt.StringWidth(tabnames[i]); - if ( (mpos.x >= xx) && (mpos.x < xx+len+1) ) + len = fnt.StringWidth(tabnames[i])+6; + if ( (mpos.x >= xx) && (mpos.x < xx+len) ) { if ( curtab == i ) break; MenuSound("menu/demotab"); @@ -716,24 +672,594 @@ Class SWWMKnowledgeBaseMenu : GenericMenu xx += len; } } - else + else if ( (curtab == TAB_MISSION) && !isrclick ) { - // TODO per-tab stuff + // are we clicking where the scrollbar should be? + if ( mpos.x < 632 ) return res; + String str = StringTable.Localize("$SWWM_MISSION_NONE"); + if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM"); + else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC"); + else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN"); + BrokenLines l = fnt.BreakLines(str,629); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,620); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + drag = 1; + } + else if ( (curtab == TAB_INVENTORY) || ((curtab == TAB_TRADING) && sub && (sel0 != -1)) ) + { + // check what item we clicked + if ( mpos.y < 377 ) + { + if ( invlist.Size() <= 0 ) return res; // clicked nothing + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); + else str = invlist[i].GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + xx = 9; + yy = 23; + int cols = 1; + for ( int i=ofs; i= xx) && (mpos.x < xx+longest) && (mpos.y >= yy) && (mpos.y < yy+14) ) + { + if ( sel0 != i ) MenuSound("menu/demoscroll"); + sel0 = i; + ofs0 = (sel0/22)*22; + // drop on right click in inventory tab + if ( (curtab == TAB_INVENTORY) && isrclick ) MenuEvent(MKEY_CLEAR,false); + else if ( !isrclick ) MenuEvent(MKEY_ENTER,false); + return res; + } + yy += 16; + if ( yy >= 370 ) + { + xx += longest+24; + yy = 23; + cols++; + if ( cols > maxcol ) break; + } + } + } + else if ( !isrclick ) + { + // check that scrollbar is present + if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); + else str = invlist[i].GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + drag = 1; + } + } + else if ( (curtab == TAB_KEYS) && !isrclick ) + { + // check what item we clicked + if ( mpos.y < 377 ) + { + if ( invlist.Size() <= 0 ) return res; // clicked nothing + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + xx = 9; + yy = 23; + int cols = 1; + for ( int i=ofs; i= xx) && (mpos.x < xx+longest) && (mpos.y >= yy) && (mpos.y < yy+14) ) + { + if ( sel0 != i ) MenuSound("menu/demoscroll"); + sel0 = i; + ofs0 = (sel0/22)*22; + // do nothing, we just selected it + return res; + } + yy += 16; + if ( yy >= 370 ) + { + xx += longest+24; + yy = 23; + cols++; + if ( cols > maxcol ) break; + } + } + } + else if ( !isrclick ) + { + // check that scrollbar is present + if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + drag = 1; + } + } + else if ( (curtab == TAB_STORE) && !isrclick ) + { + // check what item we clicked + if ( mpos.y < 377 ) + { + if ( storelist.Size() <= 0 ) return res; // clicked nothing + xx = 9; + yy = 23; + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag()); + else str = def.GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+96); + totalcol = (storelist.Size()/22)+1; + // gotta check both the tag and the price for clicking + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + int cols = 1; + for ( int i=ofs; i= xx) && (mpos.x < xx+longest+80) && (mpos.y >= yy) && (mpos.y < yy+14) ) + { + if ( sel0 != i ) MenuSound("menu/demoscroll"); + sel0 = i; + ofs0 = (sel0/22)*22; + MenuEvent(MKEY_ENTER,false); + return res; + } + yy += 16; + if ( yy >= 370 ) + { + xx += longest+96; + yy = 23; + cols++; + if ( cols > maxcol ) break; + } + } + } + else if ( !isrclick ) + { + // check that scrollbar is present + if ( storelist.Size() <= 0 ) return res; // definitely no scrollbar + xx = 9; + yy = 23; + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag()); + else str = def.GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+96); + totalcol = (storelist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + drag = 1; + } + } + else if ( (curtab == TAB_LIBRARY) && !isrclick ) + { + double midp = (lang.GetString()~=="jp")?206:126; + if ( mpos.x < midp ) + { + if ( mpos.y < 28 ) + { + // switch category + if ( mpos.x < midp/2. ) MenuEvent(MKEY_LEFT,false); + else MenuEvent(MKEY_RIGHT,false); + } + else + { + // check what item we clicked + int xx = 3; + int yy = 32; + int ofs = max(0,ofs0-26); + for ( int i=ofs; i 370 ) break; + // check boundary + if ( (mpos.y >= yy) && (mpos.y < yy+14) ) + { + if ( sel0 != i ) MenuSound("menu/demoscroll"); + if ( (sel0 != i) || !sub ) + { + sel0 = i; + sub = false; + MenuEvent(MKEY_Enter,false); + } + return res; + } + yy += 13; + } + } + } + else if ( mpos.x < midp+8 ) + { + // check that scrollbar is present + if ( lorelist.Size() <= 27 ) return res; // no scrollbar + // calculate offset + int szr = lorelist.Size()-27; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step ) step += 26; + if ( step != ofs0 ) MenuSound("menu/demoscroll"); + ofs0 = step; + drag = 1; + } + else if ( sub && (mpos.x >= 632) ) + { + // check that scrollbar is present + str = StringTable.Localize(lorelist[sel0].text); + BrokenLines l = fnt.BreakLines(str,int(635-xx)); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,int(626-xx)); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel2 ) MenuSound("menu/demoscroll"); + ofs2 = sel2 = step; + drag = 3; + } + } + else if ( (curtab == TAB_TRADING) && !isrclick ) + { + if ( !sub ) + { + // check what item we clicked + if ( mpos.y < 377 ) + { + if ( playerlist.Size() <= 0 ) return res; // clicked nothing + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + xx = 9; + yy = 23; + int cols = 1; + for ( int i=ofs; i= xx) && (mpos.x < xx+len+1) && (mpos.y >= yy) && (mpos.y < yy+14) ) + { + if ( sel0 != i ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = i; + MenuEvent(MKEY_Enter,false); + return res; + } + yy += 16; + if ( yy >= 370 ) + { + xx += longest+24; + yy = 23; + cols++; + if ( cols > maxcol ) break; + } + } + } + else if ( !isrclick ) + { + // check that scrollbar is present (will it ever be???) + if ( playerlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + drag = 1; + } + } + else if ( sel0 == -1 ) + { + // are we clicking where the scrollbar should be? + if ( mpos.x < 632 ) return res; + if ( tradelib.ent.Size() <= 28 ) return res; // no scrollbar + // calculate offset + int szr = tradelib.ent.Size()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + drag = 1; + } + } + else if ( (curtab == TAB_CHAT) && !isrclick ) + { + // are we clicking where the scrollbar should be? + if ( mpos.x < 632 ) return res; + let bar = SWWMStatusBar(StatusBar); + if ( !bar || (bar.FullHistory.Size() <= 1) ) return res; // no scrollbar + // calculate offset + int szr = bar.FullHistory.Size()-1; + int step = szr-clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + drag = 1; + } + else if ( (curtab == TAB_HELP) && !isrclick ) + { + // are we clicking where the scrollbar should be? + if ( mpos.x < 632 ) return res; + int k1, k2; + [k1, k2] = bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu"); + String kstr = bindings.NameKeys(k1,k2); + str = String.Format(StringTable.Localize("$SWWM_HELPTXT"),kstr); + BrokenLines l = fnt.BreakLines(str,629); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,620); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + drag = 1; } } - else if ( type == MOUSE_Release ) drag = 0; // stop dragging any active scrollbars - else if ( type == MOUSE_Move ) + else if ( (type == MOUSE_Move) && drag ) // scroll dragging { - if ( drag ) + if ( curtab == TAB_MISSION ) { - // TODO scrollbar dragging + String str = StringTable.Localize("$SWWM_MISSION_NONE"); + if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM"); + else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC"); + else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN"); + BrokenLines l = fnt.BreakLines(str,629); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,620); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; } - else if ( (mpos.x < 0) || (mpos.x >= 641) || (mpos.y < 0) || (mpos.y >= 401) ) return res; // outside window bounds, ignore - else + else if ( (curtab == TAB_INVENTORY) || ((curtab == TAB_TRADING) && sub && (sel0 != -1)) ) { - // TODO select on hover + // check that scrollbar is present + if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); + else str = invlist[i].GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + } + else if ( curtab == TAB_KEYS ) + { + // check that scrollbar is present + if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + } + else if ( curtab == TAB_STORE ) + { + // check that scrollbar is present + if ( storelist.Size() <= 0 ) return res; // definitely no scrollbar + xx = 9; + yy = 23; + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag()); + else str = def.GetTag(); + len = fnt.StringWidth(str); + if ( len > longest ) longest = len; + } + maxcol = 622/(longest+96); + totalcol = (storelist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + } + else if ( curtab == TAB_LIBRARY ) + { + if ( drag == 1 ) + { + // check that scrollbar is present + if ( lorelist.Size() <= 27 ) return res; // no scrollbar + // calculate offset + int szr = lorelist.Size()-27; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step ) step += 26; + if ( step != ofs0 ) MenuSound("menu/demoscroll"); + ofs0 = step; + } + else if ( drag == 3 ) + { + // check that scrollbar is present + str = StringTable.Localize(lorelist[sel0].text); + BrokenLines l = fnt.BreakLines(str,int(635-xx)); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,int(626-xx)); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel2 ) MenuSound("menu/demoscroll"); + ofs2 = sel2 = step; + } + } + else if ( curtab == TAB_TRADING ) + { + if ( !sub ) + { + // check that scrollbar is present (will it ever be???) + if ( playerlist.Size() <= 0 ) return res; // definitely no scrollbar + int longest = 0, len; + int maxcol, totalcol; + for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + if ( maxcol >= totalcol ) return res; // no scrollbar + // calculate offset + int szr = totalcol-maxcol; + int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr); + if ( step > 0 ) step += (maxcol-1); + if ( step != (ofs0/22) ) MenuSound("menu/demoscroll"); + ofs0 = step*22; + } + else if ( sel0 == -1 ) + { + if ( tradelib.ent.Size() <= 28 ) return res; // no scrollbar + // calculate offset + int szr = tradelib.ent.Size()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + } + } + else if ( curtab == TAB_CHAT ) + { + let bar = SWWMStatusBar(StatusBar); + if ( !bar || (bar.FullHistory.Size() <= 1) ) return res; // no scrollbar + // calculate offset + int szr = bar.FullHistory.Size()-1; + int step = szr-clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; + } + else if ( curtab == TAB_HELP ) + { + int k1, k2; + [k1, k2] = bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu"); + String kstr = bindings.NameKeys(k1,k2); + str = String.Format(StringTable.Localize("$SWWM_HELPTXT"),kstr); + BrokenLines l = fnt.BreakLines(str,629); + if ( l.Count() > 28 ) l = fnt.BreakLines(str,620); + else return res; // no scrollbar + // calculate offset + int szr = l.Count()-28; + int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr); + if ( step != sel0 ) MenuSound("menu/demoscroll"); + ofs0 = sel0 = step; } } + else if ( type == MOUSE_Release ) drag = 0; // stop dragging any active scrolls return res; } @@ -952,6 +1478,10 @@ Class SWWMKnowledgeBaseMenu : GenericMenu int idx = lorelist.Find(oldone); if ( (idx > 0) && (idx < lorelist.Size()) ) sel0 = idx; + // update ofs so selection stays on-screen + int ofs = max(ofs0-26,0); + if ( sel0 < ofs ) ofs0 = sel0+26; + else if ( sel0 > ofs+26 ) ofs0 = sel0; } // add "new entries" message if ( lorelib.ent.Size() != oldloresiz ) @@ -1109,11 +1639,69 @@ Class SWWMKnowledgeBaseMenu : GenericMenu } break; case UIEvent.Type_WheelDown: + if ( (curtab == TAB_LIBRARY) && sub && (lorelist.Size() > 1) ) + { + // special handling, need to check which side is being scrolled + double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.); + Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs; + Vector2 origin = (ss.x-640,ss.y-400)/2.; + Vector2 mpos = (curmouse/hs)-origin; + double midp = (lang.GetString()~=="jp")?206:126; + if ( ((lorelist.Size() > 27) && (mpos.x < midp+8)) || (mpos.x < midp) ) + { + MenuSound("menu/democlose"); + sub = false; + } + } return MenuEvent(MKEY_DOWN,false); break; case UIEvent.Type_WheelUp: + if ( (curtab == TAB_LIBRARY) && sub && (lorelist.Size() > 1) ) + { + // special handling, need to check which side is being scrolled + double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.); + Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs; + Vector2 origin = (ss.x-640,ss.y-400)/2.; + Vector2 mpos = (curmouse/hs)-origin; + double midp = (lang.GetString()~=="jp")?206:126; + if ( ((lorelist.Size() > 27) && (mpos.x < midp+8)) || (mpos.x < midp) ) + { + MenuSound("menu/democlose"); + sub = false; + } + } return MenuEvent(MKEY_UP,false); break; + case UIEvent.Type_LButtonDown: + isrclick = false; + return Super.OnUIEvent(ev); + break; + case UIEvent.Type_RButtonDown: + isrclick = true; + // copy over what base menus do for L click + int y = ev.MouseY; + bool res = MouseEventBack(MOUSE_Click,ev.MouseX,y); + if ( res ) y = -1; + res |= MouseEvent(MOUSE_Click,ev.MouseX,y); + if ( res ) SetCapture(true); + return false; + break; + case UIEvent.Type_RButtonUp: + // copy over what base menus do for L release + if ( mMouseCapture ) + { + SetCapture(false); + int y = ev.MouseY; + bool res = MouseEventBack(MOUSE_Release,ev.MouseX,y); + if ( res ) y = -1; + res |= MouseEvent(MOUSE_Release,ev.MouseX,y); + } + return false; + break; + case UIEvent.Type_MouseMove: + // store coords + curmouse = (ev.MouseX,ev.MouseY); + break; } return Super.OnUIEvent(ev); } @@ -1267,7 +1855,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); yy += 16; } - else if ( curtab == TAB_INVENTORY ) + else if ( (curtab == TAB_INVENTORY) || ((curtab == TAB_TRADING) && sub && (sel0 != -1)) ) { if ( invlist.Size() <= 0 ) { @@ -1277,16 +1865,25 @@ Class SWWMKnowledgeBaseMenu : GenericMenu } xx = 9; yy = 23; - int longest = 0, len; - int ofs = int(floor(max(0,sel0-44)/22.)*22); - int cols = 1; - for ( int i=ofs; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); else str = invlist[i].GetTag(); len = fnt.StringWidth(str); if ( len > longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + for ( int i=ofs; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); + else str = invlist[i].GetTag(); int clscol = Font.CR_WHITE; if ( invlist[i] is 'Weapon' ) clscol = Font.CR_GOLD; else if ( (invlist[i] is 'Ammo') || (invlist[i] is 'BackpackItem') || (invlist[i] is 'HammerspaceEmbiggener') ) clscol = Font.CR_BROWN; @@ -1300,16 +1897,15 @@ Class SWWMKnowledgeBaseMenu : GenericMenu { xx += longest+24; yy = 23; - longest = 0; cols++; - if ( cols > 3 ) break; + if ( cols > maxcol ) break; } } - if ( invlist.Size() > 65 ) + if ( maxcol < totalcol ) { // draw scrollbar - int szr = (invlist.Size()/22)-2; - xx = floor((ofs/22)*(630./szr))+2; + int szr = totalcol-maxcol; + xx = floor((ofs/22.)*(630./szr))+2.; Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } @@ -1325,30 +1921,36 @@ Class SWWMKnowledgeBaseMenu : GenericMenu xx = 9; yy = 23; int longest = 0, len; - int ofs = int(floor(max(0,sel0-44)/22.)*22); - int cols = 1; + int maxcol, totalcol, cols = 1; for ( int i=0; i longest ) longest = len; + } + maxcol = 622/(longest+24); + totalcol = (invlist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + for ( int i=0; i= 370 ) { xx += longest+24; yy = 23; - longest = 0; cols++; - if ( cols > 3 ) break; + if ( cols > maxcol ) break; } } - if ( invlist.Size() > 65 ) + if ( maxcol < totalcol ) { // draw scrollbar - int szr = (invlist.Size()/22)-2; - xx = floor((ofs/22)*(630./szr))+2; + int szr = totalcol-maxcol; + xx = floor((ofs/22.)*(630./szr))+2.; Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } @@ -1378,7 +1980,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu Screen.DrawTexture((lang.GetString()~=="jp")?LoreSeparatorW:LoreSeparator,false,origin.x,origin.y+27,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); yy += 18; // draw the current entries - int ofs = max(0,sel0-26); + int ofs = max(0,ofs0-26); for ( int i=ofs; i 370 ) break; @@ -1393,7 +1995,7 @@ Class SWWMKnowledgeBaseMenu : GenericMenu Screen.DrawTexture(WindowSeparator,false,origin.x+xx,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); xx += 3; // scrollbar - if ( lorelist.Size() > 26 ) + if ( lorelist.Size() > 27 ) { int szr = lorelist.Size()-27; yy = floor((ofs)*(353./szr))+17; @@ -1443,10 +2045,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu xx = 9; yy = 23; int longest = 0, len; - int ofs = int(floor(max(0,sel0-22)/22.)*22); - int cols = 1; - int collen[2]; - for ( int i=ofs; i longest ) longest = len; - collen[cols-1] = longest; + } + maxcol = 622/(longest+96); + totalcol = (storelist.Size()/22)+1; + int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22); + int cols = 1; + for ( int i=ofs; i 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag()); + else str = def.GetTag(); int clscol = Font.CR_WHITE; if ( storelist[i] is 'Weapon' ) clscol = Font.CR_GOLD; else if ( storelist[i] is 'Ammo' ) clscol = Font.CR_BROWN; @@ -1467,9 +2077,8 @@ Class SWWMKnowledgeBaseMenu : GenericMenu { xx += longest+96; yy = 23; - longest = 0; cols++; - if ( cols > 2 ) break; + if ( cols > maxcol ) break; } } xx = 9; @@ -1484,21 +2093,21 @@ Class SWWMKnowledgeBaseMenu : GenericMenu len = TewiFont.StringWidth(str); int clscol = Font.CR_FIRE; if ( price > muns ) clscol = Font.CR_BLACK; - Screen.DrawText(TewiFont,clscol,origin.x+xx+collen[cols-1]+80-len,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0)); + Screen.DrawText(TewiFont,clscol,origin.x+xx+longest+80-len,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0)); yy += 16; if ( yy >= 370 ) { - xx += collen[cols-1]+96; + xx += longest+96; yy = 23; cols++; - if ( cols > 2 ) break; + if ( cols > maxcol ) break; } } - if ( storelist.Size() > 43 ) + if ( maxcol < totalcol ) { // draw scrollbar - int szr = (storelist.Size()/22)-1; - xx = floor((ofs/22)*(630./szr))+2; + int szr = totalcol-maxcol; + xx = floor((ofs/22.)*(630./szr))+2.; Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } @@ -1578,47 +2187,6 @@ Class SWWMKnowledgeBaseMenu : GenericMenu Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } } - else - { - xx = 9; - yy = 23; - int longest = 0, len; - int ofs = int(floor(max(0,sel1-44)/22.)*22); - int cols = 1; - for ( int i=ofs; i 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag()); - else str = invlist[i].GetTag(); - len = fnt.StringWidth(str); - if ( len > longest ) longest = len; - int clscol = Font.CR_WHITE; - if ( invlist[i] is 'Weapon' ) clscol = Font.CR_GOLD; - else if ( (invlist[i] is 'Ammo') || (invlist[i] is 'BackpackItem') || (invlist[i] is 'HammerspaceEmbiggener') ) clscol = Font.CR_BROWN; - else if ( (invlist[i] is 'PowerupGiver') || (invlist[i] is 'AmmoFabricator') || invlist[i].bBIGPOWERUP ) clscol = Font.CR_PURPLE; - else if ( (invlist[i] is 'Health') || (invlist[i] is 'HealthPickup') || (invlist[i] is 'SWWMHealth') ) clscol = Font.CR_RED; - else if ( (invlist[i] is 'Armor') || (invlist[i] is 'SWWMSpareArmor') ) clscol = Font.CR_GREEN; - else if ( invlist[i] is 'PuzzleItem' ) clscol = Font.CR_LIGHTBLUE; - Screen.DrawText(fnt,clscol,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel1)?Color(96,0,0,0):Color(0,0,0,0)); - yy += 16; - if ( yy >= 370 ) - { - xx += longest+24; - yy = 23; - longest = 0; - cols++; - if ( cols > 3 ) break; - } - } - if ( invlist.Size() > 65 ) - { - // draw scrollbar - int szr = (invlist.Size()/22)-2; - xx = floor((ofs/22)*(630./szr))+2; - Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); - Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); - } - } } } else if ( curtab == TAB_CHAT ) @@ -1695,185 +2263,3 @@ Class SWWMKnowledgeBaseMenu : GenericMenu } } } - -// voice selector -Class OptionMenuItemSWWMVoiceOption : OptionMenuItemOptionBase -{ - CVar mCVar; - Array types; - - OptionMenuItemSWWMVoiceOption Init( String label, Name command, CVar graycheck = null, int center = 0 ) - { - Super.Init(label,command,'',graycheck,center); - mCVar = CVar.FindCVar(mAction); - int lmp; - for ( lmp = Wads.FindLump("swwmvoicepack.txt"); lmp > 0; lmp = Wads.FindLump("swwmvoicepack.txt",lmp+1) ) - { - Array lst; - lst.Clear(); - String dat = Wads.ReadLump(lmp); - dat.Split(lst,"\n",0); - for ( int i=0; i= 0 ) - { - mValues = newtext; - int s = GetSelection(); - if ( (s >= cnt) || (s < 0) ) s = 0; - SetSelection(s); - return true; - } - } - return false; - } - - override int GetSelection() - { - int Selection = -1; - int cnt = types.Size(); - if ( (cnt > 0) && mCVar ) - { - String cv = mCVar.GetString(); - for( int i=0; i 0) && mCVar ) - mCVar.SetString(types[Selection]); - } - - override int Draw( OptionMenuDescriptor desc, int y, int indent, bool selected ) - { - if ( mCenter ) indent = (screen.GetWidth()/2); - drawLabel(indent,y,selected?OptionMenuSettings.mFontColorSelection:OptionMenuSettings.mFontColor,isGrayed()); - int Selection = GetSelection(); - String loc; - if ( Selection == -1 ) loc = "Unknown"; - else - { - String uptxt = types[Selection]; - uptxt.MakeUpper(); - String str = String.Format("SWWM_VOICENAME_%s",uptxt); - loc = StringTable.Localize(str,false); - if ( str == loc ) loc = types[Selection]; - } - drawValue(indent,y,OptionMenuSettings.mFontColorValue,loc,isGrayed()); - return indent; - } - - override bool MenuEvent( int mkey, bool fromcontroller ) - { - int cnt = types.Size(); - if ( cnt > 0 ) - { - int Selection = GetSelection(); - if ( mkey == Menu.MKEY_Left ) - { - if ( Selection == -1 ) Selection = 0; - else if ( --Selection < 0 ) Selection = cnt-1; - } - else if ( (mkey == Menu.MKEY_Right) || (mkey == Menu.MKEY_Enter) ) - { - if ( ++Selection >= cnt ) Selection = 0; - } - else return OptionMenuItem.MenuEvent(mkey,fromcontroller); - SetSelection(Selection); - Menu.MenuSound("menu/change"); - } - else return OptionMenuItem.MenuEvent(mkey,fromcontroller); - return true; - } -} - -// option menu /w tooltips -Class SWWMOptionMenu : OptionMenu -{ - private String ttip; - transient CVar lang; - transient Font TewiFont, MPlusFont; - - override void Ticker() - { - Super.Ticker(); - // fetch the tooltip for whatever's selected (if any) - if ( mDesc.mSelectedItem == -1 ) return; - String mcvar = mDesc.mItems[mDesc.mSelectedItem].GetAction(); - mcvar.Replace(" ","_"); // need to strip whitespace for command actions - String locstr = String.Format("TOOLTIP_%s",mcvar); - ttip = StringTable.Localize(locstr,false); - if ( ttip == locstr ) ttip = ""; - } - override void Drawer() - { - Super.Drawer(); - if ( ttip == "" ) return; - // re-evaluate y to check where the cursor is - int cy = 0; - int y = mDesc.mPosition; - if ( y <= 0 ) - { - let font = generic_ui||!mDesc.mFont?NewSmallFont:mDesc.mFont; - if ( font && (mDesc.mTitle.Length() > 0) ) - y = -y+font.GetHeight(); - else y = -y; - } - int fontheight = OptionMenuSettings.mLinespacing*CleanYfac_1; - y *= CleanYfac_1; - int lastrow = Screen.GetHeight()-OptionHeight()*CleanYfac_1; - for ( int i=0; ((i < mDesc.mItems.Size()) && (y <= lastrow)); i++ ) - { - // Don't scroll the uppermost items - if ( i == mDesc.mScrollTop ) - { - i += mDesc.mScrollPos; - if ( i >= mDesc.mItems.Size() ) break; // skipped beyond end of menu - } - y += fontheight; - if ( mDesc.mSelectedItem == i ) - { - cy = y; - break; - } - } - if ( !TewiFont ) TewiFont = Font.GetFont('Tewi'); - if ( !MPlusFont ) MPlusFont = Font.GetFont('MPlus'); - if ( !lang ) lang = CVar.GetCVar('language',players[consoleplayer]); - Font fnt = TewiFont; - if ( lang.GetString() ~== "jp" ) fnt = MPlusFont; - let lines = fnt.BreakLines(ttip,CleanWidth_1-8); - int height = (8+fnt.GetHeight()*lines.Count())*CleanYFac_1; - // draw at the bottom unless the selected option could is covered by the tooltip - int ypos = Screen.GetHeight()-height; - if ( cy >= ypos ) ypos = 0; - Screen.Dim("Black",.75,0,ypos,Screen.GetWidth(),height); - ypos += 4*CleanYFac_1; - for ( int i=0; i types; + + OptionMenuItemSWWMVoiceOption Init( String label, Name command, CVar graycheck = null, int center = 0 ) + { + Super.Init(label,command,'',graycheck,center); + mCVar = CVar.FindCVar(mAction); + int lmp; + for ( lmp = Wads.FindLump("swwmvoicepack.txt"); lmp > 0; lmp = Wads.FindLump("swwmvoicepack.txt",lmp+1) ) + { + Array lst; + lst.Clear(); + String dat = Wads.ReadLump(lmp); + dat.Split(lst,"\n",0); + for ( int i=0; i= 0 ) + { + mValues = newtext; + int s = GetSelection(); + if ( (s >= cnt) || (s < 0) ) s = 0; + SetSelection(s); + return true; + } + } + return false; + } + + override int GetSelection() + { + int Selection = -1; + int cnt = types.Size(); + if ( (cnt > 0) && mCVar ) + { + String cv = mCVar.GetString(); + for( int i=0; i 0) && mCVar ) + mCVar.SetString(types[Selection]); + } + + override int Draw( OptionMenuDescriptor desc, int y, int indent, bool selected ) + { + if ( mCenter ) indent = (screen.GetWidth()/2); + drawLabel(indent,y,selected?OptionMenuSettings.mFontColorSelection:OptionMenuSettings.mFontColor,isGrayed()); + int Selection = GetSelection(); + String loc; + if ( Selection == -1 ) loc = "Unknown"; + else + { + String uptxt = types[Selection]; + uptxt.MakeUpper(); + String str = String.Format("SWWM_VOICENAME_%s",uptxt); + loc = StringTable.Localize(str,false); + if ( str == loc ) loc = types[Selection]; + } + drawValue(indent,y,OptionMenuSettings.mFontColorValue,loc,isGrayed()); + return indent; + } + + override bool MenuEvent( int mkey, bool fromcontroller ) + { + int cnt = types.Size(); + if ( cnt > 0 ) + { + int Selection = GetSelection(); + if ( mkey == Menu.MKEY_Left ) + { + if ( Selection == -1 ) Selection = 0; + else if ( --Selection < 0 ) Selection = cnt-1; + } + else if ( (mkey == Menu.MKEY_Right) || (mkey == Menu.MKEY_Enter) ) + { + if ( ++Selection >= cnt ) Selection = 0; + } + else return OptionMenuItem.MenuEvent(mkey,fromcontroller); + SetSelection(Selection); + Menu.MenuSound("menu/change"); + } + else return OptionMenuItem.MenuEvent(mkey,fromcontroller); + return true; + } +} + +// option menu /w tooltips +Class SWWMOptionMenu : OptionMenu +{ + private String ttip; + transient CVar lang; + transient Font TewiFont, MPlusFont; + + override void Ticker() + { + Super.Ticker(); + // fetch the tooltip for whatever's selected (if any) + if ( mDesc.mSelectedItem == -1 ) return; + String mcvar = mDesc.mItems[mDesc.mSelectedItem].GetAction(); + mcvar.Replace(" ","_"); // need to strip whitespace for command actions + String locstr = String.Format("TOOLTIP_%s",mcvar); + ttip = StringTable.Localize(locstr,false); + if ( ttip == locstr ) ttip = ""; + } + override void Drawer() + { + Super.Drawer(); + if ( ttip == "" ) return; + // re-evaluate y to check where the cursor is + int cy = 0; + int y = mDesc.mPosition; + if ( y <= 0 ) + { + let font = generic_ui||!mDesc.mFont?NewSmallFont:mDesc.mFont; + if ( font && (mDesc.mTitle.Length() > 0) ) + y = -y+font.GetHeight(); + else y = -y; + } + int fontheight = OptionMenuSettings.mLinespacing*CleanYfac_1; + y *= CleanYfac_1; + int lastrow = Screen.GetHeight()-OptionHeight()*CleanYfac_1; + for ( int i=0; ((i < mDesc.mItems.Size()) && (y <= lastrow)); i++ ) + { + // Don't scroll the uppermost items + if ( i == mDesc.mScrollTop ) + { + i += mDesc.mScrollPos; + if ( i >= mDesc.mItems.Size() ) break; // skipped beyond end of menu + } + y += fontheight; + if ( mDesc.mSelectedItem == i ) + { + cy = y; + break; + } + } + if ( !TewiFont ) TewiFont = Font.GetFont('Tewi'); + if ( !MPlusFont ) MPlusFont = Font.GetFont('MPlus'); + if ( !lang ) lang = CVar.GetCVar('language',players[consoleplayer]); + Font fnt = TewiFont; + if ( lang.GetString() ~== "jp" ) fnt = MPlusFont; + let lines = fnt.BreakLines(ttip,CleanWidth_1-8); + int height = (8+fnt.GetHeight()*lines.Count())*CleanYFac_1; + // draw at the bottom unless the selected option could is covered by the tooltip + int ypos = Screen.GetHeight()-height; + if ( cy >= ypos ) ypos = 0; + Screen.Dim("Black",.75,0,ypos,Screen.GetWidth(),height); + ypos += 4*CleanYFac_1; + for ( int i=0; i 0) && passive ) { + if ( (damagetype == 'Drowning') || (damagetype == 'Falling') || (damagetype == 'Poison') || (damagetype == 'PoisonCloud') ) + return; // these go through armor and get ignored by the player if ( damageType == 'Ynykron' ) { newdamage = damage;