This commit is contained in:
2025-07-28 14:57:27 +02:00
parent 48eb799861
commit 6ab0cab5a0
18 changed files with 437 additions and 34 deletions

0
lang/en.json Normal file
View File

View File

@@ -0,0 +1,7 @@
// main: ./pokemon.less
.pokemon.sheet.charactersheet {
.sheet {
width: 500px;
height: 500px;
};
}

2
less/pokemon.less Normal file
View File

@@ -0,0 +1,2 @@
// relativeUrls: true, out: ../pokemon.css
@import "./character-sheet.less";

5
modules/config.js Normal file
View File

@@ -0,0 +1,5 @@
export const POKEMON = {};
POKEMON.attributes = {
Test: "TEST!"
}

0
modules/dialog.js Normal file
View File

0
modules/dice.js Normal file
View File

View File

View File

@@ -0,0 +1,34 @@
export default class pokemonActor extends Actor {
preparedata() {
// In case some steps need to be overwritten later
super.preparedata();
}
prepareDerivedData() {
const actorData = this.system;
this._preparePlayerCharacterData(actorData);
}
_preparePlayerCharacterData(actorData) {
this._setCharacterValues(actorData);
}
async _setCharacterValues(data) {
// Calculations of values here
}
setNote(note) {
this.update({"system.note ": note});
}
addLogEntry(entry) {
// Add a log entry to the character event log
let log = this.system.log;
log.push(entry);
this.update({"system.log": log})
}
}

View File

@@ -1,5 +0,0 @@
export default class PokemonItemSheet extends foundry.appv1.sheets.ItemSheet {
get template() {
return `systems/pokemon/templates/sheets/${this.item.type}-sheet.html`
}
}

View File

@@ -0,0 +1,80 @@
const api = foundry.applications.api;
const sheets = foundry.applications.sheets;
export default class pokemonCharacterSheet extends api.HandlebarApplicationMixin(sheets.ActorSheetV2) {
sheetContext = {};
static DEFAULT_OPTIONS = {
tag: "form",
classes: ["pokemon", "sheet", "characterSheet"],
actions: {
},
form: {
submitOnChange: true,
closeOnSubmit: false
},
position: {
width: 650
}
}
static PARTS = {
header: { template: "systems/pokemon/templates/sheets/character/header.hbs" },
sidebar: { template: "systems/pokemon/templates/sheets/character/sidebar.hbs" }
}
get title() {
return this.actor.name;
}
/** @override */
_configureRenderOptions(options) {
super._configureRenderOptions(options);
if (this.document.limited) options.parts = ["header"]
else options.parts = ["header", "sidebar"];
}
/** @override */
async _prepareContext(options) {
// #################################################################################################
// #################################################################################################
// ## ##
// ## Creates Basic Datamodel, which is used to fill the HTML together with Handelbars with Data. ##
// ## ##
// #################################################################################################
// #################################################################################################
const baseData = await super._prepareContext();
let context = {
// Set General Values
owner: baseData.document.isOwner,
editable: baseData.editable,
actor: baseData.document,
system: baseData.document.system,
items: baseData.document.items,
config: CONFIG.POKEMON,
isGM: baseData.user.isGM,
effects: baseData.document.effects
};
this.sheetContext = context;
return context;
}
/** @override */
_onRender(context, options) {
const tabs = new foundry.applications.ux.Tabs({navSelector: ".tabs", contentSelector: ".content", initial: "tab1"});
tabs.bind(this.element);
const tabs2 = new foundry.applications.ux.Tabs({navSelector: ".tabs2", contentSelector: ".content2", initial: "tab2-1"});
tabs2.bind(this.element);
}
}

0
modules/utils.js Normal file
View File

4
pokemon.css Normal file
View File

@@ -0,0 +1,4 @@
.pokemon.sheet.charactersheet .sheet {
width: 500px;
height: 500px;
}

View File

@@ -1,8 +1,103 @@
import PokemonItemSheet from "./modules/sheets/PokemonItemSheet.js";
import { POKEMON } from "./modules/config.js";
import pokemonActor from "./modules/objects/pokemonActor.js";
import pokemonCharacterSheet from "./modules/sheets/pokemonCharacterSheet.js";
Hooks.once("init", function() {
console.log("pokemon | Initializing the Pokémon system");
Hooks.once("init", async () => {
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
foundry.documents.collections.Items.registerSheet("pokemon", PokemonItemSheet, { makeDefault: true });
console.log("POKEMON | Initalizing Pokémon System");
// Setting up the Global Configuration Object
CONFIG.POKEMON = POKEMON;
CONFIG.INIT = true;
CONFIG.Actor.documentClass = pokemonActor;
// Register custom Sheets and unregister the start Sheets
// Items.unregisterSheet("core", ItemSheet);
const DocumentSheetConfig = foundry.applications.apps.DocumentSheetConfig;
DocumentSheetConfig.unregisterSheet(Actor, "core", foundry.appv1.sheets.ActorSheet);
DocumentSheetConfig.registerSheet(Actor, "pokemon", pokemonCharacterSheet, {
types: ["character"],
makeDefault: true,
label: "POKEMON.SheetClassCharacter"
})
// Load all Partial-Handlebar Files
preloadHandlebarsTemplates();
// Register Additional Handelbar Helpers
registerHandlebarsHelpers();
});
Hooks.once("ready", async () => {
// Finished Initalization Phase and release lock
CONFIG.INIT = false;
// Only execute when run as Gamemaster
if(!game.user.isGM) return;
});
function preloadHandlebarsTemplates() {
const templatePaths = [
"systems/pokemon/templates/partials/character-sheet-character.hbs",
"systems/pokemon/templates/partials/character-sheet-background.hbs",
"systems/pokemon/templates/partials/character-sheet-moves.hbs"
];
return foundry.applications.handlebars.loadTemplates(templatePaths);
};
function registerHandlebarsHelpers() {
Handlebars.registerHelper("equals", function(v1, v2) { return (v1 === v2)});
Handlebars.registerHelper("contains", function(element, search) { return (element.includes(search))});
Handlebars.registerHelper("concat", function(s1, s2, s3 = "") { return s1 + s2 + s3;});
Handlebars.registerHelper("isGreater", function(p1, p2) { return (p1 > p2)});
Handlebars.registerHelper("isEqualORGreater", function(p1, p2) { return (p1 >= p2)});
Handlebars.registerHelper("ifOR", function(conditional1, conditional2) { return (conditional1 || conditional2)});
Handlebars.registerHelper("doLog", function(value) { console.log(value)});
Handlebars.registerHelper("toBoolean", function(string) { return (string === "true")});
Handlebars.registerHelper('for', function(from, to, incr, content) {
let result = "";
for(let i = from; i < to; i += incr)
result += content.fn(i);
return result;
});
Handlebars.registerHelper("times", function(n, content) {
let result = "";
for(let i = 0; i < n; i++)
result += content.fn(i);
return result;
});
Handlebars.registerHelper("notEmpty", function(value) {
if (value == 0 || value == "0") return true;
if (value == null|| value == "") return false;
return true;
});
}
/* -------------------------------------------- */
/* General Functions */
/* -------------------------------------------- */

View File

@@ -1,5 +1,5 @@
{
"version": "0.0.7",
"version": "0.0.8",
"id": "pokemon",
"title": "Pokémon TTRPG",
"description": "A Pokémon TTRPG",
@@ -19,11 +19,23 @@
"esmodules": [
"pokemon.js"
],
"styles": [],
"styles": [
"pokemon.css"
],
"packs": [],
"languages": [],
"languages": [
{
"lang": "en",
"name": "English",
"path": "lang/en.json"
}
],
"socket": false,
"url": "https://git.ingemanngade.net/NikolajDanger/pokemon-foundry/raw/branch/main/",
"grid": {
"distance": 5,
"units": "ft"
},
"url": "https://git.ingemanngade.net/NikolajDanger/pokemon-foundry/",
"manifest": "https://git.ingemanngade.net/NikolajDanger/pokemon-foundry/raw/branch/main/system.json",
"download": "https://git.ingemanngade.net/NikolajDanger/pokemon-foundry/raw/branch/main/system.zip"
}

View File

@@ -1,16 +1,86 @@
{
"Actor": {},
"Item": {
"types": ["item"],
"templates": {
"base": {
"description": ""
}
"Actor": {
"types": [
"character"
],
"character": {
"species": "",
"experience": {
"level": 1,
"EXP": 0
},
"armor class": 0,
"stats": {
"attack": {
"value": 0,
"modifier": 0
},
"defense": {
"value": 0,
"modifier": 0
},
"move": {
"value": 0,
"modifier": 0
},
"hp": {
"value": 0,
"modifier": 0
}
},
"speed": 0,
"hp": {
"max": 0,
"current": 0
},
"moves": {
"move 1": {
"category": 0,
"type": 0,
"description": ""
},
"move 2": {
"category": 0,
"type": 0,
"description": ""
},
"move 3": {
"category": 0,
"type": 0,
"description": ""
},
"move 4": {
"category": 0,
"type": 0,
"description": ""
}
}
}
},
"item": {
"templates": ["base"],
"quantity": 1,
"weight": 0
"Item": {
"types":[
"Item"
],
"templates": {
"generalItems": {
"weight": 10,
"value": 100,
"description": ""
}
},
"Item": {
"templates": ["generalItems"],
"type": "item",
"quantity": 1
}
}
}
}

View File

@@ -0,0 +1,17 @@
<div class="headerBox">
{{!-- <div class="logoBox">
<div class="logoImg"><div class="logoText">{{localize "POKEMON.SystemName"}}</div></div>
</div> --}}
<div class="charInfoBox">
<input class="bigInputText" type="text" name="name" value="{{actor.name}}">
<div class="lvlBox">
<div class="lvlLabel">{{localize "POKEMON.System.LevelShort"}}</div>
<div class="lvlValue">{{system.experience.level}}</div>
</div>
<div class="expBox">
<div class="expValue">{{system.experience.EXP}} EXP</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,89 @@
<div>
<div class="sideBarBox">
<div class="imgBox">
<img class="charImg" src="{{actor.img}}" data-edit="img" data-action="editImage" title="{{actor.name}}" >
<div class="imgOverlay">
<div class="charHex charHPCurrent"><span class="charHexHead">HP</span></br><span class="charHexValue">{{system.hp.current}}</span></div>
<div class="charHex charHPMax"><span class="charHexHead">Max</span></br><span class="charHexValue">{{system.hp.max}}</span></div>
</div>
<div class="charHex"><span class="charHexHead">{{localize "POKEMON.System.Attack"}}</span></br><span class="charHexValue">{{system.stats}}</span></div>
</div>
<div class="menuBox">
<div class="menuBG"></div>
<div class="menuLbl"></div>
<nav class="tabs menuTabs" data-group="primary-tabs">
<div class="menuIcon" style="left: 135px;">
<a class="item" data-tab="tab1" data-group="primary-tabs">
<i class="fa-solid fa-book-open-cover"></i>
</a>
</div>
<div class="menuIcon" style="left: 180px;">
<a class="item" data-tab="tab2" data-group="primary-tabs">
<i class="fa-solid fa-book"></i>
</a>
</div>
<div class="menuIcon" style="left: 225px;">
<a class="item" data-tab="tab3" data-group="primary-tabs">
<i class="fa-regular fa-stars"></i>
</a>
</div>
<div class="menuIcon" style="left: 270px;">
<a class="item" data-tab="tab4" data-group="primary-tabs">
<i class="fa-solid fa-swords"></i>
</a>
</div>
<div class="menuIcon" style="left: 315px;">
<a class="item" data-tab="tab5" data-group="primary-tabs">
<i class="fa-solid fa-aperture"></i>
</a>
</div>
<div class="menuIcon" style="left: 360px;">
<a class="item" data-tab="tab6" data-group="primary-tabs">
<i class="fa-solid fa-bezier-curve"></i>
</a>
</div>
<div class="menuSetup" style="left: 405px;">
<a class="item" data-tab="tab7" data-group="primary-tabs">
<i class="fa-solid fa-ellipsis-vertical"></i>
</a>
</div>
</nav>
</div>
<div class="contentBox">
<section class="content">
<div class="tab" data-tab="tab1" data-group="primary-tabs">
{{> "systems/nether/templates/partials/character-sheet-character.hbs"}}
</div>
<div class="tab" data-tab="tab2" data-group="primary-tabs">
{{> "systems/nether/templates/partials/character-sheet-background.hbs"}}
</div>
<div class="tab" data-tab="tab3" data-group="primary-tabs">
{{> "systems/nether/templates/partials/character-sheet-skill.hbs"}}
</div>
<div class="tab" data-tab="tab4" data-group="primary-tabs">
{{> "systems/nether/templates/partials/character-sheet-combat.hbs"}}
</div>
<div class="tab" data-tab="tab5" data-group="primary-tabs">
{{> "systems/nether/templates/partials/character-sheet-progression.hbs"}}
</div>
<div class="tab" data-tab="tab6" data-group="primary-tabs">
Pfade
</div>
<div class="tab" data-tab="tab7" data-group="primary-tabs">
Settings
</div>
</section>
</div>
</div>

View File

@@ -1,7 +0,0 @@
<form class="{{cssClass}}" autocomplete="off">
<header class="sheet-header">
<img src="{{item.img}}" data-edit="img" title="{{item.name}}" height="64" width="64"/>
<h1><input name="name" type="text" value="{{item.name}}" placeholder="Name"/></h1>
</header>
<p>HELLO TEST</p>
</form>