From e5f9b0163c765010dc4a890612c54e0076883a53 Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Wed, 1 Jul 2020 14:48:38 +0200
Subject: [PATCH] Add new murder attempt event

---
 src/events/scheduled/murderAttempt.js | 349 ++++++++++++++++++++++++++
 src/events/scheduled/murderAttempt.tw |   5 +
 2 files changed, 354 insertions(+)
 create mode 100644 src/events/scheduled/murderAttempt.js
 create mode 100644 src/events/scheduled/murderAttempt.tw

diff --git a/src/events/scheduled/murderAttempt.js b/src/events/scheduled/murderAttempt.js
new file mode 100644
index 00000000000..c33bcc75acf
--- /dev/null
+++ b/src/events/scheduled/murderAttempt.js
@@ -0,0 +1,349 @@
+App.Events.murderAttempt = function() {
+	const nextPassage = "Main"; // TODO
+	const perceptiveCareers = ["mercenary", "gang"];
+	// event unique
+	const variation = jsEither(["trade", "slave", "drug", "military"]);
+	const companyName = "RealTec"; // TODO generate name
+	const isSincere = Math.random() > 0.6;
+	// TODO get business man pronouns dynamically
+	let he, man, himself, him, his;
+	if (V.arcologies[0].FSGenderRadicalist === "unset") {
+		he = "he";
+		his = "his";
+		him = "him";
+		man = "man";
+		himself = "himself";
+	} else {
+		he = "she";
+		his = "her";
+		him = "her";
+		man = "woman";
+		himself = "herself";
+	}
+
+	const documentFragment = document.createDocumentFragment();
+	intro(documentFragment);
+	return documentFragment;
+
+	function intro(fragment) {
+		const r = [];
+		r.push("As every day you are going through the messages your personal assistant flagged as relevant from the mass you get every day.");
+		r.push("One is a request by a company called \"" + companyName + "\" for a personal meeting to propose some kind of");
+		switch (variation) {
+			case "trade":
+				r.push("business venture.");
+				break;
+			case "slave":
+				r.push("unique slave trade.");
+				break;
+			case "drug":
+				r.push("deal for a new drug.");
+				break;
+			case "military":
+				r.push("military endeavour.");
+				break;
+		}
+		r.push("Despite being incredibly vague about the details of said business venture they have references from multiple reputable businesses in the");
+		switch (variation) {
+			case "trade":
+				r.push("trading");
+				break;
+			case "slave":
+				r.push("arcology");
+				break;
+			case "drug":
+				r.push("medicine");
+				break;
+			case "military":
+				r.push("military");
+				break;
+		}
+		r.push("and slavery sectors, many of which are known for dealing in not so legal business regularly, making the vague details seem more like making sure not to leave any possible proofs of illegal ventures behind.");
+		App.Events.addParagraph(fragment, r);
+
+		let yesText, noText;
+		switch (variation) {
+			case "trade":
+				yesText = "New business is";
+				noText = "profitable business venture";
+				break;
+			case "slave":
+				yesText = "Unique slaves are";
+				noText = "special slave";
+				break;
+			case "drug":
+				yesText = "Special drugs you cannot buy are";
+				noText = "new drug";
+				break;
+			case "military":
+				yesText = "A profitable use for your mercenary troops are";
+				noText = "profitable military venture";
+				break;
+		}
+		App.Events.addResponses(fragment, [
+			new App.Events.Result(`${yesText} always good, invite them to a private meeting.`, invite),
+			new App.Events.Result(`You are not going to waste your time on something as vague as a "${noText}".`, endEvent)
+		], "invite");
+	}
+
+	function invite() {
+		const fragment = document.createDocumentFragment();
+
+		let r = [];
+		r.push("Your assistant makes a meeting a few days later in your personal office, despite those meetings usually being conducted in a more neutral, albeit as secure location, but",
+			companyName, "insisted on meeting in your office.");
+		if (["capitalist", "mercenary", "slaver", "engineer"].includes(V.PC.career)) {
+			r.push("This seems shady.");
+		} else {
+			r.push("Less time wasted in case nothing comes out of it.");
+		}
+		App.Events.addParagraph(fragment, r);
+
+		r = [];
+		r.push("At the time of the meeting a", man,
+			"arrives at your penthouse and is brought to your office by one of your slaves, while you watch him on your PC screen. The",
+			man, "is distinctively average looking, as if you took all business man that did their job well, but did not overachieve, and created the perfect average of it. Someone looking this average is certainly everything but average.");
+		App.Events.addParagraph(fragment, r);
+
+		r = [];
+		r.push("Once", he, "arrives at your office you settle down after a short greeting and", he, "starts");
+		switch (variation) {
+			case "trade":
+			case "military":
+				r.push("showing you the plans they have.");
+				break;
+			case "slave":
+				r.push("explaining the uniqueness of their slaves.");
+				break;
+			case "drug":
+				r.push("showing you the effects of their new drug.");
+		}
+
+		if (S.Bodyguard) {
+			r.push("Before getting anywhere though", he, "interrupts", himself,
+				"looking at your bodyguard. \"I'm sorry, this is meant only for your ears, can you please send your bodyguard outside?\"");
+			App.Events.addParagraph(fragment, r);
+
+			App.Events.addResponses(fragment, [
+				new App.Events.Result("\"No one gives me commands in my own office. You can leave now.\"", endEvent),
+				new App.Events.Result(`"${S.Bodyguard.slaveName} IS my ears, she stays."`, bgStaysRoute),
+				new App.Events.Result(`"This better be worth it." Order ${S.Bodyguard.slaveName} to leave.`, bgLeavesRoute)
+			], "bodyguard");
+		} else {
+			noSlaveRoute(fragment, r, false);
+		}
+
+		return fragment;
+	}
+
+	/**
+	 * @param {DocumentFragment} fragment
+	 * @param {Array<string>} paragraphStart
+	 * @param {boolean} slaveLeft only relevant for murder attempt
+	 */
+	function noSlaveRoute(fragment, paragraphStart, slaveLeft) {
+		if (isSincere) {
+			sincereProposal(fragment, paragraphStart);
+		} else {
+			paragraphStart.push("For the next few hours", he,
+				"talks in circles, doing grand gestures here and there but without actually saying anything of substance to the point where you start getting bored until");
+			if (perceptiveCareers.includes(V.PC.career)) {
+				paragraphStart.push("during one of his wide gestures you notice", he, "dropped something in your drink. When you confront", him, "about it", he, "draws a weapon and shoots you before you have a chance to react.");
+				if (slaveLeft && canWalk(S.Bodyguard)) {
+					paragraphStart.push("When your bodyguard storms in it is already too late and your murderer being dead too will not make you alive again.");
+				} else {
+					paragraphStart.push("Before", he, "can leave the building your security detains", him, ", but this won't help you anymore.");
+				}
+				App.Events.addParagraph(fragment, paragraphStart);
+				gameOver(fragment);
+			} else {
+				poisoned(fragment, paragraphStart);
+			}
+		}
+	}
+
+	function bgStaysRoute(){
+		const fragment = document.createDocumentFragment();
+
+		if (isSincere) {
+			let r = [];
+			r.push("\"Very good\"", he, "smiles. Seeing your confused look,", he,
+				"says \"We are not interested in dealing with someone who isn't in control of their own affairs.\" Seems like you just passed a test.");
+			App.Events.addParagraph(fragment, r);
+			r = [];
+			r.push("After this, he continues explaining.");
+			sincereProposal(fragment, r);
+		} else {
+			let r = [];
+			r.push("\"If you say so\", ", he,
+				"continues and starts explaining the plans anew, sometimes with great gestures, without ever getting to the point and you start to get bored");
+			if (S.Bodyguard.skill.combat > 0 && canSee(S.Bodyguard)) {
+				r.push("until", he, "does on of", his, "grand gestures again and",
+					S.Bodyguard.slaveName, canWalk(S.Bodyguard) ? "jumps forward" : "starts");
+				if (perceptiveCareers.includes(V.PC.career)) {
+					r.push(r.pop() + ", just a moment faster than you,");
+				}
+				r.push("and asks the man what", he, "just put in your drink.");
+				bgDefense(fragment, r);
+			} else if (perceptiveCareers.includes(V.PC.career)) {
+				r.push("until", he, "does on of", his, "grand gestures again, during which you notice", he,
+					"put something in your drink and you confront", him, "about what", he, "just did.");
+				bgDefense(fragment, r);
+			} else {
+				r.push(r.pop() + ". After a while");
+				poisoned(fragment, r);
+			}
+		}
+		return fragment;
+	}
+
+	function bgDefense(fragment, paragraphStart) {
+		paragraphStart.push("Before you can react to anything the", man, "draws a weapon and");
+		if (hasAnyArms(S.Bodyguard) && canSee(S.Bodyguard)) {
+			const {she: sheBG, her: herBG} = getPronouns(S.Bodyguard);
+			paragraphStart.push(paragraphStart.pop() + ",");
+			if (Deadliness(S.Bodyguard) > 4) {
+				paragraphStart.push("just a moment faster,", S.Bodyguard.slaveName, "draws", herBG, "own, shooting", him,
+					"in the shoulder. Screaming of pain, ", he, "drops", his, "weapon and", S.Bodyguard.slaveName,
+					"swiftly moves to secure", him);
+				App.Events.addParagraph(fragment, paragraphStart);
+				let r = [];
+				r.push("After the initial shock is over you are about to start interrogating", him, "about who send",
+					him + ", but all of a sudden", he, "starts convulsing and a few moments later", he,
+					"is dead. Seems like they care a lot about not being tracked down. And indeed, all the already sparse information about",
+					companyName, "is gone and any leads you might have had are useless. You task your assistant to continue searching for the one behind this, but you don't expect anything to come out of it. Someone wanting you dead is no surprise to you and without any idea as to why there are thousands of small groups and individuals who want arcology owners, your kind of owner or maybe just you personally dead.");
+				App.Events.addParagraph(fragment, r);
+				continueButton(fragment);
+			} else {
+				paragraphStart.push("just a moment too slow,", S.Bodyguard.slaveName, "draws", herBG, "own, shooting", him,
+					"in the chest, but at that point you already have a bullet in your heart.");
+				App.Events.addParagraph(fragment, paragraphStart);
+				gameOver(fragment);
+			}
+		} else {
+			paragraphStart.push("shoots you. Having a bodyguard who cannot actually defend you might not have been the best choice in retrospect.");
+			App.Events.addParagraph(fragment, paragraphStart);
+			gameOver(fragment);
+		}
+	}
+
+	function bgLeavesRoute(){
+		const fragment = document.createDocumentFragment();
+		if (isSincere) {
+			let r = [];
+			r.push("After your bodyguard leaves,", he,
+				"looks at you for a while, before saying, \"I don't believe you are ready to do business with us.\" When you question why,",
+				he, "answers \"If you can't trust your bodyguard with sensitive information, you clearly have bigger problems too worry about than our small proposal.\" before leaving your office without waiting for a guide to lead",
+				him, "outside.");
+			App.Events.addParagraph(fragment, r);
+			continueButton(fragment);
+		} else {
+			let r = [];
+			r.push("\"Thank you.\" he continues.");
+			noSlaveRoute(fragment, r, true);
+		}
+		return fragment;
+	}
+
+	function poisoned(fragment, paragraphStart){
+		let r = paragraphStart;
+		r.push(he, "starts packing up and tells you to call", him,
+			"if you are interested. You certainly will not, if you wanted to hear someone talk for hours without saying anything you would watch old world politicians.");
+		App.Events.addParagraph(fragment, r);
+		r = [];
+		r.push("Several hours later you start too feel unwell and a few minutes after you drop dead. Later autopsy reveals you were poisoned.");
+		App.Events.addParagraph(fragment, r);
+		gameOver(fragment);
+	}
+
+	function sincereProposal(fragment, paragraphStart) {
+		const options = [];
+		switch (variation) {
+			case "trade":
+				paragraphStart.push(companyName, "is planning a trade deal with an old world corporation that wants to expand into the Free Cities, but with the added twist of effectively robbing them during this. Their problem is that they need a something to show them and your arcology would ideal for this. Your role would be simple, just following a short script before leaving both sides to negotiate. If everything goes as planned your share could be in the six digit realm, but in case something goes wrong your reputation would be severely damaged.");
+				options.push(
+					new App.Events.Result("A chance to get this amount of money doesn't come by every day. Of course you take this opportunity.", accept()),
+					new App.Events.Result("The potential winnings are not in proportion to the risk. You will be part of their plans.", refused)
+				);
+				break;
+			case "slave":
+				paragraphStart.push(companyName, "is dealing in a special kind of enslavement. Instead of searching for buyers for the slaves they already have, they instead first search for buyers and enslave those the buyer wants to buy. And while you can at many companies pre buy slaves with certain traits,",
+					companyName, "enslaves the exact individuals you want, fabricating debt or even kidnapping until they own their target.");
+				options.push(
+					new App.Events.Result("Enslaving that annoying guy from high school might be petty, but it will be worth it nonetheless.", accept("school"), "Costs ¤50.000"),
+					new App.Events.Result("There is a rising star in the song industry who would fit perfectly in your stable.", accept("star"), "Costs ¤250.000"),
+					new App.Events.Result("There is no one you want to enslave right now.", refused)
+				);
+				break;
+			case "drug":
+				paragraphStart.push(companyName, "has developed a new performance enhancing drug that can greatly enhance a humans productivity. It does however come with serious drawbacks making it unusable for sex slaves, but it could immensely enhance the performance of your menial slaves.");
+				options.push(
+					new App.Events.Result("Making more money from your menials is always good. Buy the drug.", accept(), "Costs ¤100.000"),
+					new App.Events.Result("With the few menials you have you will not recoup the costs for the drug anytime soon.", refused)
+				);
+				break;
+			case "military":
+				paragraphStart.push(companyName, "is part of an endeavour to carve out a Free Cities colony in the old world. While being too far way to influence your local political climate it is certainly a new milestone in the Free Cities dominance over the old world. Your mercenaries are known to be veterans in fighting on old world territory and you supply them with state-of-the-art equipment, so it is only natural for them to ask you to borrow your mercenaries for this operation. Shipping your mercenaries around the globe would be a big operation, but all participants who don't get part of the colony itself will receive a large monetary compensation.");
+				options.push(
+					new App.Events.Result("This is a worthy endeavour. Of course you will help out.", accept()),
+					new App.Events.Result("Military operations tend to be a net loss most of the time. You will watch with interest but that's it.", refused)
+				);
+		}
+		App.Events.addParagraph(fragment, paragraphStart);
+		App.Events.addResponses(fragment, options, "deal");
+	}
+
+	/**
+	 * @param {string} [argument]
+	 * @returns {function(): Array<string>}
+	 */
+	function accept(argument) {
+		return function() {
+			// TODO write to game state
+			const r = [];
+			switch (variation) {
+				case "trade":
+					r.push("You discuss the details of the operation before", he, "leaves. You will have a guest soon.");
+					break;
+				case "slave":
+					r.push("You tell", him, "your target and he nods. \"A great idea. It should take no longer than a few weeks.\"");
+					break;
+				case "drug":
+					r.push("The drug will be delivered within the week.");
+					break;
+				case "military":
+					r.push("You order your mercenaries to prepare and a few days later they start to leave. You do not expect to hear much in the next few months, military operations of this size simply take time.");
+					break;
+			}
+			const fragment = document.createDocumentFragment();
+			App.Events.addParagraph(fragment, r);
+			continueButton(fragment);
+			return fragment;
+		};
+	}
+
+	function refused() {
+		// TODO flavor text
+		return endEvent();
+	}
+
+	/* End event functions */
+
+	function gameOver(fragment) {
+		App.Events.addParagraph(fragment, ["<span class='bold'>GAME OVER</span>"]);
+		V.ui = "start";
+		UIBar.update();
+	}
+
+	function endEvent() {
+		Engine.play(nextPassage);
+		return [];
+	}
+
+	function continueButton(fragment) {
+		fragment.append(App.UI.DOM.passageLink("Continue", nextPassage));
+		V.nextButton = "Continue";
+		V.nextLink = nextPassage;
+		UIBar.update();
+	}
+};
diff --git a/src/events/scheduled/murderAttempt.tw b/src/events/scheduled/murderAttempt.tw
new file mode 100644
index 00000000000..096c96fc2af
--- /dev/null
+++ b/src/events/scheduled/murderAttempt.tw
@@ -0,0 +1,5 @@
+:: Murder Attempt [nobr]
+
+<<set $nextButton = " ">>
+
+<<includeDOM App.Events.murderAttempt()>>
-- 
GitLab