#4 : Weakness management, including bonus/malus field for scores and reminder in the flip dialog

This commit is contained in:
sladecraven 2021-03-12 17:12:14 +01:00
parent 96991516b6
commit 87ca3febd3
11 changed files with 132 additions and 30 deletions

View File

@ -0,0 +1 @@
<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><defs><radialGradient id="delapouite-achilles-heel-gradient-0"><stop offset="0%" stop-color="#000" stop-opacity="1"></stop><stop offset="100%" stop-color="#9b9b9b" stop-opacity="1"></stop></radialGradient></defs><rect fill="url(#delapouite-achilles-heel-gradient-0)" stroke="#000000" stroke-opacity="1" stroke-width="1" height="510" width="510" rx="32" ry="32"></rect><g class="" style="" transform="translate(-5,-11)"><path d="M362.188 17.998c-12.9 65.825-49.788 140.505-98.616 197.37L352 224l-89.377 19.414 52.197 75.27-71.111-56.364L224 336l-8.576-73.182 2.812-2.779c-45.221 40.71-35.888 74.86.702 96.49 6.775 4.005 16.257 9.046 27.38 8.7 58.243-1.813 93.255 35.012 126.575 76.199 18.234 22.54 48.35 30.059 73.529 44.246 52.44 29.548 67.894-32.667 14.767-53.445l-70.677-111.036c-11.42-53.08 52.186-171.824 103.49-248.37V17.997zM92.454 23.424v32.17l32.799 32.79 8.043-24.126zM78.578 67.352c-.233-.026-.57.037-1.224.199-1.31.323-3.41 1.482-5.075 3.146-1.664 1.664-2.823 3.763-3.146 5.073-.266 1.074-.207 1.3.012 1.61l120.228 120.208 3.275-6.55 6.545-3.272L78.97 67.563c-.123-.086-.24-.195-.39-.211zM21.162 87.029L62 127.86l24.13-8.043-30.335-30.33-.397-.396-.343-.442a17.99 17.99 0 0 1-1.112-1.619zm213.563 103.098l-28.663 14.326-14.33 28.654 38.264 15.303 20.096-19.869z" fill="#fff" fill-opacity="1" transform="translate(25.6, 25.6) scale(0.9, 0.9) rotate(0, 256, 256) skewX(0) skewY(0)"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -13,6 +13,7 @@
"SCORES.Currentwounds": "Current Wounds", "SCORES.Currentwounds": "Current Wounds",
"SCORES.Shock": "Shock", "SCORES.Shock": "Shock",
"SCORES.Wounds": "Wounds", "SCORES.Wounds": "Wounds",
"SCORES.Totalwounds": "Max. Wounds",
"SCORES.Encumbrance": "Encumbrance", "SCORES.Encumbrance": "Encumbrance",
"STATS.physical": "physical", "STATS.physical": "physical",

View File

@ -25,6 +25,8 @@ export class SoSActorSheet extends ActorSheet {
getData() { getData() {
let data = super.getData(); let data = super.getData();
this.actor.checkDeck();
data.data.edgecard = this.actor.getEdgesCard(); data.data.edgecard = this.actor.getEdgesCard();
data.data.deckSize = this.actor.getDeckSize(); data.data.deckSize = this.actor.getDeckSize();

View File

@ -53,15 +53,20 @@ export class SoSActor extends Actor {
async prepareData() { async prepareData() {
super.prepareData(); super.prepareData();
if ( !this.cardDeck ) { this.checkDeck();
if ( this.hasPlayerOwner) { this.controlScores();
}
/* -------------------------------------------- */
checkDeck() {
if ( !this.cardDeck && this.hasPlayerOwner ) {
this.cardDeck = new SoSCardDeck(); this.cardDeck = new SoSCardDeck();
this.cardDeck.initCardDeck( this, this.data.data.internals.deck ); this.cardDeck.initCardDeck( this, this.data.data.internals.deck );
} else {
this.cardDeck = game.system.sos.gmDeck;
} }
if ( !this.hasPlayerOwner ) {
this.cardDeck = game.system.sos.gmDeck.GMdeck;
console.log("DECK : ", this.cardDeck);
} }
this.controlScores();
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -120,8 +125,8 @@ export class SoSActor extends Actor {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
computeDefense() { computeDefense() {
return { value: Math.ceil((this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value) / 2), return { value: Math.ceil((this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value) / 2) + this.data.data.scores.defense.bonusmalus,
critical: this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value critical: this.data.data.stats.speed.value + this.data.data.stats.perception.value + this.data.data.stats.dexterity.value + this.data.data.scores.defense.bonusmalus
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -132,23 +137,27 @@ export class SoSActor extends Actor {
getEncumbrance( ) { getEncumbrance( ) {
return this.data.data.scores.encumbrance.value; return this.data.data.scores.encumbrance.value;
} }
computeEncumbrance( ) {
return this.data.data.stats.strength.value + this.data.data.scores.encumbrance.bonusmalus;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
computeEdge( ) { computeEdge( ) {
return Math.ceil( (this.data.data.stats.intelligence.value + this.data.data.stats.charisma.value) / 2) + this.data.data.scores.edge.bonus; return Math.ceil( (this.data.data.stats.intelligence.value + this.data.data.stats.charisma.value) / 2) + this.data.data.scores.edge.bonusmalus;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getShock( ) { getShock( ) {
return this.data.data.scores.shock.value; return this.data.data.scores.shock.value;
} }
computeShock() { computeShock() {
return Math.ceil( this.data.data.stats.endurance.value + this.data.data.stats.determination.value + this.data.data.scores.dr.value); return Math.ceil( this.data.data.stats.endurance.value + this.data.data.stats.determination.value + this.data.data.scores.dr.value) + this.data.data.scores.shock.bonusmalus;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getWound( ) { getWound( ) {
return this.data.data.scores.wound.value; return this.data.data.scores.wound.value;
} }
computeWound() { computeWound() {
return Math.ceil( (this.data.data.stats.strength.value + this.data.data.stats.endurance.value) / 2); return Math.ceil( (this.data.data.stats.strength.value + this.data.data.stats.endurance.value) / 2) + this.data.data.scores.wounds.bonusmalus;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -183,7 +192,7 @@ export class SoSActor extends Actor {
} }
// Encumbrance // Encumbrance
if ( this.getEncumbrance() != this.data.data.stats.strength.value ) { if ( this.getEncumbrance() != this.data.data.stats.strength.value ) {
await this.update( {'data.scores.encumbrance.value': this.data.data.stats.strength.value }); await this.update( {'data.scores.encumbrance.value': this.computeEncumbrance() });
} }
// Shock // Shock
if ( this.getShock() != this.computeShock() ) { if ( this.getShock() != this.computeShock() ) {
@ -235,6 +244,7 @@ export class SoSActor extends Actor {
modifierList: SoSUtility.fillRange(-10, +10), modifierList: SoSUtility.fillRange(-10, +10),
tnList: SoSUtility.fillRange(6, 20), tnList: SoSUtility.fillRange(6, 20),
consequencesList: duplicate( this.getApplicableConsequences() ), consequencesList: duplicate( this.getApplicableConsequences() ),
weaknessList: this.data.items.filter( item => item.type == 'weakness' ),
wounds: duplicate( this.data.data.wounds), wounds: duplicate( this.data.data.wounds),
malusConsequence: 0, malusConsequence: 0,
bonusConsequence: 0, bonusConsequence: 0,

4
packs/weaknesses.db Normal file
View File

@ -0,0 +1,4 @@
{"name":"Complication (Wanted)","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"weakness","data":{"subtitle":"","category":"complication","description":""},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/weakness_generic1.svg","effects":[],"_id":"FxCIbJm3T44kC0sG"}
{"name":"Impairment (Limp)","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"weakness","data":{"subtitle":"","category":"impairment","description":""},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/weakness_generic1.svg","effects":[],"_id":"HxPweZ03At9tw6GH"}
{"name":"Shortcoming (Low Pain Treshold)","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"weakness","data":{"subtitle":"","category":"shortcoming","description":""},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/weakness_generic1.svg","effects":[],"_id":"UEHEoNKHUe2hJryO"}
{"name":"Disability (Blind)","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"weakness","data":{"subtitle":"","category":"disability","description":""},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/weakness_generic1.svg","effects":[],"_id":"VDYXsT8AZ6krv93p"}

View File

@ -2,11 +2,11 @@
"name": "foundryvtt-shadows-over-sol", "name": "foundryvtt-shadows-over-sol",
"title": "Shadows over Sol", "title": "Shadows over Sol",
"description": "Shadows over Sol for FoundryVTT", "description": "Shadows over Sol for FoundryVTT",
"version": "0.1.6", "version": "0.1.11",
"manifestPlusVersion": "1.0.0", "manifestPlusVersion": "1.0.0",
"minimumCoreVersion": "0.7.5", "minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9", "compatibleCoreVersion": "0.7.9",
"templateVersion": 18, "templateVersion": 22,
"author": "LeRatierBretonnien", "author": "LeRatierBretonnien",
"esmodules": [ "module/sos-main.js" ], "esmodules": [ "module/sos-main.js" ],
"styles": ["styles/simple.css"], "styles": ["styles/simple.css"],
@ -49,6 +49,15 @@
"path": "./packs/injuries.db", "path": "./packs/injuries.db",
"entity": "Item", "entity": "Item",
"tags" : [ "injury" ] "tags" : [ "injury" ]
},
{
"name": "weaknesses",
"label": "Weaknesses",
"system": "foundryvtt-shadows-over-sol",
"module": "foundryvtt-shadows-over-sol",
"path": "./packs/weaknesses.db",
"entity": "Item",
"tags" : [ "weakness" ]
}, },
{ {
"name": "languages", "name": "languages",

View File

@ -81,40 +81,48 @@
"edge": { "edge": {
"label": "SCORES.Edge", "label": "SCORES.Edge",
"value": 0, "value": 0,
"bonus": 0 "bonusmalus": 0
}, },
"wealth": { "wealth": {
"label": "SCORES.Wealth", "label": "SCORES.Wealth",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"lifestyle": { "lifestyle": {
"label": "SCORES.Lifestyle", "label": "SCORES.Lifestyle",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"defense": { "defense": {
"label": "SCORES.Defense", "label": "SCORES.Defense",
"value": 0, "value": 0,
"critical": 0 "critical": 0,
"bonusmalus": 0
}, },
"dr": { "dr": {
"label": "SCORES.DR", "label": "SCORES.DR",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"shock": { "shock": {
"label": "SCORES.Shock", "label": "SCORES.Shock",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"currentwounds": { "currentwounds": {
"label": "SCORES.Currentwounds", "label": "SCORES.Currentwounds",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"wound": { "wound": {
"label": "SCORES.Wounds", "label": "SCORES.Wounds",
"value": 0 "value": 0,
"bonusmalus": 0
}, },
"encumbrance": { "encumbrance": {
"label": "SCORES.Encumbrance", "label": "SCORES.Encumbrance",
"value": 0 "value": 0,
"bonusmalus": 0
} }
} }
}, },
@ -165,6 +173,7 @@
}, },
"weakness": { "weakness": {
"subtitle": "", "subtitle": "",
"category": "",
"description": "" "description": ""
}, },
"geneline": { "geneline": {

View File

@ -31,6 +31,12 @@
src="systems/foundryvtt-shadows-over-sol/img/icons/{{#if data.editStatSkill}}unlocked.svg{{else}}locked.svg{{/if}}" alt="lock/unlock" src="systems/foundryvtt-shadows-over-sol/img/icons/{{#if data.editStatSkill}}unlocked.svg{{else}}locked.svg{{/if}}" alt="lock/unlock"
>{{#if data.editStatSkill}}Lock{{else}}Unlock{{/if}}</a></span> >{{#if data.editStatSkill}}Lock{{else}}Unlock{{/if}}</a></span>
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="stat flexrow" >
<span class="stat-label flexrow tooltip tooltip-nobottom" name="statlabel">Stat name</span>
<span class="stat-label flexrow tooltip tooltip-nobottom" name="statlabel">Value</span>
<span class="stat-label flexrow tooltip tooltip-nobottom" name="statlabel">XP</span>
</li>
{{#each data.stats as |stat key|}} {{#each data.stats as |stat key|}}
{{#if stat.isLevelUp}} {{#if stat.isLevelUp}}
<li class="stat flexrow xp-level-up" data-attribute="{{key}}"> <li class="stat flexrow xp-level-up" data-attribute="{{key}}">
@ -55,6 +61,11 @@
</div> </div>
<div class="flex-group-left flexcol"> <div class="flex-group-left flexcol">
<ul class="stat-list alternate-list"> <ul class="stat-list alternate-list">
<li class="stat flexrow" >
<span class="generic-label flexrow tooltip tooltip-nobottom" name="statlabel">Score name</span>
<span class="generic-label flexrow tooltip tooltip-nobottom" name="statlabel">Value</span>
<span class="generic-label flexrow tooltip tooltip-nobottom" name="statlabel">Bonus/Malus</span>
</li>
{{#each data.scores as |score key|}} {{#each data.scores as |score key|}}
<li class="stat flexrow list-item" data-attribute="{{key}}"> <li class="stat flexrow list-item" data-attribute="{{key}}">
<span class="generic-label flexrow tooltip tooltip-nobottom" name="data.scores.{{key}}.label">{{localize score.label}}</span> <span class="generic-label flexrow tooltip tooltip-nobottom" name="data.scores.{{key}}.label">{{localize score.label}}</span>
@ -62,9 +73,7 @@
{{#if (eq key 'defense')}} {{#if (eq key 'defense')}}
<input class="stat-value flexrow" type="text" name="data.scores.{{key}}.critical" value="{{score.critical}}" data-dtype="Number" {{#unless @root.data.editStatSkill}}disabled{{/unless}} /> <input class="stat-value flexrow" type="text" name="data.scores.{{key}}.critical" value="{{score.critical}}" data-dtype="Number" {{#unless @root.data.editStatSkill}}disabled{{/unless}} />
{{/if}} {{/if}}
{{#if (eq key 'edge')}} <input class="stat-value flexrow" type="text" name="data.scores.{{key}}.bonusmalus" value="{{score.bonusmalus}}" data-dtype="Number" {{#unless @root.data.editStatSkill}}disabled{{/unless}} />
<input class="stat-value flexrow" type="text" name="data.scores.{{key}}.bonus" value="{{score.bonus}}" data-dtype="Number" {{#unless @root.data.editStatSkill}}disabled{{/unless}} />
{{/if}}
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
@ -313,7 +322,7 @@
</article> </article>
<hr> <hr>
<article class="flexcol"> <article class="flexcol">
<div class="grid grid-2col"> <div class="grid grid-3col">
<div class="flex-group-left flexcol genelang-column"> <div class="flex-group-left flexcol genelang-column">
<span class="description-label">Familiar Subcultures</span> <span class="description-label">Familiar Subcultures</span>
@ -345,6 +354,21 @@
{{/each}} {{/each}}
</ul> </ul>
</div> </div>
<div class="flex-group-left flexcol genelang-column">
<span class="description-label">Weaknesses</span>
<ul class="item-list alternate-list">
{{#each data.weaknessList as |weakness key|}}
<li class="item flexrow list-item" data-item-id="{{weakness._id}}">
<img class="sheet-skill-img" src="{{weakness.img}}"/>
<span class="conseq-label">{{weakness.name}}</span>
<div class="item-controls">
<a class="item-control item-edit" title="Edit Item"><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title="Delete Item"><i class="fas fa-trash"></i></a>
</div>
</li>
{{/each}}
</ul>
</div>
</div> </div>
</article> </article>

View File

@ -51,6 +51,13 @@
<h3 class="dialog-label" id="flipConsequenceBonus">Consequences Bonus : <span id='consequence-bonus'>0</span> </h3> <h3 class="dialog-label" id="flipConsequenceBonus">Consequences Bonus : <span id='consequence-bonus'>0</span> </h3>
</div> </div>
</div> </div>
<div class="flexcol">
<div class="tab" data-group="primary">
{{#each weaknessList as |weakness key|}}
<span class="dialog-label">{{localize weakness.name}} - {{weakness.data.category}}</span>
{{/each}}
</div>
</div>
<div class="flexcol"> <div class="flexcol">
{{#if (gt wounds.light 0)}} {{#if (gt wounds.light 0)}}
<span><label class="dialog-label">Apply Light Wound Malus:</label><input type="checkbox" name="wound-light-checkbox" id="wound-light-checkbox"></span> <span><label class="dialog-label">Apply Light Wound Malus:</label><input type="checkbox" name="wound-light-checkbox" id="wound-light-checkbox"></span>

View File

@ -0,0 +1,35 @@
<form class="{{cssClass}}" autocomplete="off">
<header class="sheet-header">
<img class="profile-img" src="{{item.img}}" data-edit="img" title="{{item.name}}"/>
<div class="header-fields">
<h1 class="charname"><input name="name" type="text" value="{{item.name}}" placeholder="Name"/></h1>
</div>
</header>
{{!-- Sheet Body --}}
<section class="sheet-body">
<div class="tab" data-group="primary">
<div class="flexcol">
<label class="generic-label">Type</label>
<div class="form-group small-editor">
<select class="stat-value flexrow" type="text" name="data.category" value="{{data.category}}" data-dtype="String">
{{#select data.category}}
<option value="impairment">Impairment</option>
<option value="disability">Disablity</option>
<option value="shortcoming">Shortcoming</option>
<option value="complication">Complication</option>
{{/select}}
</select>
</div>
</div>
<div class="flexcol">
<label class="generic-label">Description</label>
<div class="form-group medium-editor">
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div>
</div>
</div>
</section>
</form>