Skip to content

Commit

Permalink
Gremlin buff with added Cult Items (No Bomb) (#1694)
Browse files Browse the repository at this point in the history
Changed Cursed items to Broken Items in the Files.

New Cult Items
Armor: when broken, the attacker is given Insanity
Crystal ball: Reveals the selected player as Cultist
Key: Cult Actions are not blocked.
Knife: Converts instead of killing.
Whiskey: Does the Mind Rot roleblock instead (Only to non-Cult)
Bread: Cannibal's poison soup thing
Orange: Same as Bread
Candle: Shows random players if no one visits. Shows no one visited if
players did visit.
Falcon: Shows a random visit if the player didn't visit. Shows no visits
if the player did visit.
Tract: If the player is converted, They will be converted to a random
Cult role instead.
Syringe: Resurrects the player and Converts to Cultist.
Envelope: The Envelope's message is made Insane
Rifle: Converts instead of killing (Target Only)
Stake: Does not work on Cult.

New Broken items
Key: Blocks no one
Envelope: Doesn't send a message.
Syringe: Doesn't revive player
Candle: Same as Cult Item (Gives False info)
Falcon: Same as Cult Item  (Gives False info)
Stake: Switches target to user.

Fabricator can give out the new Broken Items. (Excluding Stake)
Trickster Items have a 25% chance to be Magic. (Because It's Funny)
Gremlin now has the worst looking description.

---------

Co-authored-by: SawJester <[email protected]>
  • Loading branch information
SawJester and SawJester authored Aug 13, 2024
1 parent a1931b4 commit cb7a5c3
Show file tree
Hide file tree
Showing 99 changed files with 1,284 additions and 817 deletions.
62 changes: 5 additions & 57 deletions Games/types/Mafia/Action.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,73 +70,21 @@ module.exports = class MafiaAction extends Action {
}
if (hasInvestigate) {
target.giveEffect("FalseMode", 1);
/*
let visits = this.getVisits(target);
let alive = this.game.alivePlayers();
var evilPlayers = alive.filter(
(p) => p.role.alignment == "Mafia" || p.role.alignment == "Cult"
);
var goodPlayers = alive.filter(
(p) => p.role.alignment != "Mafia" && p.role.alignment != "Cult"
);
if (visits.length == 0) {
//let neighbors = target.getAliveNeighbors();
let index = alive.indexOf(target);
const leftIdx = (index - 1 + alive.length) % alive.length;
const rightIdx = (index + 1) % alive.length;
let neighbors = [alive[leftIdx], alive[rightIdx]];
let neighborTarget = Random.randArrayVal(neighbors);
if (
neighborTarget.role.alignment == "Village" &&
this.actor.role.alignment != "Village"
) {
neighborTarget.setTempAppearance("investigate", this.actor.role.name);
} else if (neighborTarget.role.alignment != "Village") {
neighborTarget.setTempAppearance(
"investigate",
Random.randArrayVal(goodPlayers).role.name
);
} else {
neighborTarget.setTempAppearance(
"investigate",
Random.randArrayVal(evilPlayers).role.name
);
}
} else {
for (let visit of visits) {
if (
visit.role.alignment == "Village" &&
this.actor.role.alignment != "Village"
) {
visit.setTempAppearance("investigate", this.actor.role.name);
} else if (visit.role.alignment != "Village") {
visit.setTempAppearance(
"investigate",
Random.randArrayVal(goodPlayers).role.name
);
} else {
visit.setTempAppearance(
"investigate",
Random.randArrayVal(evilPlayers).role.name
);
}
}
}
*/
}
}

makeUntargetable(player, excludeLabel) {
makeUntargetable(player, excludeLabel, excludeAlignment) {
player = player || this.target;

for (let action of this.game.actions[0]) {
if (action.hasLabel("absolute") || action.hasLabel(excludeLabel)) {
continue;
}

if (action.actor.role.alignment == excludeAlignment) {
continue;
}

let toCheck = action.target;
if (!Array.isArray(action.target)) {
toCheck = [action.target];
Expand Down
42 changes: 42 additions & 0 deletions Games/types/Mafia/effects/BleedingCult.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const Effect = require("../Effect");
const Action = require("../Action");

module.exports = class BleedingCult extends Effect {
constructor(killer) {
super("BleedingCult");
this.killer = killer;
}

apply(player) {
if (player.hasEffect("BleedingCult")) {
return;
}

super.apply(player);
player.queueAlert("You start to bleed…");

this.action = new Action({
actor: this.killer,
target: player,
game: this.killer.game,
labels: ["convert", "bleed", "hidden", "absolute", "uncontrollable"],
delay: 1,
effect: this,
run: function () {
if (this.dominates()) {
if (this.target.role.alignment == "Cult") return;
this.target.setRole("Cultist");
}

this.effect.remove();
},
});

this.game.queueAction(this.action);
}

remove() {
super.remove();
this.action.cancel(true);
}
};
44 changes: 23 additions & 21 deletions Games/types/Mafia/effects/ChoirSong.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,43 @@ module.exports = class ChoirSong extends Effect {
this.actor = actor;
this.word = word;
this.lifespan = lifespan || 1;
this.listeners = {

this.listeners = {
state: function () {
if (this.game.getStateName() != "Day") return;
if (!this.player.alive) return;
//if(this.word == "Complete") return;

var action = new Action({
labels: ["hidden", "absolute", "condemn", "overthrow","Choir"],
labels: ["hidden", "absolute", "condemn", "overthrow", "Choir"],
actor: this.actor,
target: this.player,
game: this.game,
priority: PRIORITY_OVERTHROW_VOTE -2,
priority: PRIORITY_OVERTHROW_VOTE - 2,
run: function () {
if(this.word != 5){
for (let action of this.game.actions[0]) {
if (action.hasLabel("condemn") && !action.hasLabel("overthrow")) {
// Only one village vote can be overthrown
action.cancel(true);
break;
}
}
if (this.word != 5) {
for (let action of this.game.actions[0]) {
if (
action.hasLabel("condemn") &&
!action.hasLabel("overthrow")
) {
// Only one village vote can be overthrown
action.cancel(true);
break;
}
}

if (this.dominates(this.target)) {
this.target.kill("condemn", this.actor);
}
if (this.dominates(this.target)) {
this.target.kill("condemn", this.actor);
}
}
},
});
this.game.queueAction(action);

},
};

}

speak(message) {
if (message.content.replace(" ", "").toLowerCase().includes(this.word)) {
var action = new Action({
Expand All @@ -54,7 +55,9 @@ module.exports = class ChoirSong extends Effect {
labels: ["hidden"],
run: function () {
this.word = 5;
this.target.queueAlert(`You have spoken the role so you are safe unless the Banshee guesses you as their target!`);
this.target.queueAlert(
`You have spoken the role so you are safe unless the Banshee guesses you as their target!`
);
for (let action of this.game.actions[0]) {
if (action.hasLabel("Choir") && action.target == this.target) {
// Only one village vote can be overthrown
Expand All @@ -69,5 +72,4 @@ module.exports = class ChoirSong extends Effect {
this.game.instantAction(action);
}
}

};
10 changes: 9 additions & 1 deletion Games/types/Mafia/effects/Cursed.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ module.exports = class Cursed extends Effect {
}

speak(message) {
if (message.content.replaceAll(" ", "").replaceAll("-", "").replaceAll("*", "").replaceAll("_", "").toLowerCase().includes(this.word)) {
if (
message.content
.replaceAll(" ", "")
.replaceAll("-", "")
.replaceAll("*", "")
.replaceAll("_", "")
.toLowerCase()
.includes(this.word)
) {
var action = new Action({
actor: this.actor,
target: this.player,
Expand Down
10 changes: 9 additions & 1 deletion Games/types/Mafia/effects/CursedCult.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ module.exports = class CursedCult extends Effect {
}

speak(message) {
if (message.content.replaceAll(" ", "").replaceAll("-", "").replaceAll("*", "").replaceAll("_", "").toLowerCase().includes(this.word)) {
if (
message.content
.replaceAll(" ", "")
.replaceAll("-", "")
.replaceAll("*", "")
.replaceAll("_", "")
.toLowerCase()
.includes(this.word)
) {
var action = new Action({
actor: this.actor,
target: this.player,
Expand Down
2 changes: 1 addition & 1 deletion Games/types/Mafia/effects/Famished.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = class Famished extends Effect {
for (let food of foodTypes) {
let foodItems = this.player.getItems(food);
for (let item of foodItems) {
if (!item.cursed) {
if (!item.broken) {
this.player.queueAlert("You eat some food.");
item.eat();
item.drop();
Expand Down
35 changes: 35 additions & 0 deletions Games/types/Mafia/effects/SedateMindRot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const Effect = require("../Effect");
const Action = require("../Action");
const { PRIORITY_NIGHT_ROLE_BLOCKER } = require("../const/Priority");

module.exports = class SedateMindRot extends Effect {
constructor(doer) {
super("SedateMindRot");
this.doer = doer;
}

apply(player) {
super.apply(player);

this.action = new Action({
actor: this.doer,
target: player,
labels: ["block"],
priority: PRIORITY_NIGHT_ROLE_BLOCKER,
delay: 1,
effect: this,
game: this.game,
run: function () {
this.blockWithMindRot();
this.effect.remove();
},
});

this.game.queueAction(this.action);
}

remove() {
super.remove();
this.action.cancel();
}
};
24 changes: 12 additions & 12 deletions Games/types/Mafia/items/Armor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ module.exports = class Armor extends Item {
super("Armor");

this.uses = 1;
// if armour starts out cursed, the setter will handle the logic of making it cursed
this.cursedUses = 0;
this.optionCursed = options?.cursed;
// if armour starts out broken, the setter will handle the logic of making it broken
this.brokenUses = 0;
this.optionBroken = options?.broken;
this.magicCult = options?.magicCult;

this.listeners = {
Expand All @@ -28,7 +28,7 @@ module.exports = class Armor extends Item {
}
}

if(this.magicCult){
if (this.magicCult) {
action.actor.giveEffect("Insanity");
}

Expand All @@ -39,7 +39,7 @@ module.exports = class Armor extends Item {

if (this.uses <= 0) {
this.removeEffectsIfNeeded();
if (this.cursedUses <= 0) {
if (this.brokenUses <= 0) {
this.drop();
}
}
Expand All @@ -48,14 +48,14 @@ module.exports = class Armor extends Item {
};
}

set cursed(cursed) {
if (cursed) {
this.cursedUses += this.uses;
set broken(broken) {
if (broken) {
this.brokenUses += this.uses;
this.uses = 0;
this.removeEffectsIfNeeded();
} else {
this.uses += this.cursedUses;
this.cursedUses = 0;
this.uses += this.brokenUses;
this.brokenUses = 0;
this.applyEffectsIfNeeded();
}
}
Expand All @@ -78,13 +78,13 @@ module.exports = class Armor extends Item {
for (let item of player.items) {
if (item.name == "Armor") {
item.uses += this.uses;
item.cursedUses += this.cursedUses;
item.brokenUses += this.brokenUses;
item.applyEffectsIfNeeded();
return;
}
}

super.hold(player);
this.cursed = this.optionCursed;
this.broken = this.optionBroken;
}
};
32 changes: 31 additions & 1 deletion Games/types/Mafia/items/Bread.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
const Item = require("../Item");
const Action = require("../Action");
const { PRIORITY_EFFECT_GIVER_DEFAULT } = require("../const/Priority");

module.exports = class Bread extends Item {
constructor(options) {
super("Bread");

this.cursed = options?.cursed;
this.broken = options?.broken;
this.magicCult = options?.magicCult;
}
eat() {
if (this.magicCult == true && this.holder.role.alignment != "Cult") {
let action = new Action({
actor: this.holder,
target: this.holder,
game: this.game,
labels: [
"giveEffect",
"poison",
"hidden",
"absolute",
"uncontrollable",
],
priority: PRIORITY_EFFECT_GIVER_DEFAULT,
run: function () {
if (this.dominates()) {
this.target.queueAlert(
"You have been poisoned by the Cult's Magic Food!"
);
this.target.giveEffect("poison", this.actor);
}
},
});

action.do();
}
}
};
Loading

0 comments on commit cb7a5c3

Please sign in to comment.