ENH: Encumbrance bar

master
U~man 2020-07-04 19:34:20 +02:00
parent 86bb4333e2
commit 2c62d33c82
14 changed files with 268 additions and 77 deletions

View File

@ -25,6 +25,7 @@
"OSE.Retainer": "Retainer",
"OSE.Appearing": "NA",
"OSE.Attack": "Attack",
"OSE.Encumbrance": "Encumbrance",
"OSE.Loyalty": "Loyalty Rating",
"OSE.LoyaltyShort": "LR",
@ -116,11 +117,16 @@
"OSE.Setting.THAC0AttacksHint": "Attacks are resolved using the THAC0 value, not compatible with AAC",
"OSE.Setting.VariableWeaponDamage": "Variable Weapon Damage",
"OSE.Setting.VariableWeaponDamageHint": "Weapons have different damage dice",
"OSE.Setting.Encumbrance": "Encumbrance",
"OSE.Setting.EncumbranceHint": "Choose the way encumbrance is calculated",
"OSE.Setting.EncumbranceBasic": "Basic",
"OSE.Setting.EncumbranceDetailed": "Detailed",
"OSE.items.Equip": "Equip",
"OSE.items.Unequip": "Unequip",
"OSE.items.Misc": "Misc",
"OSE.items.Weapons": "Weapons",
"OSE.items.Treasure": "Treasure",
"OSE.items.Armors": "Armors",
"OSE.items.Weight": "Wgt.",
"OSE.items.Qualities": "Qualities",

View File

@ -52,6 +52,35 @@ export class OseActorSheetCharacter extends OseActorSheet {
data.config.individualInit = game.settings.get("ose", "individualInit");
data.mods = this.actor.computeModifiers();
// Compute treasure
let total = 0;
data.owned.items.forEach(item => {
if (item.data.treasure) {
total += item.data.quantity.value * item.data.cost;
}
});
data.treasure = total;
let basic = game.settings.get('ose', 'encumbranceOption') == 'basic';
// Compute encumbrance
let totalWeight = 0;
Object.values(data.owned).forEach(cat => {
cat.forEach(item => {
if (item.type == 'item' && (!basic || item.data.treasure)) {
totalWeight += item.data.quantity.value * item.data.weight;
}
else if (!basic) {
totalWeight += item.data.weight;
}
})
});
data.encumbrance = {
pct: Math.clamped(100 * parseFloat(totalWeight) / data.data.encumbrance.max, 0, 100),
max: data.data.encumbrance.max,
encumbered: totalWeight > data.data.encumbrance.max,
value: totalWeight
};
return data;
}

View File

@ -17,7 +17,7 @@ export const registerHelpers = async function () {
});
Handlebars.registerHelper("mult", function (lh, rh) {
return parseInt(lh) * parseInt(rh);
return parseFloat(lh) * parseFloat(rh);
});
Handlebars.registerHelper("counter", function (status, value, max) {

View File

@ -1,38 +1,51 @@
export const registerSettings = function () {
game.settings.register('ose', 'individualInit', {
name: game.i18n.localize('OSE.Setting.IndividualInit'),
hint: game.i18n.localize('OSE.Setting.IndividualInitHint'),
default: false,
scope: 'world',
type: Boolean,
config: true
});
game.settings.register("ose", "individualInit", {
name: game.i18n.localize("OSE.Setting.IndividualInit"),
hint: game.i18n.localize("OSE.Setting.IndividualInitHint"),
default: false,
scope: "world",
type: Boolean,
config: true,
});
game.settings.register('ose', 'ascendingAC', {
name: game.i18n.localize('OSE.Setting.AscendingAC'),
hint: game.i18n.localize('OSE.Setting.AscendingACHint'),
default: false,
scope: 'world',
type: Boolean,
config: true
});
game.settings.register("ose", "ascendingAC", {
name: game.i18n.localize("OSE.Setting.AscendingAC"),
hint: game.i18n.localize("OSE.Setting.AscendingACHint"),
default: false,
scope: "world",
type: Boolean,
config: true,
});
game.settings.register('ose', 'morale', {
name: game.i18n.localize('OSE.Setting.Morale'),
hint: game.i18n.localize('OSE.Setting.MoraleHint'),
default: false,
scope: 'world',
type: Boolean,
config: true
});
game.settings.register("ose", "morale", {
name: game.i18n.localize("OSE.Setting.Morale"),
hint: game.i18n.localize("OSE.Setting.MoraleHint"),
default: false,
scope: "world",
type: Boolean,
config: true,
});
game.settings.register('ose', 'variableWeaponDamage', {
name: game.i18n.localize('OSE.Setting.VariableWeaponDamage'),
hint: game.i18n.localize('OSE.Setting.VariableWeaponDamageHint'),
default: false,
scope: 'world',
type: Boolean,
config: true
});
}
game.settings.register("ose", "variableWeaponDamage", {
name: game.i18n.localize("OSE.Setting.VariableWeaponDamage"),
hint: game.i18n.localize("OSE.Setting.VariableWeaponDamageHint"),
default: false,
scope: "world",
type: Boolean,
config: true,
});
game.settings.register("ose", "encumbranceOption", {
name: game.i18n.localize("OSE.Setting.Encumbrance"),
hint: game.i18n.localize("OSE.Setting.EncumbranceHint"),
default: false,
scope: "world",
type: String,
config: true,
default: "detailed",
choices: {
basic: "OSE.Setting.EncumbranceBasic",
detailed: "OSE.Setting.EncumbranceDetailed",
},
});
};

View File

@ -137,11 +137,12 @@
}
.attribute-mod {
position: absolute;
color: $colorTan;
color: $colorFaint;
text-shadow: 0 0 2px black;
right: 1px;
top: 1px;
line-height: 10px;
font-size: 10px;
font-size: 8px;
}
.attribute-bonuses {
display: none;
@ -196,7 +197,7 @@
}
.item-titles {
text-align: center;
padding: 4px;
padding: 4px 0;
border: 1px solid $colorDark;
box-shadow: 0 0 5px $colorDark;
.item-name {
@ -298,7 +299,7 @@
}
.item-controls {
font-size: 12px;
flex-basis: 60px;
flex-basis: 50px;
flex-grow: 0;
text-align: right;
margin-right: 4px;

View File

@ -81,6 +81,68 @@
}
}
}
/* Encumbrance Bar */
.encumbrance {
height: 12px;
background: $darkBackground;
margin: 1px 15px 0 1px;
border: 1px solid $colorDark;
border-radius: 3px;
position: relative;
.encumbrance-bar {
position: absolute;
background: rgba(255, 0, 0, 0.6);
height: 10px;
border: 1px solid #777;
border-radius: 2px;
}
.encumbrance-label {
height: 10px;
padding: 0 5px;
position: absolute;
top: 0;
right: 10px;
font-size: 13px;
line-height: 12px;
text-align: right;
color: #EEE;
text-shadow: 0 0 5px #000;
}
.encumbrance-breakpoint {
display: block;
position: absolute;
&.encumbrance-25 { left: 25% }
&.encumbrance-50 { left: 50% }
&.encumbrance-75 { left: 75% }
}
.arrow-up {
bottom: 0;
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-bottom: 4px solid $colorFaint;
}
.arrow-down {
top: 0;
width: 0;
height: 0;
border-left: 4px solid transparent;
border-right: 4px solid transparent;
border-top: 4px solid $colorFaint;
}
&.encumbered {
.arrow-up { border-bottom: 4px solid $colorDark; }
.arrow-down { border-top: 4px solid $colorDark; }
}
}
/* ----------------------------------------- */
/* Item Controls */
/* ----------------------------------------- */

View File

@ -5,7 +5,7 @@
$darkBackground: url('/systems/ose/assets/back.png');
$colorDark: rgba(0, 0, 0, 0.9);
$colorFaint: #c9c7b8;
$colorFaint: #d8d6c9;
$colorBeige: #b5b3a4;
$colorTan: #7a7971;
$colorOlive: #4b4a44;

View File

@ -13,12 +13,10 @@
"max": 20
},
"ac": {
"naked": 0,
"value": 0,
"mod": 0
},
"aac": {
"naked": 0,
"value": 0,
"mod": 0
},
@ -118,15 +116,13 @@
"mod": 0
}
},
"currency": {
"gold": 0,
"silver": 0,
"copper": 0
},
"initative": {
"value": 0,
"mod": 0
},
"encumbrance": {
"max": 1600
},
"languages": []
},
"monster": {
@ -151,6 +147,7 @@
"value": 1,
"max": 0
},
"treasure": false,
"cost": 0,
"weight": 80
},

View File

@ -71,6 +71,18 @@
/>
</div>
</div>
<div class="form-group">
<label>{{localize "OSE.Encumbrance"}}</label>
<div class="form-fields">
<input
type="text"
name="data.encumbrance.max"
id="encumbrance"
value="{{data.encumbrance.max}}"
data-dtype="Number"
/>
</div>
</div>
{{/if}}
<footer class="sheet-footer">
<button type="submit">

View File

@ -8,12 +8,12 @@
<div class="attribute-value">
<input name="data.scores.str.value" type="text" value="{{data.scores.str.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.Melee'}} ({{mods.str}})<br/>
{{localize 'OSE.exploration.od.long'}}
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
<li class="attribute ability-score" data-score="int">
@ -22,12 +22,12 @@
<div class="attribute-value">
<input name="data.scores.int.value" type="text" value="{{data.scores.int.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.SpokenLanguages'}}<br/>
{{localize 'OSE.Literacy'}}
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
<li class="attribute ability-score" data-score="wis">
@ -36,11 +36,11 @@
<div class="attribute-value">
<input name="data.scores.wis.value" type="text" value="{{data.scores.wis.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.saves.magic.long'}}({{mods.wis}})
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
<li class="attribute ability-score" data-score="dex">
@ -49,13 +49,13 @@
<div class="attribute-value">
<input name="data.scores.dex.value" type="text" value="{{data.scores.dex.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.Missile'}} ({{mods.dex}})<br/>
{{localize 'OSE.Initiative'}} ({{mods.init}})<br/>
{{localize 'OSE.ArmorClass'}} ({{mods.dex}})
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
<li class="attribute ability-score" data-score="con">
@ -64,11 +64,11 @@
<div class="attribute-value">
<input name="data.scores.con.value" type="text" value="{{data.scores.con.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.Health'}} ({{mods.con}})
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
<li class="attribute ability-score" data-score="cha">
@ -77,17 +77,17 @@
<div class="attribute-value">
<input name="data.scores.cha.value" type="text" value="{{data.scores.cha.value}}" placeholder="0"
data-dtype="Number" />
<span class="attribute-mod"><a><i class="fas fa-plus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
<div class="attribute-bonuses">
{{localize 'OSE.NPCReaction'}} ({{mods.npc}})<br/>
{{localize 'OSE.RetainersMax'}} ({{add mods.cha 4}})<br/>
{{localize 'OSE.Loyalty'}} ({{add mods.cha 7}})
<span class="attribute-mod"><a><i class="fas fa-minus"></i></a></span>
<span class="attribute-mod"><a><i class="fas fa-circle"></i></a></span>
</div>
</li>
{{#if data.retainer.enabled}}
<li class="attribute">
<li class="attribute ability-score">
<h4 class="attribute-name box-title" title="{{ localize 'OSE.Loyalty' }}">
{{ localize "OSE.LoyaltyShort" }}
</h4>

View File

@ -3,9 +3,10 @@
<li class="item-titles flexrow">
<div class="item-name">{{localize "OSE.items.Weapons"}}</div>
<div class="field-longer">{{localize "OSE.items.Qualities"}}</div>
<div class="field-short">{{localize "OSE.items.Weight"}}</div>
<div class="field-short"><i class="fas fa-weight-hanging"></i></div>
<div class="item-controls">
<a class="item-control item-create" data-type="weapon" title="{{localize 'OSE.Add'}}"><i class="fa fa-plus"></i></a>
<a class="item-control item-create" data-type="weapon" title="{{localize 'OSE.Add'}}"><i
class="fa fa-plus"></i></a>
</div>
</li>
<ol class="item-list">
@ -49,9 +50,10 @@
{{else}}
<div class="field-short">{{localize "OSE.items.ArmorAC"}}</div>
{{/if}}
<div class="field-short">{{localize "OSE.items.Weight"}}</div>
<div class="field-short"><i class="fas fa-weight-hanging"></i></div>
<div class="item-controls">
<a class="item-control item-create" data-type="armor" title="{{localize 'OSE.Add'}}"><i class="fa fa-plus"></i></a>
<a class="item-control item-create" data-type="armor" title="{{localize 'OSE.Add'}}"><i
class="fa fa-plus"></i></a>
</div>
</li>
<ol class="item-list">
@ -68,9 +70,9 @@
</div>
<div class="field-short">
{{#if config.ascendingAC}}
{{item.data.aac}}
{{item.data.aac.value}}
{{else}}
{{item.data.ac}}
{{item.data.ac.value}}
{{/if}}
</div>
<div class="field-short">
@ -92,16 +94,19 @@
</ol>
</div>
<div class="">
{{!-- Misc items --}}
<li class="item-titles flexrow">
<div class="item-name">{{localize "OSE.items.Misc"}}</div>
<div class="field-short">{{localize "OSE.items.Quantity"}}</div>
<div class="field-short">{{localize "OSE.items.Weight"}}</div>
<div class="field-short"><i class="fas fa-hashtag"></i></div>
<div class="field-short"><i class="fas fa-weight-hanging"></i></div>
<div class="item-controls">
<a class="item-control item-create" data-type="item" title="{{localize 'OSE.Add'}}"><i class="fa fa-plus"></i></a>
<a class="item-control item-create" data-type="item" title="{{localize 'OSE.Add'}}"><i
class="fa fa-plus"></i></a>
</div>
</li>
<ol class="item-list">
{{#each owned.items as |item|}}
{{#unless item.data.treasure}}
<li class="item-entry">
<div class="item flexrow" data-item-id="{{item._id}}">
<div class="item-name flexrow">
@ -117,7 +122,7 @@
placeholder="0" />{{#if item.data.quantity.max}}<span>/{{item.data.quantity.max}}</span>{{/if}}
</div>
<div class="field-short">
{{item.data.weight}}
{{mult item.data.quantity.value item.data.weight}}
</div>
<div class="item-controls">
{{#if ../owner}}
@ -127,7 +132,67 @@
</div>
</div>
</li>
{{/unless}}
{{/each}}
</ol>
</div>
<div class="">
{{!-- Treasure items --}}
<li class="item-titles flexrow">
<div class="item-name">{{localize "OSE.items.Treasure"}}</div>
<div class="field-long">{{treasure}} <i class="fas fa-circle"></i></div>
<div class="field-short"><i class="fas fa-hashtag"></i></div>
<div class="field-short"><i class="fas fa-weight-hanging"></i></div>
<div class="item-controls">
<a class="item-control item-create" data-type="item" title="{{localize 'OSE.Add'}}"><i
class="fa fa-plus"></i></a>
</div>
</li>
<ol class="item-list">
{{#each owned.items as |item|}}
{{#if item.data.treasure}}
<li class="item-entry">
<div class="item flexrow" data-item-id="{{item._id}}">
<div class="item-name flexrow">
<div class="item-image" style="background-image: url({{item.img}})"></div>
<a>
<h4 title="{{item.name}}">
{{item.name~}}
</h4>
</a>
</div>
<div class="field-long">{{mult item.data.quantity.value item.data.cost}}</div>
<div class="field-short quantity">
<input value="{{item.data.quantity.value}}" type="text"
placeholder="0" />{{#if item.data.quantity.max}}<span>/{{item.data.quantity.max}}</span>{{/if}}
</div>
<div class="field-short">
{{mult item.data.quantity.value item.data.weight}}
</div>
<div class="item-controls">
{{#if ../owner}}
<a class="item-control item-edit" title='{{localize "OSE.Edit"}}'><i class="fas fa-edit"></i></a>
<a class="item-control item-delete" title='{{localize "OSE.Delete"}}'><i class="fas fa-trash"></i></a>
{{/if}}
</div>
</div>
</li>
{{/if}}
{{/each}}
</ol>
</div>
</section>
<section>
{{#with encumbrance}}
<div class="encumbrance {{#if encumbered}}encumbered{{/if}}">
<span class="encumbrance-bar" style="width:{{pct}}%"></span>
<span class="encumbrance-label">{{value}} / {{max}}</span>
<i class="encumbrance-breakpoint encumbrance-25 arrow-up"></i>
<i class="encumbrance-breakpoint encumbrance-25 arrow-down"></i>
<i class="encumbrance-breakpoint encumbrance-50 arrow-up"></i>
<i class="encumbrance-breakpoint encumbrance-50 arrow-down"></i>
<i class="encumbrance-breakpoint encumbrance-75 arrow-up"></i>
<i class="encumbrance-breakpoint encumbrance-75 arrow-down"></i>
{{/with}}
</div>
</section>

View File

@ -13,13 +13,13 @@
<div class="form-group">
<label>{{localize 'OSE.items.ArmorAC'}}</label>
<div class="form-fields">
<input type="text" name="data.level" value="{{data.ac}}" data-dtype="Number" />
<input type="text" name="data.ac.value" value="{{data.ac.value}}" data-dtype="Number" />
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.ArmorAAC'}}</label>
<div class="form-fields">
<input type="text" name="data.class" value="{{data.aac}}" data-dtype="Number" />
<input type="text" name="data.aac.value" value="{{data.aac.value}}" data-dtype="Number" />
</div>
</div>
<div class="form-group">

View File

@ -16,6 +16,12 @@
<input type="text" name="data.quantity.value" value="{{data.quantity.value}}" data-dtype="Number" />/<input type="text" name="data.quantity.max" value="{{data.quantity.max}}" data-dtype="Number" />
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.Treasure'}}</label>
<div class="form-fields">
<input type="checkbox" name="data.treasure" value="{{data.treasure}}" {{checked data.treasure}} data-dtype="Boolean"/>
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.Cost'}}</label>
<div class="form-fields">
@ -25,7 +31,7 @@
<div class="form-group">
<label>{{localize 'OSE.items.Weight'}}</label>
<div class="form-fields">
<input type="text" name="data.weight" value="{{data.weight}}" data-dtype="String" />
<input type="text" name="data.weight" value="{{data.weight}}" data-dtype="Number" />
</div>
</div>
</div>

View File

@ -9,7 +9,7 @@
</header>
<section class="sheet-body">
<div class="flexrow">
<input name="data.qualities" type="text" value="{{data.qualities}}" placeholder="Qualities" />
<input name="data.qualities" type="text" value="{{data.qualities}}" placeholder="Qualities" data-dtype="String"/>
</div>
<div class="flexrow">
<div class="stats">
@ -22,19 +22,19 @@
<div class="form-group">
<label>{{localize 'OSE.items.Slow'}}</label>
<div class="form-fields">
<input type="checkbox" name="data.slow" value="{{data.level}}" {{checked data.slow}} />
<input type="checkbox" name="data.slow" value="{{data.slow}}" {{checked data.slow}} data-dtype="Number"/>
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.Missile'}}</label>
<div class="form-fields">
<input type="checkbox" name="data.missile" {{checked data.missile}} />
<input type="checkbox" name="data.missile" {{checked data.missile}} data-dtype="Number"/>
</div>
</div>
<div class="form-group">
<label>{{localize 'OSE.items.Melee'}}</label>
<div class="form-fields">
<input type="checkbox" name="data.melee" {{checked data.melee}} />
<input type="checkbox" name="data.melee" {{checked data.melee}} data-dtype="Boolean"/>
</div>
</div>
<div class="form-group">