Foundry v13 migrtion

This commit is contained in:
2025-05-02 18:58:29 +02:00
parent 15e249e41e
commit fef3e44941
80 changed files with 465 additions and 387 deletions

View File

@@ -6,7 +6,7 @@
import { SoSUtility } from "./sos-utility.js";
/* -------------------------------------------- */
export class SoSActorSheet extends ActorSheet {
export class SoSActorSheet extends foundry.appv1.sheets.ActorSheet {
/** @override */
static get defaultOptions() {
@@ -47,14 +47,14 @@ export class SoSActorSheet extends ActorSheet {
formData.edgecard = this.actor.getEdgesCard();
formData.deckSize = this.actor.getDeckSize();
formData.skills = this.actor.items.filter( item => item.type == 'skill').sort( (a, b) => {
formData.skills = this.actor.items.filter( item => item.type == 'skill').sort( (a, b) => {
if ( a.name > b.name ) return 1;
return -1;
});
formData.skill1 = formData.skills.slice(0, Math.ceil(formData.skills.length/2) )
formData.skill2 = formData.skills.slice(Math.ceil(formData.skills.length/2), formData.skills.length )
formData.consequences = this.actor.items.filter( item => item.type == 'consequence').sort( (a, b) => {
formData.consequences = this.actor.items.filter( item => item.type == 'consequence').sort( (a, b) => {
if ( a.name > b.name ) return 1;
return -1;
});
@@ -62,7 +62,7 @@ export class SoSActorSheet extends ActorSheet {
// Build the gear tree
formData.gearsRoot = formData.gears.filter(item => item.system.containerid == "");
for ( let container of formData.gearsRoot) {
for ( let container of formData.gearsRoot) {
if ( container.type == 'container') {
container.system.contains = []
container.system.containerEnc = 0;
@@ -125,7 +125,7 @@ export class SoSActorSheet extends ActorSheet {
const item = this.actor.wornObject( li.data("item-id") );
this.render(true);
});
// Delete Inventory Item
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
@@ -160,7 +160,7 @@ export class SoSActorSheet extends ActorSheet {
let woundName = event.currentTarget.attributes.woundname.value;
//console.log("Competence changed :", skillName);
this.actor.updateWound(woundName, parseInt(event.target.value));
});
});
html.find('.reset-deck-full').click((event) => {
this.actor.resetDeckFull();
this.render(true);
@@ -187,13 +187,13 @@ export class SoSActorSheet extends ActorSheet {
html.find('.lock-unlock-sheet').click((event) => {
this.options.editStatSkill = !this.options.editStatSkill;
this.render(true);
});
});
html.find('.item-link a').click((event) => {
const itemId = $(event.currentTarget).data("item-id");
const item = this.actor.getOwnedItem(itemId);
item.sheet.render(true);
});
});
}
/* -------------------------------------------- */
@@ -203,7 +203,7 @@ export class SoSActorSheet extends ActorSheet {
super._onDrop(event);
}
}
/* -------------------------------------------- */
/** @override */
setPosition(options = {}) {

View File

@@ -14,8 +14,8 @@ export class SoSActor extends Actor {
/**
* Override the create() function to provide additional SoS functionality.
*
* This overrided create() function adds initial items
* Namely: Basic skills, money,
* This overrided create() function adds initial items
* Namely: Basic skills, money,
*
* @param {Object} data Barebones actor data which this function adds onto.
* @param {Object} options (Unused) Additional options which customize the creation workflow.
@@ -64,7 +64,7 @@ export class SoSActor extends Actor {
if ( !this.system.cardDeck && this.hasPlayerOwner ) {
this.system.cardDeck = new SoSCardDeck();
this.system.cardDeck.initCardDeck( this, this.system.internals.deck );
}
}
if ( !this.hasPlayerOwner ) {
this.system.cardDeck = game.system.sos.gmDeck.GMdeck;
console.log("DECK : ", this.system.cardDeck);
@@ -91,28 +91,28 @@ export class SoSActor extends Actor {
this.saveDeck();
}
/* -------------------------------------------- */
drawNewEdge( ) {
drawNewEdge( ) {
this.system.cardDeck.drawEdge( 1 );
this.saveDeck();
}
/* -------------------------------------------- */
discardEdge( cardName ) {
discardEdge( cardName ) {
this.system.cardDeck.discardEdge( cardName );
this.saveDeck();
}
/* -------------------------------------------- */
resetDeck( ) {
this.system.cardDeck.resetDeck();
this.saveDeck();
}
/* -------------------------------------------- */
saveDeck( ) {
let deck = { deck: foundry.utils.duplicate(this.system.cardDeck.data.deck),
let deck = { deck: foundry.utils.duplicate(this.system.cardDeck.data.deck),
discard: foundry.utils.duplicate(this.system.cardDeck.data.discard),
cardEdge: foundry.utils.duplicate(this.system.cardDeck.data.cardEdge)
cardEdge: foundry.utils.duplicate(this.system.cardDeck.data.cardEdge)
}
if ( this.hasPlayerOwner ) {
this.update( { 'system.internals.deck': deck });
@@ -123,22 +123,22 @@ export class SoSActor extends Actor {
/* -------------------------------------------- */
getDefense( ) {
return this.system.scores.defense;
}
return this.system.scores.defense;
}
/* -------------------------------------------- */
computeDefense() {
return { value: Math.ceil((this.system.stats.speed.value + this.system.stats.perception.value + this.system.stats.dexterity.value) / 2) + this.system.scores.defense.bonusmalus,
critical: this.system.stats.speed.value + this.system.stats.perception.value + this.system.stats.dexterity.value + this.system.scores.defense.bonusmalus
}
}
}
/* -------------------------------------------- */
getEdge( ) {
return this.system.scores.edge.value;
}
}
/* -------------------------------------------- */
getEncumbrance( ) {
return this.system.scores.encumbrance.value;
}
}
computeEncumbrance( ) {
return this.system.stats.strength.value + this.system.scores.encumbrance.bonusmalus;
}
@@ -161,7 +161,7 @@ export class SoSActor extends Actor {
computeWound() {
return Math.ceil( (this.system.stats.strength.value + this.system.stats.endurance.value) / 2) + this.system.scores.wound.bonusmalus;
}
/* -------------------------------------------- */
getSkillExperience( skillName ) {
return this.items.filter( item => item.type == 'skillexperience' && item.system.skill == skillName);
@@ -170,21 +170,21 @@ export class SoSActor extends Actor {
/* -------------------------------------------- */
async wornObject( itemID) {
let item = this.items.get(itemID);
if (item && item.system) {
if (item?.system) {
let update = { _id: item.id, "system.worn": !item.system.worn };
await this.updateEmbeddedDocuments("Item", [update]);
}
}
/* -------------------------------------------- */
async equipObject(itemID) {
let item = this.items.get(itemID)
if (item && item.system) {
if (item?.system) {
let update = { _id: item.id, "system.equiped": !item.system.equiped };
await this.updateEmbeddedDocuments("Item", [update]);
}
}
/* -------------------------------------------- */
async controlScores() {
// Defense check
@@ -257,10 +257,10 @@ export class SoSActor extends Actor {
bonusConsequence: 0,
woundMalus: 0
}
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
new SoSFlipDialog(flipData, html).render(true);
}
/* -------------------------------------------- */
async rollSkill( skill ) {
let flipData = {
@@ -280,10 +280,10 @@ export class SoSActor extends Actor {
bonusSkillXP: 0
}
flipData.statList['nostat'] = { label: "No stat (ie defaulting skills)", value: 0, cardsuit: "none" }
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
new SoSFlipDialog(flipData, html).render(true);
}
/* -------------------------------------------- */
async rollWeapon( weapon ) {
let target = SoSUtility.getTarget();
@@ -321,7 +321,7 @@ export class SoSActor extends Actor {
console.log(flipData);
flipData.statList['nostat'] = { label: "No stat (ie defaulting skills)", value: 0, cardsuit: "none" }
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
new SoSFlipDialog(flipData, html).render(true);
}
@@ -329,12 +329,12 @@ export class SoSActor extends Actor {
async checkDeath( ) {
if ( this.system.scores.currentwounds.value >= this.system.scores.wound.value*2) {
let woundData = {
name: this.name,
name: this.name,
wounds: this.system.wounds,
currentWounds: this.system.scores.currentwounds.value,
totalWounds: this.system.scores.wound.value
totalWounds: this.system.scores.wound.value
}
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-character-death.html', woundData );
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-character-death.html', woundData );
ChatMessage.create( { content: html, whisper: ChatMessage.getWhisperRecipients(this.name).concat(ChatMessage.getWhisperRecipients("GM") ) } )
}
}
@@ -360,15 +360,15 @@ export class SoSActor extends Actor {
currentWounds.value = sumWound;
await this.update( { 'data.scores.currentwounds': currentWounds, 'data.wounds': wounds } );
let woundData = {
name: this.name,
let woundData = {
name: this.name,
consequenceName: consequenceName,
severity: severity,
severity: severity,
wounds: wounds,
currentWounds: sumWound,
totalWounds: this.system.scores.wound.value
}
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-consequence.html', woundData );
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-consequence.html', woundData );
ChatMessage.create( { content: html, whisper: ChatMessage.getWhisperRecipients(this.name).concat(ChatMessage.getWhisperRecipients("GM")) } )
this.checkDeath();
@@ -387,10 +387,10 @@ export class SoSActor extends Actor {
let alreadyInside = this.items.filter( item => item.system.containerid && item.system.containerid == containerId);
if ( alreadyInside.length >= container.system.container ) {
ui.notifications.warn("Container is already full !");
} else {
} else {
setTimeout(function() { this.updateEmbeddedDocuments( "Item", [{ _id: object.id, 'system.containerid':containerId }])}, 800 )
}
} else if ( object && object.system.containerid) { // remove from container
} else if ( object?.system?.containerid) { // remove from container
setTimeout(function() { this.updateEmbeddedDocuments( "Item", [{ _id: object.id, 'system.containerid':"" }])}, 800 )
}
}
@@ -398,8 +398,8 @@ export class SoSActor extends Actor {
/* -------------------------------------------- */
async applyWounds( flipData ) {
if ( flipData.damageStatus == 'no_damage') {
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-nodamage-taken.html', flipData );
ChatMessage.create( { content: html, whisper: ChatMessage.getWhisperRecipients(this.name).concat(ChatMessage.getWhisperRecipients("GM")) } );
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-nodamage-taken.html', flipData );
ChatMessage.create( { content: html, whisper: ChatMessage.getWhisperRecipients(this.name).concat(ChatMessage.getWhisperRecipients("GM")) } );
return;
}
@@ -436,7 +436,7 @@ export class SoSActor extends Actor {
flipData.wounds = wounds;
flipData.currentWounds = sumWound;
flipData.totalWounds = this.system.scores.wound.value;
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-taken.html', flipData );
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-taken.html', flipData );
ChatMessage.create( { content: html, whisper: ChatMessage.getWhisperRecipients(this.name).concat(ChatMessage.getWhisperRecipients("GM")) } );
this.checkDeath();

View File

@@ -4,7 +4,7 @@ import { SoSUtility } from "./sos-utility.js";
* Extend the basic ItemSheet with some very simple modifications
* @extends {ItemSheet}
*/
export class SoSItemSheet extends ItemSheet {
export class SoSItemSheet extends foundry.appv1.sheets.ItemSheet {
/** @override */
static get defaultOptions() {
@@ -40,7 +40,7 @@ export class SoSItemSheet extends ItemSheet {
sheetBody.css("height", bodyHeight);
return position;
}
/* -------------------------------------------- */
async getData() {
const objectData = this.object
@@ -60,7 +60,7 @@ export class SoSItemSheet extends ItemSheet {
description: await TextEditor.enrichHTML(this.object.system.description, {async: true}),
};
formData.isGM = game.user.isGM;
formData.isGM = game.user.isGM;
if ( objectData.type == 'skillexperience') {
formData.skillList = await SoSUtility.loadCompendiumNames("foundryvtt-shadows-over-sol.skills")
}
@@ -68,14 +68,14 @@ export class SoSItemSheet extends ItemSheet {
formData.skillExperienceList = this.object.options.actor.getSkillExperience( objectData.name )
}
if ( objectData.type == 'geneline') {
formData.weakness = await TextEditor.enrichHTML(this.object.system.weakness, {async: true})
formData.weakness = await TextEditor.enrichHTML(this.object.system.weakness, {async: true})
}
if ( objectData.type == 'malady') {
formData.notes = await TextEditor.enrichHTML(this.object.system.notes, {async: true})
formData.notes = await TextEditor.enrichHTML(this.object.system.notes, {async: true})
}
return formData;
}
/* -------------------------------------------- */
/** @override */
activateListeners(html) {
@@ -83,7 +83,7 @@ export class SoSItemSheet extends ItemSheet {
// Everything below here is only needed if the sheet is editable
if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
@@ -95,9 +95,9 @@ export class SoSItemSheet extends ItemSheet {
const li = $(ev.currentTarget).parents(".item");
this.object.options.actor.deleteOwnedItem( li.data("item-id") ).then( this.render(true));
});
}
/* -------------------------------------------- */
get template()
{

View File

@@ -5,30 +5,30 @@ const NB_POKER_CARD = 54;
const IDX2CARDFAMILY = ['c', 'd', 'h', 's'];
/* -------------------------------------------- */
export class SoSCardDeck {
export class SoSCardDeck {
/* -------------------------------------------- */
async initCardDeck(actor, savedDeck = undefined ) {
async initCardDeck(actor, savedDeck = undefined) {
this.data = {};
this.data.deck = [];
this.data.discard = [];
this.data.cardState = [];
this.data.cardEdge = [];
this.data.cardEdge = [];
if ( savedDeck.deck && savedDeck.deck.length > 0 ) {
if (savedDeck.deck && savedDeck.deck.length > 0) {
this.data.deck = foundry.utils.duplicate(savedDeck.deck);
}
if ( savedDeck.discard && savedDeck.discard.length > 0 ) {
if (savedDeck.discard && savedDeck.discard.length > 0) {
this.data.discard = foundry.utils.duplicate(savedDeck.discard);
}
if ( savedDeck.cardEdge && savedDeck.cardEdge.length > 0 ) {
if (savedDeck.cardEdge && savedDeck.cardEdge.length > 0) {
this.data.cardEdge = foundry.utils.duplicate(savedDeck.cardEdge);
}
this.data.actor = actor;
if ( this.data.deck.length == 0 && this.data.discard.length == 0) {
this.data.actor = actor;
if (this.data.deck.length == 0 && this.data.discard.length == 0) {
await this.shuffleDeck();
}
}
@@ -38,58 +38,56 @@ export class SoSCardDeck {
this.cleanCardList();
// Randomize deck
while (this.data.deck.length != NB_POKER_CARD) {
let roll = await new Roll("1d54").roll();
let idx = roll.total;
let idx = Math.floor(Math.random() * 55);
if (!this.data.cardState[idx - 1]) {
if (idx == 53) { // Red Joker
this.data.deck.push( { cardName: 'jr' } );
this.data.deck.push({ cardName: 'jr' });
} else if (idx == 54) { // Black Joker
this.data.deck.push({ cardName: 'jb' });
} else {
let familyIdx = idx % 4;
let cardIdx = String( (idx % 13) + 1);
cardIdx = (cardIdx.length < 2) ? "0"+cardIdx: cardIdx;
let cardIdx = String((idx % 13) + 1);
cardIdx = (cardIdx.length < 2) ? "0" + cardIdx : cardIdx;
let cardName = IDX2CARDFAMILY[familyIdx] + cardIdx;
this.data.deck.push( { cardName: cardName } );
this.data.deck.push({ cardName: cardName });
}
this.data.cardState[idx - 1] = true;
}
}
}
}
/* -------------------------------------------- */
async resetDeck() {
let newdeck = foundry.utils.duplicate(this.data.deck).concat( foundry.utils.duplicate (this.data.discard) )
let newdeck = foundry.utils.duplicate(this.data.deck).concat(foundry.utils.duplicate(this.data.discard))
this.data.discard = [] // Reinit discard pile
this.data.deck = []
this.data.deck = []
let decklen = newdeck.length
let cardState = []
for (let i = 0; i <decklen; i++) {
for (let i = 0; i < decklen; i++) {
cardState[i] = false
}
// Randomize deck
while (this.data.deck.length != decklen) {
let roll = await new Roll("1d"+decklen).roll()
let idx = roll.total
let idx = Math.floor(Math.random() * (decklen + 1));
//console.log("Deck stuff", this.data.deck.length, decklen, idx)
if (!cardState[idx-1]) {
this.data.deck.push( newdeck[idx-1] )
if (!cardState[idx - 1]) {
this.data.deck.push(newdeck[idx - 1])
}
cardState[idx-1] = true
cardState[idx - 1] = true
}
}
/* -------------------------------------------- */
discardEdge( cardName ) {
let newEdge = this.data.cardEdge.filter( card => card.cardName != cardName);
this.data.cardEdge = newEdge; // New edge list
this.data.discard.push( { cardName: cardName }); // And push in the discard pile
}
/* -------------------------------------------- */
drawEdge( edgeNumber = 1 ) {
for (let i=0; i<edgeNumber; i++) {
this.data.cardEdge.push( this.data.deck.pop() );
discardEdge(cardName) {
let newEdge = this.data.cardEdge.filter(card => card.cardName != cardName);
this.data.cardEdge = newEdge; // New edge list
this.data.discard.push({ cardName: cardName }); // And push in the discard pile
}
/* -------------------------------------------- */
drawEdge(edgeNumber = 1) {
for (let i = 0; i < edgeNumber; i++) {
this.data.cardEdge.push(this.data.deck.pop());
console.log("DRAW EDGE", this.data.cardEdge);
}
}
@@ -110,133 +108,133 @@ export class SoSCardDeck {
}
/* -------------------------------------------- */
getCardSuit( cardName ) {
if ( cardName[0] == 'c') return 'club';
if ( cardName[0] == 'd') return 'diamond';
if ( cardName[0] == 'h') return 'hearts';
if ( cardName[0] == 's') return 'spade';
if ( cardName[0] == 'j') return 'joker';
getCardSuit(cardName) {
if (cardName[0] == 'c') return 'club';
if (cardName[0] == 'd') return 'diamond';
if (cardName[0] == 'h') return 'hearts';
if (cardName[0] == 's') return 'spade';
if (cardName[0] == 'j') return 'joker';
}
/* -------------------------------------------- */
drawFromDeck() {
drawFromDeck() {
let card = this.data.deck.pop();
this.data.discard.push( card );
this.data.discard.push(card);
return card;
}
/* -------------------------------------------- */
getFromEdge( cardName) {
let card = this.data.cardEdge.find( card => card.cardName == cardName); // Get the card
let newEdge = this.data.cardEdge.filter(card => card.cardName != cardName); // Remove used card
getFromEdge(cardName) {
let card = this.data.cardEdge.find(card => card.cardName == cardName); // Get the card
let newEdge = this.data.cardEdge.filter(card => card.cardName != cardName); // Remove used card
this.data.cardEdge = newEdge;
return card;
}
/* -------------------------------------------- */
getCardValue( cardName ) {
getCardValue(cardName) {
console.log(cardName);
if (cardName[0] == 'j' ) return 0; // Joker case
let parsed = cardName.match( /\w(\d\d)/i );
let value = Number( parsed[1] );
if ( value > 10 ) value -= 10;
if (cardName[0] == 'j') return 0; // Joker case
let parsed = cardName.match(/\w(\d\d)/i);
let value = Number(parsed[1]);
if (value > 10) value -= 10;
return value;
}
/* -------------------------------------------- */
isCardFace(cardName) {
if (cardName[0] == 'j' ) return false; // Joker case
let parsed = cardName.match( /\w(\d\d)/i );
let value = Number( parsed[1] );
return (value > 10) ? true : false;
if (cardName[0] == 'j') return false; // Joker case
let parsed = cardName.match(/\w(\d\d)/i);
let value = Number(parsed[1]);
return (value > 10);
}
/* -------------------------------------------- */
setJoker( flipData ) {
setJoker(flipData) {
console.log("THIS IS A JOKER !!!!");
flipData.cardSlot[0].total = 0;
flipData.cardSlot[0].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card1.cardName}.webp`;
flipData.cardSlot[0].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card1.cardName}.webp`;
flipData.isJoker = true;
}
/* -------------------------------------------- */
isJoker( cardName) {
isJoker(cardName) {
return cardName[0] == 'j';
}
/* -------------------------------------------- */
async doFlipFromDeckOrEdge( flipData ) {
flipData.cardSlot = [ { total: 0}];
async doFlipFromDeckOrEdge(flipData) {
flipData.cardSlot = [{ total: 0 }];
flipData.isTrump = false;
flipData.isJoker = false;
flipData.fullTrump = false;
if ( flipData.edgeLuck ) {
flipData.cardOrigin == "Deck"; // Force Deck
if (flipData.edgeLuck) {
flipData.cardOrigin = "Deck"; // Force Deck
}
// Select card origin
if ( flipData.cardOrigin == "Deck") {
if (flipData.cardOrigin == "Deck") {
flipData.cardSlot[0].card1 = this.drawFromDeck();
} else {
flipData.cardSlot[0].card1 = this.getFromEdge( flipData.edgeName );
}
flipData.cardSlot[0].card1 = this.getFromEdge(flipData.edgeName);
}
let cardsuit = this.getCardSuit(flipData.cardSlot[0].card1.cardName);
if ( cardsuit == 'joker' ) {
this.setJoker( flipData );
if (cardsuit == 'joker') {
this.setJoker(flipData);
} else {
//console.log("First card : ", flipData.cardSlot[0].card1);
// Face check for first card
flipData.cardSlot[0].value1 = this.getCardValue(flipData.cardSlot[0].card1.cardName);
flipData.cardSlot[0].isFace1 = this.isCardFace(flipData.cardSlot[0].card1.cardName);
flipData.cardSlot[0].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card1.cardName}.webp`;
flipData.cardSlot[0].value1 = this.getCardValue(flipData.cardSlot[0].card1.cardName);
flipData.cardSlot[0].isFace1 = this.isCardFace(flipData.cardSlot[0].card1.cardName);
flipData.cardSlot[0].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card1.cardName}.webp`;
flipData.cardSlot[0].card2 = false;
if ( flipData.cardSlot[0].isFace1 ) {
flipData.cardSlot[0].card2 = this.drawFromDeck();
if (flipData.cardSlot[0].isFace1) {
flipData.cardSlot[0].card2 = this.drawFromDeck();
flipData.isJoker = this.isJoker(flipData.cardSlot[0].card2.cardName);
flipData.cardSlot[0].value2 = this.getCardValue(flipData.cardSlot[0].card2.cardName);
flipData.cardSlot[0].value2 = this.getCardValue(flipData.cardSlot[0].card2.cardName);
flipData.cardSlot[0].isFace2 = this.isCardFace(flipData.cardSlot[0].card2.cardName);
flipData.cardSlot[0].card2Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card2.cardName}.webp`;
} else {
flipData.cardSlot[0].value2 = 0; // Safe init
}
flipData.cardSlot[0].total = flipData.cardSlot[0].value1 + flipData.cardSlot[0].value2;
flipData.cardSlot[0].total = flipData.cardSlot[0].value1 + flipData.cardSlot[0].value2;
// Trump check
flipData.cardSlot[0].cardsuit = cardsuit;
if ( !flipData.isJoker && ( cardsuit == flipData.stat.cardsuit || flipData.edgeLuck) ) {
flipData.cardSlot[0].cardsuit = cardsuit;
if (!flipData.isJoker && (cardsuit == flipData.stat.cardsuit || flipData.edgeLuck)) {
// This is a trump !
flipData.cardSlot[1] = { total: 0 };
flipData.isTrump = true;
flipData.cardSlot[1].card1 = this.drawFromDeck();
flipData.isJoker = this.isJoker(flipData.cardSlot[1].card1.cardName);
flipData.cardSlot[1].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[1].card1.cardName}.webp`;
flipData.cardSlot[1].cardsuit = this.getCardSuit(flipData.cardSlot[1].card1.cardName);
flipData.cardSlot[1].value1 = this.getCardValue(flipData.cardSlot[1].card1.cardName);
flipData.cardSlot[1].isFace1 = this.isCardFace(flipData.cardSlot[1].card1.cardName);
if ( !flipData.isJoker && flipData.cardSlot[1].isFace1 ) {
flipData.cardSlot[1].card2 = this.drawFromDeck();
flipData.cardSlot[1].cardsuit = this.getCardSuit(flipData.cardSlot[1].card1.cardName);
flipData.cardSlot[1].value1 = this.getCardValue(flipData.cardSlot[1].card1.cardName);
flipData.cardSlot[1].isFace1 = this.isCardFace(flipData.cardSlot[1].card1.cardName);
if (!flipData.isJoker && flipData.cardSlot[1].isFace1) {
flipData.cardSlot[1].card2 = this.drawFromDeck();
flipData.isJoker = this.isJoker(flipData.cardSlot[1].card2.cardName);
flipData.cardSlot[1].value2 = this.getCardValue(flipData.cardSlot[1].card2.cardName);
flipData.cardSlot[1].isFace2 = this.isCardFace(flipData.cardSlot[1].card2.cardName);
flipData.cardSlot[1].value2 = this.getCardValue(flipData.cardSlot[1].card2.cardName);
flipData.cardSlot[1].isFace2 = this.isCardFace(flipData.cardSlot[1].card2.cardName);
flipData.cardSlot[1].card2Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[1].card2.cardName}.webp`;
} else {
flipData.cardSlot[1].value2 = 0; // Safe init
}
if ( flipData.cardSlot[1].cardsuit == cardsuit ) {
if (flipData.cardSlot[1].cardsuit == cardsuit) {
flipData.fullTrump = true;
}
flipData.cardSlot[1].total = flipData.cardSlot[1].value1 + flipData.cardSlot[1].value2;
flipData.cardSlot[1].total = flipData.cardSlot[1].value1 + flipData.cardSlot[1].value2;
}
}
// Card Total
flipData.cardTotal = flipData.cardSlot[0].total;
flipData.cardSlotIndex = 0;
if ( flipData.fullTrump ) {
if (flipData.fullTrump) {
flipData.cardTotal = flipData.cardSlot[0].total + flipData.cardSlot[1].total;
} else if (flipData.isTrump) {
if (flipData.cardSlot[0].total > flipData.cardSlot[1].total ) {
if (flipData.cardSlot[0].total > flipData.cardSlot[1].total) {
flipData.cardSlotIndex = 0;
flipData.cardTotal = flipData.cardSlot[0].total;
} else {
@@ -246,66 +244,66 @@ export class SoSCardDeck {
}
// Compute final result and compare
if ( flipData.mode == 'stat' || flipData.mode == 'weapon' ) {
if (flipData.mode == 'stat' || flipData.mode == 'weapon') {
flipData.baseScore = flipData.stat.value + flipData.malusConsequence + flipData.bonusConsequence + flipData.woundMalus;
} else if (flipData.mode == 'skill') {
flipData.baseScore = Math.floor(flipData.stat.value/2) + flipData.skill.system.value + flipData.malusConsequence + flipData.bonusConsequence + flipData.woundMalus;
flipData.baseScore = Math.floor(flipData.stat.value / 2) + flipData.skill.system.value + flipData.malusConsequence + flipData.bonusConsequence + flipData.woundMalus;
}
flipData.finalScore = flipData.baseScore + flipData.cardTotal + Number(flipData.modifier);
flipData.magnitude = flipData.finalScore - flipData.tn;
flipData.result = (flipData.magnitude >= 0) ? "Success": "Failure";
flipData.result = (flipData.magnitude >= 0) ? "Success" : "Failure";
//console.log(flipData);
this.data.actor.saveDeck();
flipData.alias = this.data.actor.name;
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-flip.html', flipData);
ChatMessage.create( { content: html });
flipData.alias = this.data.actor.name;
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-flip.html', flipData);
ChatMessage.create({ content: html });
if ( flipData.mode == 'weapon' && flipData.magnitude >= 0 && !flipData.isJoker) { // Success
this.processWeapon( flipData );
if (flipData.mode == 'weapon' && flipData.magnitude >= 0 && !flipData.isJoker) { // Success
this.processWeapon(flipData);
}
if (flipData.isJoker) { // Critical mismatch !
// TODO
}
}
/* -------------------------------------------- */
async processWeapon( flipData ) {
async processWeapon(flipData) {
flipData.damageCardsuit = flipData.cardSlot[flipData.cardSlotIndex].cardsuit;
let damageKey = 'damage_'+ flipData.damageCardsuit;
let damageKey = 'damage_' + flipData.damageCardsuit;
flipData.damageString = flipData.weapon.system[damageKey];
if (flipData.damageString.includes('Str') ) {
let damageRegexp = flipData.damageString.match( /Str([\d])?\+?([\d])?([LMSC])/i );
flipData.damageValue = (flipData.actor.system.stats.strength.value * Number(damageRegexp[1]?damageRegexp[1]:1)) + Number(damageRegexp[2]?damageRegexp[2]:0);
if (flipData.damageString.includes('Str')) {
let damageRegexp = flipData.damageString.match(/Str([\d])?\+?([\d])?([LMSC])/i);
flipData.damageValue = (flipData.actor.system.stats.strength.value * Number(damageRegexp[1] ? damageRegexp[1] : 1)) + Number(damageRegexp[2] ? damageRegexp[2] : 0);
flipData.damageSeverity = damageRegexp[3];
} else {
let damageRegexp = flipData.damageString.match( /(\d*)([LMSC])/i );
let damageRegexp = flipData.damageString.match(/(\d*)([LMSC])/i);
flipData.damageValue = damageRegexp[1];
flipData.damageSeverity = damageRegexp[2];
}
// Now process damage
if ( flipData.target) {
if ( game.user.isGM ) { // Direct access
SoSUtility.applyDamage( flipData );
if (flipData.target) {
if (game.user.isGM) { // Direct access
SoSUtility.applyDamage(flipData);
} else {
game.socket.emit("system.foundryvtt-shadows-over-sol", {
msg: "msg_request_defense", data: flipData } );
msg: "msg_request_defense", data: flipData
});
}
} else {
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-only.html', flipData );
ChatMessage.create( { content: html });
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/chat-damage-only.html', flipData);
ChatMessage.create({ content: html });
}
}
/* -------------------------------------------- */
getDeckHTML( ) {
getDeckHTML() {
return "<a class='view-deck'><img class='flip-card deck-card' src='systems/foundryvtt-shadows-over-sol/img/cards/card_back.webp' /></a>";
}
/* -------------------------------------------- */
getEdgeHTML( ) {
getEdgeHTML() {
let html = "";
for (let edge of this.data.cardEdge) {
html += `<a class='view-edge'><img class='flip-card edge-card' data-edge-card='${edge.cardName}' src='systems/foundryvtt-shadows-over-sol/img/cards/${edge.cardName}.webp' /></a>`
@@ -313,21 +311,21 @@ export class SoSCardDeck {
return html;
}
/* -------------------------------------------- */
getEdgeHTMLForFlip( ) {
let html = "";
for (let edge of this.data.cardEdge) {
html += `<a class='view-edge'><img class='flip-card edge-card' data-edge-card='${edge.cardName}' src='systems/foundryvtt-shadows-over-sol/img/cards/${edge.cardName}.webp' /></a>`
}
return html;
}
/* -------------------------------------------- */
getDiscardTopHTML( ) {
getEdgeHTMLForFlip() {
let html = "";
console.log( "DISCARD: ", this.data.discard );
if ( this.data.discard.length > 0) {
let card = this.data.discard[this.data.discard.length-1];
for (let edge of this.data.cardEdge) {
html += `<a class='view-edge'><img class='flip-card edge-card' data-edge-card='${edge.cardName}' src='systems/foundryvtt-shadows-over-sol/img/cards/${edge.cardName}.webp' /></a>`
}
return html;
}
/* -------------------------------------------- */
getDiscardTopHTML() {
let html = "";
console.log("DISCARD: ", this.data.discard);
if (this.data.discard.length > 0) {
let card = this.data.discard[this.data.discard.length - 1];
html = `<img class='view-discard flip-card' src='systems/foundryvtt-shadows-over-sol/img/cards/${card.cardName}.webp' />`;
}
return html;

View File

@@ -37,14 +37,14 @@ Hooks.once("init", async function () {
// preload handlebars templates
SoSUtility.preloadHandlebarsTemplates();
// Create useful storage space
let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/gm-deck.html', {} );
let html = await foundry.applications.handlebars.renderTemplate('systems/foundryvtt-shadows-over-sol/templates/gm-deck.html', {} );
let gmDeck = new SoSGMDeck(html);
game.system.sos = {
game.system.sos = {
gmDeck: gmDeck,
}
/* -------------------------------------------- */
// Set an initiative formula for the system
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "1d3",
decimals: 2
@@ -64,10 +64,10 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
// Register sheet application classes
Actors.unregisterSheet("core", ActorSheet);
Actors.registerSheet("foundryvtt-shadows-over-sol", SoSActorSheet, { types: ["character"], makeDefault: true });
Items.unregisterSheet("core", ItemSheet);
Items.registerSheet("foundryvtt-shadows-over-sol", SoSItemSheet, { makeDefault: true });
foundry.documents.collections.Actors.unregisterSheet("core", foundry.appv1.sheets.ActorSheet);
foundry.documents.collections.Actors.registerSheet("foundryvtt-shadows-over-sol", SoSActorSheet, { types: ["character"], makeDefault: true });
foundry.documents.collections.Items.unregisterSheet("core", foundry.appv1.sheets.ItemSheet);
foundry.documents.collections.Items.registerSheet("foundryvtt-shadows-over-sol", SoSItemSheet, { makeDefault: true });
// Init/registers
Hooks.on('renderChatLog', (log, html, data) => {
@@ -77,7 +77,7 @@ Hooks.once("init", async function () {
Hooks.on('updateCombat', (combat, round, diff, id) => {
SoSUtility.updateCombat(combat, round, diff, id);
});
});
/* -------------------------------------------- */
@@ -105,7 +105,7 @@ Hooks.once("ready", function () {
}
ClassCounter.registerUsageCount()
SoSUtility.ready()
welcomeMessage();
});

View File

@@ -27,7 +27,7 @@ export class SoSUtility {
'systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html'
]
return loadTemplates(templatePaths);
return foundry.applications.handlebars.loadTemplates(templatePaths);
}
/* -------------------------------------------- */
@@ -137,14 +137,14 @@ export class SoSUtility {
/* -------------------------------------------- */
static async registerChatCallbacks(html) {
html.on("click", '#button-declare-actions', event => {
$(html).on("click", '#button-declare-actions', event => {
SoSUtility.openDeclareActions(event);
});
html.on("click", '#button-end-action', event => {
$(html).on("click", '#button-end-action', event => {
SoSUtility.closeAction(event);
});
html.on("click", '#button-reaction-cover', event => {
$(html).on("click", '#button-reaction-cover', event => {
let uniqId = event.currentTarget.attributes['data-uniq-id'].value;
if (game.user.isGM) {
SoSUtility.reactionCover(uniqId);
@@ -153,7 +153,7 @@ export class SoSUtility {
}
});
html.on("click", '#button-reaction-melee', event => {
$(html).on("click", '#button-reaction-melee', event => {
let uniqId = event.currentTarget.attributes['data-uniq-id'].value;
if (game.user.isGM) {
SoSUtility.reactionMelee(uniqId);
@@ -161,7 +161,7 @@ export class SoSUtility {
game.socket.emit("system.foundryvtt-shadows-over-sol", { name: "msg_reaction_melee", data: { uniqId: uniqId } });
}
});
html.on("click", '#button-reaction-hit', event => {
$(html).on("click", '#button-reaction-hit', event => {
let uniqId = event.currentTarget.attributes['data-uniq-id'].value;
if (game.user.isGM) {
SoSUtility.reactionHit(uniqId);