implements lootable creatures
parent
2da34b6af3
commit
a57cf98aa1
|
|
@ -50,6 +50,7 @@ const convert = function (from, to, ofType, overwrite = true) {
|
|||
if (statSync(join(source, file)).isDirectory()) {
|
||||
filewalker(join(source, file));
|
||||
} else {
|
||||
console.debug("processing file", join(source, file))
|
||||
let originalSource = JSON.parse(readFileSync(join(source, file), {encoding: "utf8"}));
|
||||
let id = randomID();
|
||||
|
||||
|
|
|
|||
70
src/main.mjs
70
src/main.mjs
|
|
@ -88,6 +88,76 @@ Hooks.once("init", () => {
|
|||
decimals: 0
|
||||
}
|
||||
|
||||
const setMovementSpeeds = () => {
|
||||
const movementActions = CONFIG.Token.movement.actions
|
||||
|
||||
for (const key of ["swim", "climb", "crawl", "walk", "drive", "ride", "fly"]) {
|
||||
delete movementActions[key]?.getCostFunction
|
||||
}
|
||||
|
||||
movementActions.climb.canSelect = (token) => {
|
||||
const actor = token.actor | null;
|
||||
console.log
|
||||
return (actor.type === "Character" && actor.system.itemTypes["Skill"].find(p => p.name === "Klettern")?.system.taw > 0) || actor.type === "Creature"
|
||||
}
|
||||
|
||||
movementActions.crawl.canSelect = (token) => {
|
||||
const actor = token.actor | null;
|
||||
return actor.type === "Character" || actor.type === "Creature"
|
||||
}
|
||||
|
||||
movementActions.walk.canSelect = (token) => {
|
||||
const actor = token.actor | null;
|
||||
return actor.type === "Character" || actor.type === "Creature"
|
||||
}
|
||||
|
||||
movementActions.swim = {
|
||||
label: "TOKEN.MOVEMENT.ACTIONS.swim.label",
|
||||
icon: "fa-solid fa-swim",
|
||||
order: 0,
|
||||
canSelect: (token) => {
|
||||
const actor = token.actor | null;
|
||||
return actor.type === "Character" || actor.type === "Creature"
|
||||
},
|
||||
deriveTerrainDifficulty: () => 1,
|
||||
}
|
||||
|
||||
movementActions.drive = {
|
||||
label: "TOKEN.MOVEMENT.ACTIONS.drive.label",
|
||||
icon: "fa-solid fa-car-side",
|
||||
order: 0,
|
||||
canSelect: (token) => {
|
||||
const actor = token.actor | null;
|
||||
return (actor.type === "Character" && actor.system.itemTypes["Skill"].find(p => p.name === "Fahrzeuge lenken")?.system.taw > 0) || actor.type === "Creature"
|
||||
},
|
||||
deriveTerrainDifficulty: () => 1,
|
||||
}
|
||||
|
||||
movementActions.ride = {
|
||||
label: "TOKEN.MOVEMENT.ACTIONS.ride.label",
|
||||
icon: "fa-solid fa-horse",
|
||||
order: 0,
|
||||
canSelect: (token) => {
|
||||
const actor = token.actor | null;
|
||||
return (actor.type === "Character" && actor.system.itemTypes["Skill"].find(p => p.name === "Reiten")?.system.taw > 0) || actor.type === "Creature"
|
||||
},
|
||||
deriveTerrainDifficulty: () => 1,
|
||||
}
|
||||
|
||||
movementActions.fly = {
|
||||
label: "TOKEN.MOVEMENT.ACTIONS.fly.label",
|
||||
icon: "fa-solid fa-wings",
|
||||
order: 0,
|
||||
canSelect: (token) => {
|
||||
const actor = token.actor | null;
|
||||
return (actor.type === "Character" && actor.system.itemTypes["Skill"].find(p => p.name === "Fliegen")?.system.taw > 0) || actor.type === "Creature"
|
||||
},
|
||||
deriveTerrainDifficulty: () => 1,
|
||||
}
|
||||
|
||||
}
|
||||
setMovementSpeeds()
|
||||
|
||||
console.log("DSA 4.1 is ready for development!")
|
||||
|
||||
foundry.documents.collections.Actors.registerSheet('dsa41.character', CharacterSheet, {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {
|
||||
SchemaField, NumberField, StringField, HTMLField, ArrayField
|
||||
SchemaField, BooleanField, NumberField, StringField, HTMLField, ArrayField
|
||||
} = foundry.data.fields;
|
||||
|
||||
export class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
|
@ -24,7 +24,13 @@ export class CreatureDataModel extends foundry.abstract.TypeDataModel {
|
|||
tp: new StringField(),
|
||||
name: new StringField(),
|
||||
}), {min: 0}),
|
||||
description: new HTMLField()
|
||||
description: new HTMLField(),
|
||||
visibility: new SchemaField({
|
||||
meta: new BooleanField(),
|
||||
attacks: new BooleanField(),
|
||||
description: new BooleanField(),
|
||||
loot: new BooleanField(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,19 +220,19 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
}
|
||||
|
||||
|
||||
_getTabsConfig(group) {
|
||||
const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
|
||||
Meta._getTabConfig(tabs, this);
|
||||
Social._getTabConfig(tabs, this);
|
||||
Advsf._getTabConfig(tabs, this)
|
||||
Combat._getTabConfig(tabs, this)
|
||||
Equipment._getTabConfig(tabs, this)
|
||||
Skills._getTabConfig(tabs, this)
|
||||
Spells._getTabConfig(tabs, this)
|
||||
Liturgies._getTabConfig(tabs, this)
|
||||
Effects._getTabConfig(tabs, this)
|
||||
return tabs
|
||||
}
|
||||
_getTabsConfig(group) {
|
||||
const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
|
||||
Meta._getTabConfig(tabs, this);
|
||||
Social._getTabConfig(tabs, this);
|
||||
Advsf._getTabConfig(tabs, this)
|
||||
Combat._getTabConfig(tabs, this)
|
||||
Equipment._getTabConfig(tabs, this)
|
||||
Skills._getTabConfig(tabs, this)
|
||||
Spells._getTabConfig(tabs, this)
|
||||
Liturgies._getTabConfig(tabs, this)
|
||||
Effects._getTabConfig(tabs, this)
|
||||
return tabs
|
||||
}
|
||||
|
||||
async _preparePartContext(partId, context) {
|
||||
switch (partId) {
|
||||
|
|
@ -494,8 +494,10 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
async _onDrop(event) {
|
||||
const data = TextEditor.implementation.getDragEventData(event);
|
||||
const actor = this.actor;
|
||||
const allowed = Hooks.call("dropActorSheetData", actor, this, data);
|
||||
if (allowed === false) return;
|
||||
//const allowed = Hooks.call("dropActorSheetData", actor, this, data);
|
||||
//if (allowed === false) return;
|
||||
|
||||
console.log("looted or dropped", data)
|
||||
|
||||
// Dropped Documents
|
||||
const documentClass = foundry.utils.getDocumentClass(data.type);
|
||||
|
|
|
|||
|
|
@ -24,11 +24,7 @@ export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
|
||||
static TABS = {
|
||||
sheet: {
|
||||
tabs: [
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
{id: 'attacks', group: 'sheet', label: 'Attacken'},
|
||||
{id: 'description', group: 'sheet', label: 'Beschreibung'},
|
||||
],
|
||||
tabs: [],
|
||||
initial: 'meta'
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +42,31 @@ export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
},
|
||||
description: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-description.hbs`
|
||||
},
|
||||
loot: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-loot.hbs`
|
||||
},
|
||||
visibility: {
|
||||
template: `systems/DSA_4-1/templates/actor/creature/tab-visibility.hbs`
|
||||
},
|
||||
}
|
||||
|
||||
_getTabsConfig(group) {
|
||||
const tabs = foundry.utils.deepClone(super._getTabsConfig(group))
|
||||
const tabDef = [
|
||||
{id: 'meta', group: 'sheet', label: 'Meta'},
|
||||
{id: 'attacks', group: 'sheet', label: 'Attacken'},
|
||||
{id: 'description', group: 'sheet', label: 'Beschreibung'},
|
||||
{id: 'loot', group: 'sheet', label: 'Loot'},
|
||||
{id: 'visibility', group: 'sheet', label: 'Sichtbarkeit'},
|
||||
]
|
||||
|
||||
for (const tab of tabDef) {
|
||||
if (game.user.isGM || this.document.system.visibility[tab.id]) {
|
||||
tabs.tabs.push(tab)
|
||||
}
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,7 +145,74 @@ export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
})
|
||||
})
|
||||
|
||||
context.metaRevealed = actorData.system.visibility.meta
|
||||
context.attacksRevealed = actorData.system.visibility.attacks
|
||||
context.descriptionRevealed = actorData.system.visibility.description
|
||||
context.lootRevealed = actorData.system.visibility.loot
|
||||
context.inventoryItems = []
|
||||
|
||||
actorData.items.forEach((item, index) => {
|
||||
if (item.type === "Equipment") {
|
||||
context.inventoryItems.push({
|
||||
index: index,
|
||||
id: item._id,
|
||||
quantity: item.system.quantity,
|
||||
name: item.name,
|
||||
icon: item.img
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
_canDragDrop(event, options) {
|
||||
return game.user.isGM
|
||||
}
|
||||
|
||||
_canDrag(event, options) {
|
||||
return true
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
|
||||
const data = TextEditor.implementation.getDragEventData(event);
|
||||
const actor = this.actor;
|
||||
//const allowed = Hooks.call("dropActorSheetData", actor, this, data);
|
||||
// if (allowed === false) return;
|
||||
console.log("dropped")
|
||||
// Dropped Documents
|
||||
const documentClass = foundry.utils.getDocumentClass(data.type);
|
||||
if (documentClass) {
|
||||
const document = await documentClass.fromDropData(data);
|
||||
|
||||
if (document.type === "Equipment") {
|
||||
// No duplication by moving items from one actor to another
|
||||
if (document.parent && document.parent !== this.actor) {
|
||||
document.parent.items.get(document._id).delete()
|
||||
}
|
||||
|
||||
await this._onDropDocument(event, document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_onRender(context, options) {
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dropSelector: ".window-content",
|
||||
dragSelector: ".equipment",
|
||||
permissions: {
|
||||
drop: this._canDragDrop.bind(this),
|
||||
drag: this._canDrag.bind(this)
|
||||
},
|
||||
callbacks: {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
drop: this._onDrop.bind(this)
|
||||
}
|
||||
}).bind(this.element);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,8 +222,7 @@ export class MerchantSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
}
|
||||
|
||||
_canDragDrop(event, options) {
|
||||
console.log(event, options)
|
||||
return true
|
||||
return game.user.isGM
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
@use "../atoms/assets";
|
||||
|
||||
@mixin equipment {
|
||||
position: relative;
|
||||
height: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 32px 24px 1fr 48px;
|
||||
grid-template-rows: 1fr;
|
||||
padding: 2px 0 0 2px;
|
||||
margin: 4px 0 0 4px;
|
||||
gap: 8px;
|
||||
background: assets.$tab-pane-background;
|
||||
|
||||
.icon {
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.name, .weight {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input.quantity {
|
||||
padding: 0;
|
||||
border: unset;
|
||||
border-radius: 0;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 4px 0;
|
||||
text-align: right;
|
||||
background: unset;
|
||||
box-shadow: unset;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
transition: box-shadow 0.2s, border 0.2s, margin 0.2s, padding 0.2s;
|
||||
|
||||
&:hover {
|
||||
.name {
|
||||
text-shadow: 0 0 10px rgb(255 0 0);
|
||||
}
|
||||
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);
|
||||
margin: -4px 4px 4px -4px;
|
||||
padding: 0 0 0 0;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
@use "../atoms/colours" as colour;
|
||||
@use 'sass:color';
|
||||
@use "../atoms/numbers";
|
||||
@use "../molecules/equipment";
|
||||
|
||||
.dsa41.sheet.actor.creature {
|
||||
|
||||
|
|
@ -163,6 +164,16 @@
|
|||
padding: 16px;
|
||||
}
|
||||
|
||||
.tab.loot {
|
||||
|
||||
div {
|
||||
.equipment {
|
||||
@include equipment.equipment
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@use "../../atoms/assets";
|
||||
@use "../../molecules/equipment";
|
||||
|
||||
@mixin tab {
|
||||
|
||||
|
|
@ -49,56 +50,7 @@
|
|||
flex-direction: column;
|
||||
|
||||
.equipment {
|
||||
position: relative;
|
||||
height: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 32px 24px 1fr 48px;
|
||||
grid-template-rows: 1fr;
|
||||
padding: 2px 0 0 2px;
|
||||
margin: 4px 0 0 4px;
|
||||
gap: 8px;
|
||||
background: assets.$tab-pane-background;
|
||||
|
||||
.icon {
|
||||
width: 32px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.name, .weight {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input.quantity {
|
||||
padding: 0;
|
||||
border: unset;
|
||||
border-radius: 0;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
margin: 4px 0;
|
||||
text-align: right;
|
||||
background: unset;
|
||||
box-shadow: unset;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
transition: box-shadow 0.2s, border 0.2s, margin 0.2s, padding 0.2s;
|
||||
|
||||
&:hover {
|
||||
.name {
|
||||
text-shadow: 0 0 10px rgb(255 0 0);
|
||||
}
|
||||
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5);
|
||||
margin: -4px 4px 4px -4px;
|
||||
padding: 0 0 0 0;
|
||||
z-index: 2;
|
||||
}
|
||||
@include equipment.equipment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
<section class="tab {{tabs.loot.id}} {{tabs.loot.cssClass}}"
|
||||
data-tab="{{tabs.loot.id}}"
|
||||
data-group="{{tabs.loot.group}}">
|
||||
<div>
|
||||
{{> "systems/DSA_4-1/templates/ui/partial-equipment-button.hbs" inventoryItems}}
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<section class="tab {{tabs.visibility.id}} {{tabs.visibility.cssClass}}"
|
||||
data-tab="{{tabs.visibility.id}}"
|
||||
data-group="{{tabs.visibility.group}}">
|
||||
<div>
|
||||
<fieldset>
|
||||
<legend>Folgendes für alle sichtbar machen</legend>
|
||||
|
||||
<label><input type="checkbox" name="system.visibility.meta" {{checked metaRevealed}}/> Meta</label>
|
||||
<label><input type="checkbox" name="system.visibility.attacks" {{checked attacksRevealed}}/>
|
||||
Attacken</label>
|
||||
<label><input type="checkbox" name="system.visibility.description" {{checked descriptionRevealed}}/>
|
||||
Beschreibung</label>
|
||||
<label><input type="checkbox" name="system.visibility.loot" {{checked lootRevealed}}/> Loot</label>
|
||||
<label><input type="checkbox" disabled="disabled"/> Sichtbarkeiten</label>
|
||||
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
Loading…
Reference in New Issue