diff --git a/src/events/nonRandom/mercs/pRaidInvitation.js b/src/events/nonRandom/mercs/pRaidInvitation.js
index 2bbc8ff8707fe1dadd5560cef88fb447f965b0ab..f5a5ff4ced2b57af4683e4bd40a0db138cfcd9d5 100644
--- a/src/events/nonRandom/mercs/pRaidInvitation.js
+++ b/src/events/nonRandom/mercs/pRaidInvitation.js
@@ -1,49 +1,61 @@
-		:: P raid invitation [nobr]
+App.Events.PRaidInvitation = class PRaidInvitation extends App.Events.BaseEvent {
+	eventPrerequisites() {
+		return [
+			() => V.mercenaries === 0
+		];
+	}
 
+	execute(node) {
 		V.nextButton = "Continue";
 
-		V.eventResults.raid = 0, V.eventResults.raidTarget = 0;
-
-		The former country whose citizens launched the ultimately futile attack on the arcology has continued to degenerate. After a series of civil disturbances and minor natural disasters, the nearest major city is being abandoned by its few remaining residents. A regional warlord is threatening the area, so they are streaming in small parties towards another city that is not yet under his shadow.
-		<br><br>
-		The citizens of V.arcologies[0].name view their discomfiture without much pity. These people almost certainly would have abused them just as much as they are now in danger of being abused themselves, had the attack on the Free City been a success. There would be little to no criticism if you and your mercenary contingent were to take this unique opportunity to corral one of the refugee groups. They are refugees, after all; no one will miss them.
-		<br><br>
-		<span id="result">
-		Fund a quick raid on the refugees with 
-		V.cashFormat(5000)
-			r.push(`, targeting:`);
-		<br>&nbsp;&nbsp;&nbsp;&nbsp;
-		<<link "Ex-soldiers">>
-			<<replace "#result">>
-			r.push(`Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`);
-			cashX(-5000, "war");
+		V.eventResults.raid = 0;
+		V.eventResults.raidTarget = 0;
+		App.Events.addParagraph(node, [
+			`The former country whose citizens launched the ultimately futile attack on the arcology has continued to degenerate. After a series of civil disturbances and minor natural disasters, the nearest major city is being abandoned by its few remaining residents. A regional warlord is threatening the area, so they are streaming in small parties towards another city that is not yet under his shadow.`
+		]);
+
+		App.Events.addParagraph(node, [
+			`The citizens of ${V.arcologies[0].name} view their discomfiture without much pity. These people almost certainly would have abused them just as much as they are now in danger of being abused themselves, had the attack on the Free City been a success. There would be little to no criticism if you and your mercenary contingent were to take this unique opportunity to corral one of the refugee groups. They are refugees, after all; no one will miss them.`
+		]);
+
+		const raidCost = 5000;
+		App.Events.addParagraph(node, [`Fund a quick raid on the refugees with ${cashFormat(raidCost)}, targeting:`]);
+
+		const choices = [];
+		if (V.cash > raidCost) {
+			choices.push(new App.Events.Result(`Ex-soldiers`, exSoldiers));
+			choices.push(new App.Events.Result(`Healthy civilians`, healthyCiv));
+			choices.push(new App.Events.Result(`The largest possible group of slaves`, slaveDotMax));
+		} else {
+			choices.push(new App.Events.Result(null, null, `You can't even afford ${cashFormat(raidCost)}`));
+		}
+		choices.push(new App.Events.Result(`Or, just let them go`, free));
+		App.Events.addResponses(node, choices);
+
+		function exSoldiers() {
+			cashX(-raidCost, "war");
 			V.eventResults.raid = 1;
 			V.eventResults.raidTarget = 1;
-			<</replace>>
-		<</link>>
-		<br>&nbsp;&nbsp;&nbsp;&nbsp;
-		<<link "Healthy civilians">>
-			<<replace "#result">>
-			r.push(`Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`);
-			cashX(-5000, "war");
+			return `Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`;
+		}
+
+		function healthyCiv() {
+			cashX(-raidCost, "war");
 			V.eventResults.raid = 1;
 			V.eventResults.raidTarget = 2;
-			<</replace>>
-		<</link>>
-		<br>&nbsp;&nbsp;&nbsp;&nbsp;
-		<<link "The largest possible group of slaves">>
-			<<replace "#result">>
-			r.push(`Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`);
-			cashX(-5000, "war");
+			return `Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`;
+		}
+
+		function slaveDotMax() {
+			cashX(-raidCost, "war");
 			V.eventResults.raid = 1;
 			V.eventResults.raidTarget = 3;
-			<</replace>>
-		<</link>>
-		<br>Or, simply:
-		<br>&nbsp;&nbsp;&nbsp;&nbsp;
-		<<link "Let them go">>
-			<<replace "#result">>
-			r.push(`Some of the refugees make it to safety. Some do not.`);
-			<</replace>>
-		<</link>>
-		</span>
+			return `Your mercenaries probably would have been enthusiastic even before the recent combat, but now they're positively eager. The split agreed upon is that they keep the proceeds from the sale of anything that isn't sex slave material, while you keep anything that is.`;
+		}
+
+		function free() {
+			return `Some of the refugees make it to safety. Some do not.`;
+		}
+	}
+};
+
diff --git a/src/events/timeGatedPlotEvent.js b/src/events/timeGatedPlotEvent.js
index b0c58f8b5736caa84b9bdfd18f367111713c86a0..9d29c023ad8ce1103edcc9b57195126e413578d5 100644
--- a/src/events/timeGatedPlotEvent.js
+++ b/src/events/timeGatedPlotEvent.js
@@ -18,9 +18,7 @@ App.Events.TimeGatedPlotEvent = class TimeGatedPlotEvent extends App.Events.Base
 			() => V.mercenaries > 0
 		], "P snatch and grab");
 		this.events[43] = new App.Events.TwineEvent().wrapPassage([], "P invasion");
-		this.events[46] = new App.Events.TwineEvent().wrapPassage([
-			() => V.mercenaries > 0
-		], "P raid invitation");
+		this.events[46] = new App.Events.PRaidInvitation();
 		this.events[56] = new App.Events.PUndergroundRailroad();
 		this.events[58] = new App.Events.PBombing();
 		this.events[61] = new App.Events.PTraitorMessage();