generated from DNDs/dnd-template
Compare commits
2 Commits
c7b0f6d14d
...
e037f81d2b
Author | SHA1 | Date | |
---|---|---|---|
e037f81d2b | |||
350248b4d4 |
3
.obsidian/community-plugins.json
vendored
3
.obsidian/community-plugins.json
vendored
@ -4,5 +4,6 @@
|
|||||||
"obsidian-image-toolkit",
|
"obsidian-image-toolkit",
|
||||||
"obsidian-icons-plugin",
|
"obsidian-icons-plugin",
|
||||||
"obsidian-reading-time",
|
"obsidian-reading-time",
|
||||||
"dataview"
|
"dataview",
|
||||||
|
"obsidian-dialogue-plugin"
|
||||||
]
|
]
|
340
.obsidian/plugins/obsidian-dialogue-plugin/main.js
vendored
Normal file
340
.obsidian/plugins/obsidian-dialogue-plugin/main.js
vendored
Normal file
@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||||
|
if you want to view the source, please visit the github repository of this plugin
|
||||||
|
*/
|
||||||
|
|
||||||
|
var __create = Object.create;
|
||||||
|
var __defProp = Object.defineProperty;
|
||||||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||||
|
var __getProtoOf = Object.getPrototypeOf;
|
||||||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||||
|
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
||||||
|
var __export = (target, all) => {
|
||||||
|
__markAsModule(target);
|
||||||
|
for (var name in all)
|
||||||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||||||
|
};
|
||||||
|
var __reExport = (target, module2, desc) => {
|
||||||
|
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
||||||
|
for (let key of __getOwnPropNames(module2))
|
||||||
|
if (!__hasOwnProp.call(target, key) && key !== "default")
|
||||||
|
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
var __toModule = (module2) => {
|
||||||
|
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
||||||
|
};
|
||||||
|
var __async = (__this, __arguments, generator) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var fulfilled = (value) => {
|
||||||
|
try {
|
||||||
|
step(generator.next(value));
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var rejected = (value) => {
|
||||||
|
try {
|
||||||
|
step(generator.throw(value));
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
||||||
|
step((generator = generator.apply(__this, __arguments)).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/main.ts
|
||||||
|
__export(exports, {
|
||||||
|
default: () => DialoguePlugin
|
||||||
|
});
|
||||||
|
var import_obsidian2 = __toModule(require("obsidian"));
|
||||||
|
|
||||||
|
// src/types/dialogueTitleMode.ts
|
||||||
|
var DialogueTitleMode;
|
||||||
|
(function(DialogueTitleMode2) {
|
||||||
|
DialogueTitleMode2["Disabled"] = "disabled";
|
||||||
|
DialogueTitleMode2["First"] = "first";
|
||||||
|
DialogueTitleMode2["All"] = "all";
|
||||||
|
})(DialogueTitleMode || (DialogueTitleMode = {}));
|
||||||
|
|
||||||
|
// src/constants/classes.ts
|
||||||
|
var CLASSES = class {
|
||||||
|
};
|
||||||
|
CLASSES.DIALOGUE_WRAPPER = "dialogue-plugin-wrapper";
|
||||||
|
CLASSES.BLOCK_WRAPPER = "dialogue-plugin-block-wrapper";
|
||||||
|
CLASSES.MESSAGE_WRAPPER_LEFT = "dialogue-plugin-message-wrapper-left";
|
||||||
|
CLASSES.MESSAGE_WRAPPER_RIGHT = "dialogue-plugin-message-wrapper-right";
|
||||||
|
CLASSES.MESSAGE = "dialogue-plugin-message";
|
||||||
|
CLASSES.MESSAGE_TITLE = "dialogue-plugin-message-title";
|
||||||
|
CLASSES.MESSAGE_CONTENT = "dialogue-plugin-message-content";
|
||||||
|
CLASSES.DELIMITER_WRAPPER = "dialogue-plugin-delimiter-wrapper";
|
||||||
|
CLASSES.DELIMITER = "dialogue-plugin-delimiter";
|
||||||
|
CLASSES.DELIMITER_DOT = "dialogue-plugin-delimiter-dot";
|
||||||
|
CLASSES.COMMENT_WRAPPER = "dialogue-plugin-comment-wrapper";
|
||||||
|
CLASSES.COMMENT = "dialogue-plugin-comment";
|
||||||
|
|
||||||
|
// src/components/message.ts
|
||||||
|
var SIDES = class {
|
||||||
|
};
|
||||||
|
SIDES.LEFT = "left";
|
||||||
|
SIDES.RIGHT = "right";
|
||||||
|
var Message = class {
|
||||||
|
constructor(content, side, dialogueSettings) {
|
||||||
|
this.content = content;
|
||||||
|
this.side = side;
|
||||||
|
this.dialogueSettings = dialogueSettings;
|
||||||
|
this.participant = this.side == SIDES.LEFT ? this.dialogueSettings.leftParticipant : this.dialogueSettings.rightParticipant;
|
||||||
|
this.renderMessage();
|
||||||
|
}
|
||||||
|
renderMessage() {
|
||||||
|
const messageEl = this.createMessageEl();
|
||||||
|
if (this.titleShouldRender()) {
|
||||||
|
messageEl.createDiv({ cls: CLASSES.MESSAGE_TITLE, text: this.participant.title });
|
||||||
|
}
|
||||||
|
messageEl.createDiv({ cls: CLASSES.MESSAGE_CONTENT, text: this.content });
|
||||||
|
}
|
||||||
|
createMessageEl() {
|
||||||
|
var _a;
|
||||||
|
const sideClass = this.side == SIDES.LEFT ? CLASSES.MESSAGE_WRAPPER_LEFT : CLASSES.MESSAGE_WRAPPER_RIGHT;
|
||||||
|
const messageWrapperEl = this.dialogueSettings.parent.createDiv({
|
||||||
|
cls: `${CLASSES.BLOCK_WRAPPER} ${sideClass}`
|
||||||
|
});
|
||||||
|
return messageWrapperEl.createDiv({
|
||||||
|
cls: CLASSES.MESSAGE,
|
||||||
|
attr: {
|
||||||
|
style: `max-width: ${this.dialogueSettings.messageMaxWidth};`,
|
||||||
|
"data-participant-name": this.participant.title,
|
||||||
|
"data-participant-id": (_a = this.participant.enforcedId) != null ? _a : this.dialogueSettings.participants.get(this.participant.title)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
titleShouldRender() {
|
||||||
|
if (this.participant.title.length < 1)
|
||||||
|
return false;
|
||||||
|
switch (this.dialogueSettings.titleMode) {
|
||||||
|
case DialogueTitleMode.Disabled:
|
||||||
|
return false;
|
||||||
|
case DialogueTitleMode.All:
|
||||||
|
return true;
|
||||||
|
case DialogueTitleMode.First: {
|
||||||
|
if (this.participant.renderedOnce)
|
||||||
|
return false;
|
||||||
|
this.participant.renderedOnce = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/components/delimiter.ts
|
||||||
|
var Delimiter = class {
|
||||||
|
constructor(dialogueSettings) {
|
||||||
|
this.dialogueSettings = dialogueSettings;
|
||||||
|
this.renderDelimiter();
|
||||||
|
}
|
||||||
|
renderDelimiter() {
|
||||||
|
const delimiterWrapperEl = this.dialogueSettings.parent.createDiv({
|
||||||
|
cls: `${CLASSES.BLOCK_WRAPPER} ${CLASSES.DELIMITER_WRAPPER}`
|
||||||
|
});
|
||||||
|
const delimiterEl = delimiterWrapperEl.createDiv({ cls: CLASSES.DELIMITER });
|
||||||
|
delimiterEl.createEl("div", { cls: CLASSES.DELIMITER_DOT });
|
||||||
|
delimiterEl.createEl("div", { cls: CLASSES.DELIMITER_DOT });
|
||||||
|
delimiterEl.createEl("div", { cls: CLASSES.DELIMITER_DOT });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/components/comment.ts
|
||||||
|
var Comment = class {
|
||||||
|
constructor(content, dialogueSettings) {
|
||||||
|
this.content = content;
|
||||||
|
this.dialogueSettings = dialogueSettings;
|
||||||
|
this.renderComment();
|
||||||
|
}
|
||||||
|
renderComment() {
|
||||||
|
const commentEl = this.dialogueSettings.parent.createDiv({
|
||||||
|
cls: `${CLASSES.BLOCK_WRAPPER} ${CLASSES.COMMENT_WRAPPER}`
|
||||||
|
});
|
||||||
|
return commentEl.createDiv({
|
||||||
|
cls: CLASSES.COMMENT,
|
||||||
|
text: this.content,
|
||||||
|
attr: {
|
||||||
|
style: `max-width: ${this.dialogueSettings.commentMaxWidth};`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/dialogue.ts
|
||||||
|
var KEYWORDS = class {
|
||||||
|
};
|
||||||
|
KEYWORDS.LEFT_PATTERN = /^l(?:eft)?(?:-(\d+))?:/i;
|
||||||
|
KEYWORDS.RIGHT_PATTERN = /^r(?:ight)?(?:-(\d+))?:/i;
|
||||||
|
KEYWORDS.TITLE_MODE = "titleMode:";
|
||||||
|
KEYWORDS.MESSAGE_MAX_WIDTH = "messageMaxWidth:";
|
||||||
|
KEYWORDS.COMMENT_MAX_WIDTH = "commentMaxWidth:";
|
||||||
|
KEYWORDS.DELIMITER = /^-|delimiter/;
|
||||||
|
KEYWORDS.COMMENT = "#";
|
||||||
|
KEYWORDS.MESSAGE_LEFT = "<";
|
||||||
|
KEYWORDS.MESSAGE_RIGHT = ">";
|
||||||
|
var DialogueRenderer = class {
|
||||||
|
constructor(src, parent, settings) {
|
||||||
|
this.src = src;
|
||||||
|
this.dialogueWrapperEl = parent.createDiv({ cls: CLASSES.DIALOGUE_WRAPPER });
|
||||||
|
this.dialogueSettings = {
|
||||||
|
parent: this.dialogueWrapperEl,
|
||||||
|
leftParticipant: {
|
||||||
|
title: settings.defaultLeftTitle,
|
||||||
|
renderedOnce: false,
|
||||||
|
enforcedId: null
|
||||||
|
},
|
||||||
|
rightParticipant: {
|
||||||
|
title: settings.defaultRightTitle,
|
||||||
|
renderedOnce: false,
|
||||||
|
enforcedId: null
|
||||||
|
},
|
||||||
|
titleMode: settings.defaultTitleMode,
|
||||||
|
messageMaxWidth: settings.defaultMessageMaxWidth,
|
||||||
|
commentMaxWidth: settings.defaultCommentMaxWidth,
|
||||||
|
participants: new Map()
|
||||||
|
};
|
||||||
|
this.renderDialogue();
|
||||||
|
}
|
||||||
|
registerParticipant(participant) {
|
||||||
|
if (!this.dialogueSettings.participants.has(participant)) {
|
||||||
|
this.dialogueSettings.participants.set(participant, this.dialogueSettings.participants.size + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getEnforcedId(pattern, line) {
|
||||||
|
let enforcedId = null;
|
||||||
|
const result = pattern.exec(line);
|
||||||
|
if (result != null && result.length > 1) {
|
||||||
|
enforcedId = result[1];
|
||||||
|
}
|
||||||
|
return enforcedId;
|
||||||
|
}
|
||||||
|
renderDialogue() {
|
||||||
|
const lines = this.src.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
||||||
|
for (const line of lines) {
|
||||||
|
if (KEYWORDS.LEFT_PATTERN.test(line)) {
|
||||||
|
this.dialogueSettings.leftParticipant.title = line.split(":").splice(1).join(":").trim();
|
||||||
|
this.dialogueSettings.leftParticipant.renderedOnce = false;
|
||||||
|
this.dialogueSettings.leftParticipant.enforcedId = this.getEnforcedId(KEYWORDS.LEFT_PATTERN, line);
|
||||||
|
} else if (KEYWORDS.RIGHT_PATTERN.test(line)) {
|
||||||
|
this.dialogueSettings.rightParticipant.title = line.split(":").splice(1).join(":").trim();
|
||||||
|
this.dialogueSettings.rightParticipant.renderedOnce = false;
|
||||||
|
this.dialogueSettings.rightParticipant.enforcedId = this.getEnforcedId(KEYWORDS.RIGHT_PATTERN, line);
|
||||||
|
} else if (line.startsWith(KEYWORDS.TITLE_MODE)) {
|
||||||
|
const modeName = line.substr(KEYWORDS.TITLE_MODE.length).trim().toLowerCase();
|
||||||
|
if (Object.values(DialogueTitleMode).some((mode) => mode == modeName)) {
|
||||||
|
this.dialogueSettings.titleMode = modeName;
|
||||||
|
}
|
||||||
|
} else if (line.startsWith(KEYWORDS.MESSAGE_MAX_WIDTH)) {
|
||||||
|
this.dialogueSettings.messageMaxWidth = line.substr(KEYWORDS.MESSAGE_MAX_WIDTH.length).trim();
|
||||||
|
} else if (line.startsWith(KEYWORDS.COMMENT_MAX_WIDTH)) {
|
||||||
|
this.dialogueSettings.commentMaxWidth = line.substr(KEYWORDS.COMMENT_MAX_WIDTH.length).trim();
|
||||||
|
} else if (KEYWORDS.DELIMITER.test(line)) {
|
||||||
|
new Delimiter(this.dialogueSettings);
|
||||||
|
} else if (line.startsWith(KEYWORDS.COMMENT)) {
|
||||||
|
const content = line.substr(KEYWORDS.COMMENT.length);
|
||||||
|
new Comment(content, this.dialogueSettings);
|
||||||
|
} else if (line.startsWith(KEYWORDS.MESSAGE_LEFT)) {
|
||||||
|
const content = line.substr(KEYWORDS.MESSAGE_LEFT.length);
|
||||||
|
this.registerParticipant(this.dialogueSettings.leftParticipant.title);
|
||||||
|
new Message(content, SIDES.LEFT, this.dialogueSettings);
|
||||||
|
} else if (line.startsWith(KEYWORDS.MESSAGE_RIGHT)) {
|
||||||
|
const content = line.substr(KEYWORDS.MESSAGE_RIGHT.length);
|
||||||
|
this.registerParticipant(this.dialogueSettings.rightParticipant.title);
|
||||||
|
new Message(content, SIDES.RIGHT, this.dialogueSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/settings.ts
|
||||||
|
var import_obsidian = __toModule(require("obsidian"));
|
||||||
|
var DEFAULT_SETTINGS = {
|
||||||
|
defaultLeftTitle: "",
|
||||||
|
defaultRightTitle: "",
|
||||||
|
defaultTitleMode: DialogueTitleMode.First,
|
||||||
|
defaultMessageMaxWidth: "60%",
|
||||||
|
defaultCommentMaxWidth: "60%"
|
||||||
|
};
|
||||||
|
var DialogueSettingTab = class extends import_obsidian.PluginSettingTab {
|
||||||
|
constructor(app, plugin) {
|
||||||
|
super(app, plugin);
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
display() {
|
||||||
|
const { containerEl } = this;
|
||||||
|
containerEl.empty();
|
||||||
|
containerEl.createEl("h2", { text: "Dialogue Settings" });
|
||||||
|
const coffeeEl = containerEl.createEl("div", {
|
||||||
|
attr: {
|
||||||
|
style: "text-align: center; margin-bottom: 10px;"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const coffeeLinkEl = coffeeEl.createEl("a", { href: "https://www.buymeacoffee.com/holubj" });
|
||||||
|
coffeeLinkEl.createEl("img", {
|
||||||
|
attr: {
|
||||||
|
src: "https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png",
|
||||||
|
alt: "Buy Me A Coffee",
|
||||||
|
style: "height: 60px; width: 217px;"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
new import_obsidian.Setting(containerEl).setName("Default left title").setDesc("Default value for left title in all dialogues.").addText((text) => text.setPlaceholder("Enter default left title").setValue(this.plugin.settings.defaultLeftTitle).onChange((value) => __async(this, null, function* () {
|
||||||
|
this.plugin.settings.defaultLeftTitle = value;
|
||||||
|
yield this.plugin.saveSettings();
|
||||||
|
})));
|
||||||
|
new import_obsidian.Setting(containerEl).setName("Default right title").setDesc("Default value for right title in all dialogues.").addText((text) => text.setPlaceholder("Enter default right title").setValue(this.plugin.settings.defaultRightTitle).onChange((value) => __async(this, null, function* () {
|
||||||
|
this.plugin.settings.defaultRightTitle = value;
|
||||||
|
yield this.plugin.saveSettings();
|
||||||
|
})));
|
||||||
|
new import_obsidian.Setting(containerEl).setName("Default title mode").setDesc("Default title mode in all dialogues.").addDropdown((cb) => {
|
||||||
|
Object.values(DialogueTitleMode).forEach((titleMode) => {
|
||||||
|
const mode = titleMode.toString();
|
||||||
|
cb.addOption(mode, mode.charAt(0).toUpperCase() + mode.slice(1));
|
||||||
|
});
|
||||||
|
cb.setValue(this.plugin.settings.defaultTitleMode).onChange((value) => __async(this, null, function* () {
|
||||||
|
this.plugin.settings.defaultTitleMode = value;
|
||||||
|
yield this.plugin.saveSettings();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
new import_obsidian.Setting(containerEl).setName("Default max message width").setDesc("Default max message width in all dialogues.").addText((text) => text.setPlaceholder("Enter default max message width").setValue(this.plugin.settings.defaultMessageMaxWidth).onChange((value) => __async(this, null, function* () {
|
||||||
|
this.plugin.settings.defaultMessageMaxWidth = value;
|
||||||
|
yield this.plugin.saveSettings();
|
||||||
|
})));
|
||||||
|
new import_obsidian.Setting(containerEl).setName("Default max comment width").setDesc("Default max comment width in all dialogues.").addText((text) => text.setPlaceholder("Enter default max comment width").setValue(this.plugin.settings.defaultCommentMaxWidth).onChange((value) => __async(this, null, function* () {
|
||||||
|
this.plugin.settings.defaultCommentMaxWidth = value;
|
||||||
|
yield this.plugin.saveSettings();
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/main.ts
|
||||||
|
var DialoguePlugin = class extends import_obsidian2.Plugin {
|
||||||
|
onload() {
|
||||||
|
return __async(this, null, function* () {
|
||||||
|
yield this.loadSettings();
|
||||||
|
this.registerMarkdownCodeBlockProcessor(`dialogue`, (src, el, ctx) => {
|
||||||
|
new DialogueRenderer(src, el, this.settings);
|
||||||
|
});
|
||||||
|
this.addSettingTab(new DialogueSettingTab(this.app, this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
loadSettings() {
|
||||||
|
return __async(this, null, function* () {
|
||||||
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
saveSettings() {
|
||||||
|
return __async(this, null, function* () {
|
||||||
|
yield this.saveData(this.settings);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
10
.obsidian/plugins/obsidian-dialogue-plugin/manifest.json
vendored
Normal file
10
.obsidian/plugins/obsidian-dialogue-plugin/manifest.json
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"id": "obsidian-dialogue-plugin",
|
||||||
|
"name": "Dialogue",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"minAppVersion": "0.12.0",
|
||||||
|
"description": "Create dialogues in Markdown.",
|
||||||
|
"author": "Jakub Holub",
|
||||||
|
"authorUrl": "https://github.com/holubj",
|
||||||
|
"isDesktopOnly": false
|
||||||
|
}
|
58
.obsidian/plugins/obsidian-dialogue-plugin/styles.css
vendored
Normal file
58
.obsidian/plugins/obsidian-dialogue-plugin/styles.css
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
.dialogue-plugin-wrapper {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-block-wrapper {
|
||||||
|
display: flex;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-message-wrapper-left {
|
||||||
|
justify-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-message-wrapper-right {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-message {
|
||||||
|
overflow: hidden;
|
||||||
|
max-width: 60%;
|
||||||
|
background-color: var(--background-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-message-title {
|
||||||
|
padding: 5px 10px;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-message-content {
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-delimiter-wrapper {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-delimiter {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-delimiter-dot {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin: 0 3px;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: var(--background-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-comment-wrapper {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialogue-plugin-comment {
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
@ -1,43 +1,81 @@
|
|||||||
|
*Version 1.0*
|
||||||
# Änderungen am Basisregelwerk
|
# Änderungen am Basisregelwerk
|
||||||
Im generellen belege ich alles auf dem Basisregelwerk, welches hier schnell eingesehen werden kann; [Crobis quickref](https://crobi.github.io/dnd5e-quickref/preview/quickref.html)
|
Im generellen belege ich alles auf dem Basisregelwerk, welches hier schnell eingesehen werden kann; [Crobis quickref](https://crobi.github.io/dnd5e-quickref/preview/quickref.html)
|
||||||
|
|
||||||
Ich versuche mich daran zu halten, diese Regelungen so gut wie möglich ein zu halten.
|
|
||||||
|
|
||||||
## Regelablauf
|
## Regelablauf
|
||||||
Der GM geht von fairem verhalten der Spieler aus.
|
Der GM geht von fairem verhalten der Spieler aus. Spieler sind eigenständig dafür verantwortlich die Regeln zu ihren Charactern zu kennen.
|
||||||
Ich erlaube ebenfalls leichte Regelverbiegungen. Diese sind aber meist einmalig
|
|
||||||
|
Da mein Wissen nicht mehr auf dem neusten Stand ist, lass ich mich gerne belehren.
|
||||||
|
|
||||||
|
## Geworfen ist gezogen
|
||||||
|
Wer eine Aktion spricht, und seine Würfel dazu sprechen lässt, ist an diese gebunden. No Backsies.
|
||||||
|
*Konsequenzen sind stetig ein Teil der Spannung. Wer sich nicht mit seinem Wurf sicher fühlt, so soll er nicht werfen.*
|
||||||
|
|
||||||
|
## Kenkus
|
||||||
|
Kenkus müssen leider draussen bleiben. Die sind zwar eine geniale Rasse, aber funktionieren nicht fürs Roleplay.
|
||||||
|
|
||||||
## Exhaustion
|
## Exhaustion
|
||||||
|
|
||||||
### Orte mit Exhaustion
|
### Orte mit Exhaustion
|
||||||
Es gibt spezifische Orte an welchen die Exhaustion stärker ausschlägt. Die Rede dabei ist von Extrem Gebieten wie beispielsweise eine Wüste, in welcher es über die Dauer der Nacht trotzdem zu einer extremen Kälte kommen kann. Jeh nach ausrüstung kann dann trotzdem eine Exhaustion getriggert werden. Informationen zum richtigen ausharren in den jeweiligen Wildgebieten können von den Einheimischen eingeholt werden.
|
Es gibt spezifische Orte an welchen die Exhaustion stärker ausschlägt. Die Rede dabei ist von Extrem Gebieten wie beispielsweise eine Wüste, in welcher es über die Dauer der Nacht trotzdem zu einer extremen Kälte kommen kann. Jeh nach ausrüstung kann dann trotzdem eine Exhaustion getriggert werden. Informationen zum richtigen ausharren in den jeweiligen Wildgebieten können von den Einheimischen eingeholt werden.
|
||||||
|
|
||||||
|
### [[#Wiederauferstehung]]
|
||||||
|
|
||||||
## Pistolen
|
## Pistolen
|
||||||
Misfire kann immernoch gleich triggern wie immer. ABER wenn man sich mit einer Waffe Attuned (Durch Waffentraining für einen Tag) so kann man den Misfire stat ignorieren
|
Misfire kann immernoch gleich triggern wie immer. ABER wenn man sich mit einer Waffe Attuned (Durch Waffentraining für einen Tag) so kann man den Misfire stat ignorieren
|
||||||
|
|
||||||
## Death Saves
|
## Bewegung
|
||||||
|
Im PHB (Englisch), Seite. 190. Steht, dass das Überqueren einer Kreatur jeweils difficult terrain ist. Auch können nicht-hostile Plätze automatisch (ohne fragen) überquert werden. Dies kann vom Spieler, der gerade "überquert" wird aber mit einer Reaction abgefangen werden, solange noch keine Würfel Aktion durchgeführt wurde.
|
||||||
Jegliche Abilities welche die “Save Checks” manipulieren funktionieren auch in den Death Saves. Death Saves sind privat an den GM zu rollen, weder der Spieler, noch die Truppe wissen dann, welches Unheil den Spieler erwarten. (Und nicht Linsen bei dem Character Sheet ^^)
|
|
||||||
|
|
||||||
## Weniger bekannte Möglichkeiten
|
## Weniger bekannte Möglichkeiten
|
||||||
|
|
||||||
### Bewegung
|
|
||||||
Im PHB (Englisch), Seite. 190. Steht, dass das Überqueren einer Kreatur jeweils difficult terrain ist. Auch können nicht-hostile Plätze automatisch (ohne fragen) überquert werden. Dies kann vom Spieler, der gerade "überquert" wird aber mit einer Reaction abgefangen werden, solange noch keine Würfel Aktion durchgeführt wurde.
|
|
||||||
|
|
||||||
### Zauberklassen (Hinweis)
|
### Zauberklassen (Hinweis)
|
||||||
Ihr könnt eure Spells auch mit einer Ready Action benutzen! Das benötigt aber Concentration und der Spell darf maximal eine Casting Time von einer Action haben.
|
Ihr könnt eure Spells auch mit einer Ready Action benutzen! Das benötigt aber Concentration und der Spell darf maximal eine Casting Time von einer Action haben.
|
||||||
|
|
||||||
### Death Saves (Hinweis)
|
### Death Saves (Hinweis)
|
||||||
Wird man in den Death Saves angegriffen, so wird mit Advantage angegriffen. Treffer addieren einen negativen Punkt zum death save.
|
Wird man in den Death Saves angegriffen, so wird mit Advantage angegriffen. Treffer addieren einen negativen Punkt zum death save.
|
||||||
|
|
||||||
## Hausregeln
|
## Hausregeln - WIP
|
||||||
| Nr. | Name | Beschreibung |
|
| Nr. | Name | Beschreibung |
|
||||||
|:---:|:-----------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:---:|:---------------------- |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 1 | Kenkus | Kenkus müssen leider draussen bleiben. Die sind zwar eine geniale Rasse, aber funktionieren nicht fürs Roleplay. |
|
|
||||||
| 2 | Rassen | Im generellen gehe ich von den 9 Standard 5E Rassen aus, ohne Zusatzinhalt. Man kann mich gerne daran überzeugen, dass diese Rasse unbedingt genommen werden muss, weil sie “oh doch so perfekt zu dem Charakter passen”. (Standardmässig, mach einfach einen anderen.) Ebenfalls dürfen keine Rassen genommen werden, welche fliegen können. Ich erlaube aber [diese Klasse](https://homebrewery.naturalcrit.com/share/Hyj68ZHhM), weil sie toll ist. Begründung: Da dies ein komplettes BUCH wird als DND, wird es schwierig für alle Klassen eine spassige Inszenierung darzustellen. Ich gehe von einer Party of 4 aus. Das bedeutet, dass ich von einem Fighter, einem Barbarian, einem Druid und einem Rogue. Alle haben einen +1 Modifier auf allen Ability Scores. |
|
| 2 | Rassen | Im generellen gehe ich von den 9 Standard 5E Rassen aus, ohne Zusatzinhalt. Man kann mich gerne daran überzeugen, dass diese Rasse unbedingt genommen werden muss, weil sie “oh doch so perfekt zu dem Charakter passen”. (Standardmässig, mach einfach einen anderen.) Ebenfalls dürfen keine Rassen genommen werden, welche fliegen können. Ich erlaube aber [diese Klasse](https://homebrewery.naturalcrit.com/share/Hyj68ZHhM), weil sie toll ist. Begründung: Da dies ein komplettes BUCH wird als DND, wird es schwierig für alle Klassen eine spassige Inszenierung darzustellen. Ich gehe von einer Party of 4 aus. Das bedeutet, dass ich von einem Fighter, einem Barbarian, einem Druid und einem Rogue. Alle haben einen +1 Modifier auf allen Ability Scores. |
|
||||||
| 3 | Party splitting | Es kann durchaus mal vorkommen, dass die Party gesplittet wird. Das ist unabdingbar, aber nervig. Bitte habt geduld mit der subparty oder nutzt das Modul "Walkie Talkie". Ich werde noch darauf eingehen, wie das genutzt wird. |
|
| 3 | Party splitting | Es kann durchaus mal vorkommen, dass die Party gesplittet wird. Das ist unabdingbar, aber nervig. Bitte habt geduld mit der subparty oder nutzt das Modul "Walkie Talkie". Ich werde noch darauf eingehen, wie das genutzt wird. |
|
||||||
| 4 | Der GM hat immer Recht | Und sollte er mal nicht recht haben, so ist das dem GM egal. (Ich hatte die Ehre, ihn selbst zu fragen!) Scherz beiseite, WENN mal irgendwas nicht stimmt, so bitte ich euch den Regelbruch oder was auch immer aufzuschreiben und am ENDE der Runde beizutragen. Ich kenn bedauerlicherweise nicht das ganze Regelwerk auswendig. |
|
| 4 | Der GM hat immer Recht | Und sollte er mal nicht recht haben, so ist das dem GM egal. (Ich hatte die Ehre, ihn selbst zu fragen!) Scherz beiseite, WENN mal irgendwas nicht stimmt, so bitte ich euch den Regelbruch oder was auch immer aufzuschreiben und am ENDE der Runde beizutragen. Ich kenn bedauerlicherweise nicht das ganze Regelwerk auswendig. |
|
||||||
| 5 | PC Wechsel | Ich sags schon mal vorab, ihr kommt von dem Hauptort nicht so einfach weg in ein anderes Land. Wenn ihr euren PC aufgebt und ihn “Cool in den Sonnenuntergang reiten” lässt, sodass ihr einen neuen Character erstellen könnt, so wird dieser den Fluch der unendlich fallenden Steine erleiden (50d100 stupidity damage, dagegen könnt ihr nicht mal resistent sein!) |
|
| 5 | PC Wechsel | Ich sags schon mal vorab, ihr kommt von dem Hauptort nicht so einfach weg in ein anderes Land. Wenn ihr euren PC aufgebt und ihn “Cool in den Sonnenuntergang reiten” lässt, sodass ihr einen neuen Character erstellen könnt, so wird dieser den Fluch der unendlich fallenden Steine erleiden (50d100 stupidity damage, dagegen könnt ihr nicht mal resistent sein!) |
|
||||||
| 6 | Charakter erstellung | Bei der Charaktererstellung gibt es für euch die Möglichkeit, stärker zu sein, als sonst! Es gilt folgendes Vorgehen: Es werde 4 Monopoly Würfel gewürfelt JEDER Würfel, welcher eine 1 zeigt, kann neu geworfen werden. Jetzt entfernt man den niedrigsten Würfel Nun rechnet man alles zusammen |
|
| 6 | Charakter erstellung | Bei der Charaktererstellung gibt es für euch die Möglichkeit, stärker zu sein, als sonst! Es gilt folgendes Vorgehen: Es werde 4 Monopoly Würfel gewürfelt JEDER Würfel, welcher eine 1 zeigt, kann neu geworfen werden. Jetzt entfernt man den niedrigsten Würfel Nun rechnet man alles zusammen |
|
||||||
| 7 | Inspiration | Ihr werdet über die Sessions hinweg inspiriert, jedoch funktioniert die Inspiration nicht einfach als Notlösung, wenn ihr mal eine 1 gewürfelt habt. Benutzt ihr eure Inspiration, so wird der gewünschte Wurf, auf welchen ihr Inspiration verwendet automatisch eine NAT 20. Dies geht NICHT bei death saves, dort kann nur der misslungene Wurf neu gerollt werden. |
|
| 7 | Inspiration | Ihr werdet über die Sessions hinweg inspiriert, jedoch funktioniert die Inspiration nicht einfach als Notlösung, wenn ihr mal eine 1 gewürfelt habt. Benutzt ihr eure Inspiration, so wird der gewünschte Wurf, auf welchen ihr Inspiration verwendet automatisch eine NAT 20. Dies geht NICHT bei death saves, dort kann nur der misslungene Wurf neu gerollt werden. |
|
||||||
| 8 | Spelländerungen | Wenn Ihr eure Spells für eure Klasse Ändern wollt, so ist das JEDERZEIT möglich, sofern Ihr euch für einen halben Tag in einer euch Nahen “Bildungseinrichtung” sitzt. Das “Umlernen” benötigt concentration. Folgende Möglichkeiten sind akzeptabel: Artificer -> Schmiede Bard -> Taverne Cleric -> Kirche Druid -> Beim Trankhändler Paladin -> In den Trainingshallen Ranger -> Im Wald Sorcerer -> Warlock -> Irgendwo, wo sie mit ihrem Dämonen alleine sind. Wizard -> Bibliotheke |
|
| 8 | Spelländerungen | Wenn Ihr eure Spells für eure Klasse Ändern wollt, so ist das JEDERZEIT möglich, sofern Ihr euch für einen halben Tag in einer euch Nahen “Bildungseinrichtung” sitzt. Das “Umlernen” benötigt concentration. Folgende Möglichkeiten sind akzeptabel: Artificer -> Schmiede Bard -> Taverne Cleric -> Kirche Druid -> Beim Trankhändler Paladin -> In den Trainingshallen Ranger -> Im Wald Sorcerer -> Warlock -> Irgendwo, wo sie mit ihrem Dämonen alleine sind. Wizard -> Bibliotheke |
|
||||||
|
|
||||||
|
# Test-Regeln
|
||||||
|
Regeln, welche ich einführe, zum Testen von spiel Stilen. Rückmeldung erwünscht!
|
||||||
|
|
||||||
|
Es kann sein, dass diese wegfallen oder geändert werden!
|
||||||
|
|
||||||
|
## Die "Lach" Regel.
|
||||||
|
Macht ihr im RP irgendwas, was den DM zum Lachen bringt, so wird dies auch geschehen, mit gewissem Masse, natürlich.
|
||||||
|
|
||||||
|
*Dies soll das RP ein wenig auflockern und Fantasie wird öfters verwendet*
|
||||||
|
|
||||||
|
## Der Gratis Sucess pro Session
|
||||||
|
Jede Session beginnt damit, dass jeder Spieler einen gratis "Sucess" bekommt. Dies gilt für Saves, Death Saves und Checks. Der Gratis Sucess muss VOR dem Wurf ausgesprochen werden, ansonsten zählt [[#Geworfen ist gezogen]]
|
||||||
|
|
||||||
|
*Dies gibt den Charactern eine möglichkeit sich in der Session einzfügen*
|
||||||
|
|
||||||
|
## Offene DM Rolls
|
||||||
|
DM Rolls werden per-se offen gerollt. Ausnahme dafür sind Rolls, welche in die Zukunft gerollt werden, um das Gameplay zu beschleunigen. (Beispielsweise Random Encounter oder Schaden von Fallen.)
|
||||||
|
|
||||||
|
## Flanking
|
||||||
|
Flankieren gibts nid. Okay... zumindest nicht auf der Herkömmlichen Variante.
|
||||||
|
|
||||||
|
Advantage wird nur gegeben, sofern 3 Personen in einem 5 Ft. Radius um einen Gegner stehen.
|
||||||
|
|
||||||
|
## Wiederauferstehung
|
||||||
|
Okay, das benötigt eine kurze Erklärung.
|
||||||
|
|
||||||
|
Fällt man auf 0 HP, so gibt es keine Konsequenz, einfach wieder 5 HP vom nächsten Druiden zu erhalten. Diese können natürlich genau so schnell wieder heraus gehauen werden.
|
||||||
|
|
||||||
|
Meine Lösung: Für jedes mal, wenn man aus den Deathsaves zurück kommt, erhällt man 1 Exhaustion. Brutal? Möglich, aber dafür geht ja 1x Exhaustion wieder weg, wenn man geschlafen hat.
|
||||||
|
|
||||||
|
## Death Saves
|
||||||
|
Jegliche Abilities welche die “Save Checks” manipulieren funktionieren auch in den Death Saves. Death Saves sind privat an den GM zu rollen, weder der Spieler, noch die Truppe wissen dann, welches Unheil den Spieler erwarten. (Und nicht Linsen bei dem Character Sheet ^^)
|
||||||
|
|
||||||
|
Während den Deathsaves kann man jeweils noch 5ft "kriechen" und reden. Aktionen, Reaktionen und Bonusaktionen werden
|
@ -2,3 +2,4 @@
|
|||||||
- [ ] Teleporter
|
- [ ] Teleporter
|
||||||
- [ ] Encounters
|
- [ ] Encounters
|
||||||
- [ ] Maps
|
- [ ] Maps
|
||||||
|
- [ ] Rules
|
Loading…
Reference in New Issue
Block a user