Vereinfachter-NPC/Kreaturen-Bogen (#107)

Ich habe mal den ersten Entwurf eines NPC Bogens fertiggestellt. Ist jetzt ein eigener Actor Type geworden und nicht nur ein alternativer Char Bogen:
Einfach beim Erstellen eines neuen Actors NPC wählen.

Co-authored-by: Ender <harald@drueppels.de>
Co-authored-by: LeFrique <lefrique@live.de>
Co-authored-by: Byroks <byroks@gmail.com>
Reviewed-on: #107
Reviewed-by: Le-Frique <lefrique@live.de>
This commit was merged in pull request #107.
This commit is contained in:
2024-05-14 11:38:20 +02:00
co-authored by Ender Le-Frique Byroks
parent 37d6ba12e7
commit 3ecd2c6c1e
17 changed files with 636 additions and 54 deletions
+5
View File
@@ -15,6 +15,11 @@ const preloadTemplates = async (): Promise<Handlebars.TemplateDelegate<any>[]> =
"sheets/character/spells.hbs",
"sheets/character/combat.hbs",
"sheets/character/effects.hbs",
"sheets/npc/main.hbs",
"sheets/npc/combat.hbs",
"sheets/npc/properties.hbs",
"sheets/npc/description.hbs",
"sheets/npc/attribute.hbs",
"sheets/partial/mod.hbs",
"sheets/item/rolls.hbs",
"chat/roll-m5.hbs",
+1
View File
@@ -162,6 +162,7 @@ export interface M5AttributeCalculated extends M5ModResult {
export interface M5CharacterCalculatedData {
level: number;
movement: number;
attributes: {
st: M5AttributeCalculated;
gs: M5AttributeCalculated;
+12 -12
View File
@@ -314,7 +314,7 @@ export class M5Item extends Item {
return ret;
}
async roll() {
async roll(toggleAutomatedRoll = false) {
const item = this as any;
// Initialize chat data.
@@ -341,20 +341,20 @@ export class M5Item extends Item {
}
});
if (item.type === "spell" || item.type === "kampfkunst") {
if (this.actor["system"].ap.value >= item.system.ap) {
this.actor["update"]({
data: {
ap: {
value: this.actor["system"].ap.value - item.system.ap,
const roll = new M5Roll(rollData, this.actor, item.name, item.id);
if (await roll.toMessage(toggleAutomatedRoll)) {
if (item.type === "spell" || item.type === "kampfkunst") {
if (this.actor["system"].ap.value >= item.system.ap) {
this.actor["update"]({
data: {
ap: {
value: this.actor["system"].ap.value - item.system.ap,
},
},
},
});
});
}
}
}
const roll = new M5Roll(rollData, this.actor, item.name, item.id);
return roll.toMessage();
} else {
ChatMessage.create({
speaker: speaker,
+14 -6
View File
@@ -142,18 +142,26 @@ export class M5Roll {
return renderTemplate(M5Roll.TEMPLATE_PATH, this.data);
}
async toMessage() {
let checkOptions = await this.popUp({ isPW: this.data.rolls[0].label === (game as Game).i18n.localize("midgard5.pw") });
if (checkOptions["cancelled"]) {
return;
async toMessage(toggleAutomatedRoll = false) {
let automatedRoll = (game as Game).settings.get("midgard5", "automatedRoll");
automatedRoll = toggleAutomatedRoll ? !automatedRoll : automatedRoll;
const rMode = (game as Game).settings.get("core", "rollMode");
if (!automatedRoll) {
let checkOptions = await this.popUp({ isPW: this.data.rolls[0].label === (game as Game).i18n.localize("midgard5.pw") });
if (checkOptions["cancelled"]) {
return;
} else {
const rMode = checkOptions["rollMode"];
this.data.b = checkOptions;
}
} else {
this.data.b = checkOptions;
this.data.b = { difficulty: 20, modifier: 0 };
}
if (!this._evaluated) await this.evaluate();
const faces = this.pool.dice.map((x) => x.faces);
const rMode = checkOptions["rollMode"] || (game as Game).settings.get("core", "rollMode");
const chatData = {
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
content: await this.render(),
+35 -15
View File
@@ -7,7 +7,6 @@ import { M5Roll } from "../rolls/M5Roll";
export default class M5CharacterSheet extends ActorSheet {
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
template: "systems/midgard5/templates/sheets/character/main.hbs",
width: 1000,
height: 800,
classes: ["midgard5", "sheet", "character"],
@@ -21,7 +20,15 @@ export default class M5CharacterSheet extends ActorSheet {
});
}
// get template() {
get template() {
//console.log("M5CharacterSheet", this.actor.data.type)
if (this.actor.type === "npc") {
return "systems/midgard5/templates/sheets/npc/main.hbs";
}
else {
return "systems/midgard5/templates/sheets/character/main.hbs";
}
}
// return "systems/midgard5/templates/character_sheet/main.hbs"
// }Options extends ActorSheet.Options = ActorSheet.Options, Data extends object = ActorSheet.Data<Options>
@@ -78,7 +85,8 @@ export default class M5CharacterSheet extends ActorSheet {
let attributeValue = target ? parseInt(target.dataset.value) : null;
let attributeStr = target ? target.dataset.attribute : null;
const roll = M5Roll.fromAttributeValue(this.actor, attributeStr, attributeValue);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".edit-item").on("click", async (event) => {
@@ -138,7 +146,8 @@ export default class M5CharacterSheet extends ActorSheet {
});
}
await item.roll();
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
this.render();
});
@@ -158,7 +167,8 @@ export default class M5CharacterSheet extends ActorSheet {
const actor = this.actor as any;
const item = actor.items.get(skillId) as M5Item;
await item.roll();
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
});
html.find(".roll-general-button").on("click", async (event) => {
@@ -169,7 +179,8 @@ export default class M5CharacterSheet extends ActorSheet {
const unlearnedSkill = data.skills.general[skillName] as M5SkillUnlearned;
const roll = M5Roll.fromUnlearnedSkill(this.actor, unlearnedSkill, skillName);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".learn-button").on("click", async (event) => {
@@ -267,48 +278,57 @@ export default class M5CharacterSheet extends ActorSheet {
const context = this.actor as any;
const item = context.items.get(itemId) as M5Item;
await item.roll();
let toggleAutomatedRoll = (event.shiftKey)
await item.roll(toggleAutomatedRoll);
this.render();
});
html.find(".roll-brawl-button").on("click", async (event) => {
const roll = M5Roll.brawl(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-cleanSpell-button").on("click", async (event) => {
const roll = M5Roll.cleanSpell(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationCold-button").on("click", async (event) => {
const roll = M5Roll.deprivationCold(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationHeat-button").on("click", async (event) => {
const roll = M5Roll.deprivationHeat(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-deprivationFood-button").on("click", async (event) => {
const roll = M5Roll.deprivationFood(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-defense-button").on("click", async (event) => {
const roll = M5Roll.defense(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-resistanceMind-button").on("click", async (event) => {
const roll = M5Roll.resistanceMind(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".roll-resistanceBody-button").on("click", async (event) => {
const roll = M5Roll.resistanceBody(this.actor);
await roll.toMessage();
let toggleAutomatedRoll = (event.shiftKey)
await roll.toMessage(toggleAutomatedRoll);
});
html.find(".change-equipped").on("click", async (event) => {
+9
View File
@@ -13,4 +13,13 @@ export const loadSettings = async function () {
default: true,
type: Boolean,
});
(game as Game).settings.register("midgard5", "automatedRoll", {
name: "Automatische Würfelwürfe",
hint: "Falls aktiv, wird bei Würfelwürfen kein Dialog gezeigt. Das Verhalten kann mit gleichzeitig gedrückter Shift Taste umgekehrt werden.",
scope: "world",
config: true,
default: false,
type: Boolean,
});
};
+23
View File
@@ -0,0 +1,23 @@
// main: midgard5.less
@borderGroove: 2px groove #eeede0;
@attributeBorderColor: rgba(0, 0, 0, 0.5);
.midgard5 {
.sheet-npc {
.attribute-header {
align-items: center;
text-align: center;
font-weight: bold;
border: 0px solid transparent;
}
.attribute-value {
align-items: center;
text-align: center;
border: 0px solid transparent;
}
.fixed-value {
width: 3rem;
text-align: center;
}
}
}
+18 -4
View File
@@ -1,15 +1,18 @@
{
"Actor": {
"types": ["character"],
"types": [
"character",
"npc"
],
"templates": {
"characterDescription": {
"info": {
"description": "",
"background": "",
"class": {},
"npc-class": "",
"race": "",
"magicUsing": false,
"showAllItems": false,
"gender": "",
"weight": "",
"height": "",
@@ -19,9 +22,12 @@
"occupation": "",
"origin": "",
"faith": "",
"level": 1,
"gold": 0,
"silver": 0,
"copper": 0
"copper": 0,
"showAllItems": false,
"showUnlearned": false
}
},
"characterBars": {
@@ -44,6 +50,8 @@
"gp": 0
},
"attributes": {
"level": 1,
"movement": 24,
"attributes": {
"st": { "value": 50, "bonus": 0 },
"gs": { "value": 50, "bonus": 0 },
@@ -53,7 +61,8 @@
"zt": { "value": 50, "bonus": 0 },
"au": { "value": 50, "bonus": 0 },
"pa": { "value": 50, "bonus": 0 },
"wk": { "value": 50, "bonus": 0 }
"wk": { "value": 50, "bonus": 0 },
"git": { "value": 50, "bonus": 0 }
}
},
"skills": {
@@ -156,6 +165,10 @@
"character": {
"templates": ["characterBars", "attributes", "characterDescription", "characterHeader", "skills", "gear"],
"calc": {}
},
"npc": {
"templates": ["characterBars", "attributes", "characterDescription", "skills", "gear"],
"calc": {}
}
},
"Item": {
@@ -376,6 +389,7 @@
"hoarded": false,
"skillId": "",
"damageBase": "1d6",
"ew": 5,
"rolls": {
"formulas": {
"0": {