diff --git a/lang/en.json b/lang/en.json index c0d675f..caed94b 100644 --- a/lang/en.json +++ b/lang/en.json @@ -18,7 +18,7 @@ "STATS.physical": "physical", "STATS.mental": "mental", "STATS.strength": "Strength", - "STATS.dexterity": "Dextrity", + "STATS.dexterity": "Dexterity", "STATS.speed": "Speed", "STATS.endurance": "Endurance", "STATS.intelligence": "Intelligence", diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 81f3aeb..ec53547 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -75,6 +75,11 @@ export class SoSActorSheet extends ActorSheet { let statName = event.currentTarget.attributes.name.value; this.actor.rollStat(statName); }); + html.find('.skill-label a').click((event) => { + const li = $(event.currentTarget).parents(".item"); + const skill = this.actor.getOwnedItem(li.data("item-id")); + this.actor.rollSkill(skill); + }); html.find('.edge-draw').click((event) => { this.actor.resetDeck(); this.render(true); diff --git a/module/actor.js b/module/actor.js index ebbf5b2..c0268fc 100644 --- a/module/actor.js +++ b/module/actor.js @@ -141,7 +141,8 @@ export class SoSActor extends Actor { mode: 'stat', stat: duplicate(this.data.data.stats[statKey]), actor: this, - modifierList: SoSUtility.fillRange(-10, +10) + modifierList: SoSUtility.fillRange(-10, +10), + tnList: SoSUtility.fillRange(6, 20) } let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData); new SoSFlipDialog(flipData, html).render(true); @@ -149,5 +150,18 @@ export class SoSActor extends Actor { //console.log("STAT", this); //let result = this.cardDeck.doFlipStat( duplicate(this.data.data.stat[statKey]) ); } - + + /* -------------------------------------------- */ + async rollSkill( skill ) { + let flipData = { + mode: 'skill', + statList: duplicate(this.data.data.stats), + skill: duplicate(skill), + actor: this, + modifierList: SoSUtility.fillRange(-10, +10), + tnList: SoSUtility.fillRange(6, 20) + } + let html = await renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData); + new SoSFlipDialog(flipData, html).render(true); + } } diff --git a/module/sos-card-deck.js b/module/sos-card-deck.js index 1cc5d45..e187573 100644 --- a/module/sos-card-deck.js +++ b/module/sos-card-deck.js @@ -71,24 +71,145 @@ export class SoSCardDeck { } /* -------------------------------------------- */ - doFlipFromDeck( ) { + getCardSuit( cardName ) { + if ( cardName[0] == 'c') return 'club'; + if ( cardName[0] == 'd') return 'diamond'; + if ( cardName[0] == 'h') return 'hearth'; + if ( cardName[0] == 's') return 'spade'; + if ( cardName[0] == 'j') return 'joker'; + } + + /* -------------------------------------------- */ + drawFromDeck() { let card = this.data.deck.pop(); - this.data.discard.push( card ); - console.log("CARD IS : ", card, this.data.deck.length ); + 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 + this.data.cardEdge = newEdge; + return card; + } + + /* -------------------------------------------- */ + getCardValue( cardName ) { + console.log(cardName); + let parsed = cardName.match( /\w(\d\d)/i ); + let value = Number( parsed[1] ); + if ( value > 10 ) value -= 10; + return value; + } + /* -------------------------------------------- */ + isCardFace(cardName) { + let parsed = cardName.match( /\w(\d\d)/i ); + let value = Number( parsed[1] ); + return (value > 10) ? true : false; } + /* -------------------------------------------- */ + async doFlipFromDeckOrEdge( flipData ) { + flipData.cardSlot = [ { total: 0}]; + flipData.isTrump = false; + flipData.isJoker = false; + flipData.fullTrump = false; + + // Select card origin + if ( flipData.cardOrigin == "Deck") { + flipData.cardSlot[0].card1 = this.drawFromDeck(); + } else { + flipData.cardSlot[0].card1 = this.getFromEdge( flipData.edgeName ); + } + + let cardsuit = this.getCardSuit(flipData.cardSlot[0].card1.cardName); + if ( cardsuit == 'joker' ) { + console.log("THIS IS A JOKER !!!!"); + flipData.cardSlot[0].total = 0; + flipData.cardSlot[0].isJoker = true; + flipData.cardSlot[0].card1Path = `systems/foundryvtt-shadows-over-sol/img/cards/${flipData.cardSlot[0].card1.cardName}.webp`; + } 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].card2 = false; + if ( flipData.cardSlot[0].isFace1 ) { + flipData.cardSlot[0].card2 = this.drawFromDeck(); + 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; + + // Trump check + flipData.cardSlot[0].cardsuit = cardsuit; + if ( cardsuit == flipData.stat.cardsuit ) { + // This is a trump ! + flipData.cardSlot[1] = { total: 0 }; + flipData.isTrump = true; + flipData.cardSlot[1].card1 = this.drawFromDeck(); + 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.cardSlot[1].isFace1 ) { + flipData.cardSlot[1].card2 = this.drawFromDeck(); + 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 ) { + flipData.fullTrump = true; + } + flipData.cardSlot[1].total = flipData.cardSlot[1].value1 + flipData.cardSlot[1].value2; + } + } + + // Card Total + flipData.cardTotal = flipData.cardSlot[0].total; + if ( flipData.fullTrump ) { + flipData.cardTotal = flipData.cardSlot[0].total + flipData.cardSlot[1].total; + } else if (flipData.isTrump) { + flipData.cardTotal = (flipData.cardSlot[0].total > flipData.cardSlot[1].total) ? flipData.cardSlot[0].total : flipData.cardSlot[1].total; + } + + // Compute final result and compare + if ( flipData.mode == 'stat' ) { + flipData.baseScore = flipData.stat.value; + } else if (flipData.mode == 'skill') { + flipData.baseScore = Math.floor(flipData.stat.value/2) + flipData.skill.data.value; + } + flipData.finalScore = flipData.baseScore + flipData.cardTotal + Number(flipData.modifier); + flipData.magnitude = flipData.finalScore - flipData.tn; + 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 }); + } + + /* -------------------------------------------- */ getDeckHTML( ) { - return ""; + return ""; } /* -------------------------------------------- */ getEdgeHTML( ) { let html = ""; for (let edge of this.data.cardEdge) { - html += `` + html += `` } - return html; } diff --git a/module/sos-flip-dialog.js b/module/sos-flip-dialog.js index 9f56616..078d1f7 100644 --- a/module/sos-flip-dialog.js +++ b/module/sos-flip-dialog.js @@ -7,7 +7,7 @@ export class SoSFlipDialog extends Dialog { title: 'Flip Dialog', content: html, buttons: { - 'flip-close': { label: 'Flip and Close', callback: html => this.onFlipClose() } + 'flip-close': { label: 'Cancel and Close', callback: html => this.onFlipClose() } }, default: 'flip' }; @@ -18,7 +18,7 @@ export class SoSFlipDialog extends Dialog { /* -------------------------------------------- */ onFlipClose( ) { - + this.close(); } /* -------------------------------------------- */ @@ -27,11 +27,22 @@ export class SoSFlipDialog extends Dialog { $('.view-deck').remove(); $("#view-deck").append(await flipData.actor.cardDeck.getDeckHTML()); - $('.view-discard').remove(); - $("#view-discard").append(await flipData.actor.cardDeck.getDiscardTopHTML()); - $('.view-edge').remove(); $("#view-edge").append(await flipData.actor.cardDeck.getEdgeHTML()); + + $('.edge-card').click((event) => { + let flipData = duplicate(this.flipData); + flipData.modifier = $('#modifier').val(); + flipData.tn = $('#tn').val(); + flipData.edgeName = event.currentTarget.attributes['data-edge-card'].value; + flipData.cardOrigin = "Edge"; + if ( flipData.mode == 'skill') { + flipData.stat = duplicate( flipData.statList[ $('#statSelect').val() ] ); + } + this.flipData.actor.cardDeck.doFlipFromDeckOrEdge(flipData); + this.onFlipClose(); + }); + } /* -------------------------------------------- */ @@ -53,10 +64,20 @@ export class SoSFlipDialog extends Dialog { // Setup everything onload $(function () { onLoad(); }); - html.find('#do-flip-deck').click((event) => { - dialog.flipData.actor.cardDeck.doFlipFromDeck(); - dialog.updateFlip( dialog.flipData); + html.find('.class-view-deck').click((event) => { + let flipData = duplicate(this.flipData); + flipData.modifier = html.find('#modifier').val(); + flipData.tn = html.find('#tn').val(); + if ( flipData.mode == 'skill') { + console.log("SKILL STAT : ", html.find('#statSelect').val() ); + flipData.stat = duplicate( flipData.statList[ html.find('#statSelect').val() ] ); + } + flipData.cardOrigin = "Deck"; + flipData.tn = html.find('#tn').val(); + dialog.flipData.actor.cardDeck.doFlipFromDeckOrEdge(flipData); + dialog.onFlipClose(); }); + } diff --git a/styles/simple.css b/styles/simple.css index e0923ec..65733f5 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -239,7 +239,11 @@ table {border: 1px solid #7a7971;} width: 90px; margin-right: 5px; } - +.card-icon { + height: 128px; + width: 90px !important; + flex-grow: 1; +} .card-img { height: 128px; width: 90px; diff --git a/templates/chat-flip.html b/templates/chat-flip.html new file mode 100644 index 0000000..dd9367b --- /dev/null +++ b/templates/chat-flip.html @@ -0,0 +1,27 @@ +

{{alias}} flips a card from {{cardOrigin}}{{#if isTrump}} with a Trump ! {{/if}}

+

This a {{mode}} {{#if skill}} {{skill.name}} {{/if}} Flip, with {{localize stat.label}} ({{stat.value}} - {{stat.cardsuit}})

+ + + + {{#each cardSlot as |slot|}} + + {{/each}} + +
+ + {{#if slot.isFace1}} + + {{/if}} +
+ +{{#if isJoker}} + +{{else}} +
+ + + + + +
+{{/if}} diff --git a/templates/dialog-flip.html b/templates/dialog-flip.html index 9e3d657..97785eb 100644 --- a/templates/dialog-flip.html +++ b/templates/dialog-flip.html @@ -2,37 +2,59 @@

Flip Dialog !

-

{{#if (eq mode 'stat')}} - Stat Only Flip : {{localize stat.label}} +

+ Stat Only Flip : {{localize stat.label}} ({{stat.value}}, {{stat.cardsuit}}) +

{{else}} - Skill Flip : {{skill.name}} +

+ Select Stat + +

+

+ Skill Flip : {{skill.name}} ({{skill.data.value}}) +

{{/if}} -
- + + +
+
+ + {{#select modifier}} + {{#each modifierList as |key|}} + + {{/each}} + {{/select}} + +
+
+
-
- - Flip from deck ! +
+ +
-
-
-
-
-
+
+
- + \ No newline at end of file