Adds stress-as-counter with max and current value
This commit is contained in:
parent
96b1a3a3b7
commit
c2ff5bd704
11 changed files with 112 additions and 46 deletions
|
@ -1,3 +1,10 @@
|
|||
v2.0
|
||||
- Refactored the Stress to have dynamic Max value
|
||||
- Added Hull
|
||||
- Added Ghost
|
||||
- Added Vampire
|
||||
- Added Logic field to Item, Class and Ability
|
||||
|
||||
v1.2
|
||||
- Non-Turf claims are no longer counted against Rep-Turf limit
|
||||
|
||||
|
@ -11,4 +18,7 @@ v1.0
|
|||
- Added Russian localization (Cododoc)
|
||||
- Added design improvements and quality of life hinting to character sheet (OctarineSourcerer)
|
||||
- Changed the Versioning for easier tracking
|
||||
|
||||
|
||||
|
||||
TODOs:
|
||||
- Remove and Re-add ALL items, when the item is removed to implement logic.
|
13
README.md
13
README.md
|
@ -46,6 +46,19 @@ Crew Types:
|
|||
![alt screen][screenshot_roll_1]
|
||||
![alt screen][screenshot_roll_2]
|
||||
|
||||
## Logic field
|
||||
|
||||
Logic field is a json with params which allows to implement some logic when the Item of corresponding type is added or removed.
|
||||
### Example (from the Vault 1 crew upgrade)
|
||||
`{"attribute":"data.vault.max","operator":"addition","value":4,"requirement":""}`
|
||||
- `attribute` - the attribute to affect
|
||||
- `operator` - what is done to attribute
|
||||
- `value` - the value for operator
|
||||
- `requirement` - is not used
|
||||
|
||||
### Operators list
|
||||
- `addition` - is added when item is attached and substracted when removed
|
||||
|
||||
## To be done in the nearest future
|
||||
- Friends/rivals section
|
||||
- Stress/Harm dynamic values (can be modified by abilities but for now are hardcoded)
|
||||
|
|
|
@ -120,6 +120,9 @@ export class BladesHelpers {
|
|||
|
||||
/**
|
||||
* Undo Item modifications when item is removed.
|
||||
* @todo
|
||||
* - Remove all items and then Add them back to
|
||||
* sustain the logic mods
|
||||
* @param {Object} item_data
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
|
|
|
@ -52,7 +52,7 @@ Hooks.once("init", async function() {
|
|||
|
||||
let html = options.fn(this);
|
||||
|
||||
if (typeof selected != 'undefined') {
|
||||
if (typeof selected !== 'undefined') {
|
||||
selected.forEach(selected_value => {
|
||||
if (selected_value !== false) {
|
||||
const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected_value));
|
||||
|
@ -128,6 +128,22 @@ Hooks.once("init", async function() {
|
|||
return new Handlebars.SafeString(text);;
|
||||
});
|
||||
|
||||
// "N Times" loop for handlebars.
|
||||
// Block is executed N times starting from n=1.
|
||||
//
|
||||
// Usage:
|
||||
// {{#times_from_1 10}}
|
||||
// <span>{{this}}</span>
|
||||
// {{/times_from_1}}
|
||||
Handlebars.registerHelper('times_from_1', function(n, block) {
|
||||
|
||||
var accum = '';
|
||||
for (var i = 1; i <= n; ++i) {
|
||||
accum += block.fn(i);
|
||||
}
|
||||
return accum;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -137,10 +153,10 @@ Hooks.once("ready", function() {
|
|||
|
||||
// Determine whether a system migration is required
|
||||
const currentVersion = game.settings.get("bitd", "systemMigrationVersion");
|
||||
const NEEDS_MIGRATION_VERSION = 1.0;
|
||||
|
||||
const NEEDS_MIGRATION_VERSION = 1.2;
|
||||
|
||||
let needMigration = (currentVersion < NEEDS_MIGRATION_VERSION) || (currentVersion === null);
|
||||
|
||||
|
||||
// Perform the migration
|
||||
if ( needMigration && game.user.isGM ) {
|
||||
migrations.migrateWorld();
|
||||
|
|
|
@ -9,7 +9,7 @@ export const migrateWorld = async function() {
|
|||
for ( let a of game.actors.entities ) {
|
||||
if (a.data.type === 'character') {
|
||||
try {
|
||||
const updateData = _migrateActorSkills(a.data);
|
||||
const updateData = _migrateActor(a.data);
|
||||
if ( !isObjectEmpty(updateData) ) {
|
||||
console.log(`Migrating Actor entity ${a.name}`);
|
||||
await a.update(updateData, {enforceTypes: false});
|
||||
|
@ -32,15 +32,16 @@ export const migrateWorld = async function() {
|
|||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Migrate the actor skills
|
||||
* Migrate the actor attributes
|
||||
* @param {Actor} actor The actor to Update
|
||||
* @return {Object} The updateData to apply
|
||||
*/
|
||||
function _migrateActorSkills(actor) {
|
||||
function _migrateActor(actor) {
|
||||
|
||||
let updateData = {}
|
||||
const attributes = game.system.model.Actor.character.attributes;
|
||||
|
||||
// Migrate Skills
|
||||
const attributes = game.system.model.Actor.character.attributes;
|
||||
for ( let attribute_name of Object.keys(actor.data.attributes || {}) ) {
|
||||
|
||||
// Insert attribute label
|
||||
|
@ -65,6 +66,24 @@ function _migrateActorSkills(actor) {
|
|||
}
|
||||
}
|
||||
|
||||
// Migrate Stress to Array
|
||||
if (typeof actor.data.stress[0] !== 'undefined') {
|
||||
updateData[`data.stress.value`] = actor.data.stress;
|
||||
updateData[`data.stress.max`] = 9;
|
||||
updateData[`data.stress.max_default`] = 9;
|
||||
updateData[`data.stress.name_default`] = "BITD.Stress";
|
||||
updateData[`data.stress.name`] = "BITD.Stress";
|
||||
}
|
||||
|
||||
// Migrate Trauma to Array
|
||||
if (typeof actor.data.trauma === 'undefined') {
|
||||
updateData[`data.trauma.list`] = actor.data.traumas;
|
||||
updateData[`data.trauma.max`] = 4;
|
||||
updateData[`data.trauma.max_default`] = 4;
|
||||
updateData[`data.trauma.name_default`] = "BITD.Trauma";
|
||||
updateData[`data.trauma.name`] = "BITD.Trauma";
|
||||
}
|
||||
|
||||
return updateData;
|
||||
|
||||
// for ( let k of Object.keys(actor.data.attributes || {}) ) {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
{"_id":"8jExf4Zqad6e3bvn","name":"Leech","permission":{"default":0},"type":"class","data":{"description":"A saboteur and technician","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with technical skill or mayhem."},"sort":400000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icons8_64.png"}
|
||||
{"_id":"CAHfNrPDJZKVNMrH","name":"Lurk","permission":{"default":0},"type":"class","data":{"description":"A stealthy infiltrator and burglar","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with stealth or evasion."},"sort":500000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.2_68.png"}
|
||||
{"_id":"Gqx9W2P3YB4ishZB","name":"Ghost","permission":{"default":0,"BwbqQh8sHfeKmUax":3},"type":"class","data":{"description":"A disembodied spirit, craving vengeance","experience_clues":"- You exact vengeance upon those you deem deserving\n- You you express your outrage or anger.","base_skills":{"hunt":[1],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[1],"skirmish":[0],"wreck":[0],"attune":[1],"command":[0],"consort":[0],"sway":[0]}},"sort":100001,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.6_18.png"}
|
||||
{"_id":"JGxBjlbooxuUHe4E","name":"Hound","permission":{"default":0},"type":"class","data":{"description":"A deadly sharpshooter and tracker","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with tracking or violence."},"sort":100000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.3_33.png"}
|
||||
{"_id":"MePRPmnacRts4Wao","name":"Vampire","permission":{"default":0,"BwbqQh8sHfeKmUax":3},"type":"class","data":{"description":"A spirit animating an undead body","experience_clues":"- You display your dominance or slay without mercy (OVERRIDES DEFAULT EXP CLUES).","base_skills":{"hunt":[1],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[1],"skirmish":[1],"wreck":[0],"attune":[1],"command":[1],"consort":[0],"sway":[1]}},"sort":100001,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.1_19.png"}
|
||||
{"_id":"P6LMZBrG5U9eCjhX","name":"Spider","permission":{"default":0},"type":"class","data":{"description":"A devious mastermind","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with calculation or conspiracy."},"sort":700000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.7_60.png"}
|
||||
{"_id":"YUGDdyADj0PTBVcP","name":"Slide","permission":{"default":0},"type":"class","data":{"description":"A subtle manipulator and spy","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with deception or influence."},"sort":600000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.3_39.png"}
|
||||
{"_id":"tEob41rtEbHcswNM","name":"Cutter","permission":{"default":0},"type":"class","data":{"description":"A dangerous & intimidating fighter","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with violence or coercion."},"sort":300000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.2_43.png"}
|
||||
{"_id":"ti2GzB1JlnYAVvBd","name":"Hull","permission":{"default":0,"BwbqQh8sHfeKmUax":3},"type":"class","data":{"description":"A spirit animating a spark-craft frame","experience_clues":"- You fulfill your functions despite difficulty or danger.\n- You suppress or ignore your former human qualities (OVERRIDES DEFAULT EXP CLUES).","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[1],"wreck":[0],"attune":[1],"command":[0],"consort":[0],"sway":[0]}},"sort":100001,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.1_80.png","logic":"{\"attribute\":\"data.stress.max\",\"operator\":\"addition\",\"value\":1,\"requirement\":\"\"}"}
|
||||
{"_id":"zOg14xy8ZEku6bNq","name":"Whisper","permission":{"default":0},"type":"class","data":{"description":"An Arcane adept and channeler","base_skills":{"hunt":[0],"study":[0],"survey":[0],"tinker":[0],"finesse":[0],"prowl":[0],"skirmish":[0],"wreck":[0],"attune":[0],"command":[0],"consort":[0],"sway":[0]},"experience_clues":"- You addressed a challenge with knowledge or arcane power."},"sort":200000,"flags":{},"img":"systems/blades-in-the-dark/styles/assets/icons/Icon.6_88.png"}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"description": "Blades in the dark game system.",
|
||||
"version": "1.2",
|
||||
"minimumCoreVersion": "0.5.3",
|
||||
"compatibleCoreVersion": "0.7.0",
|
||||
"compatibleCoreVersion": "0.7.2",
|
||||
"templateVersion": 1,
|
||||
"author": "megastruktur",
|
||||
"esmodules": [
|
||||
|
|
|
@ -3,8 +3,20 @@
|
|||
"types": ["character", "crew"],
|
||||
"character": {
|
||||
"alias": "",
|
||||
"stress": [0],
|
||||
"traumas": [0],
|
||||
"stress": {
|
||||
"value": [0],
|
||||
"max": 9,
|
||||
"max_default": 9,
|
||||
"name_default": "BITD.Stress",
|
||||
"name": "BITD.Stress"
|
||||
},
|
||||
"trauma": {
|
||||
"max": 4,
|
||||
"max_default": 4,
|
||||
"name": "BITD.Trauma",
|
||||
"name_default": "BITD.Trauma",
|
||||
"list": [0]
|
||||
},
|
||||
"healing-clock": [0],
|
||||
"experience": [0],
|
||||
"coins": [0],
|
||||
|
@ -141,12 +153,12 @@
|
|||
}
|
||||
},
|
||||
"item": {
|
||||
"templates": ["default"],
|
||||
"templates": ["default", "logic"],
|
||||
"class": "",
|
||||
"load": 0
|
||||
},
|
||||
"class": {
|
||||
"templates": ["default"],
|
||||
"templates": ["default", "logic"],
|
||||
"experience_clues": "",
|
||||
"base_skills": {
|
||||
"hunt": [0],
|
||||
|
@ -164,7 +176,7 @@
|
|||
}
|
||||
},
|
||||
"ability": {
|
||||
"templates": ["ability"]
|
||||
"templates": ["ability", "logic"]
|
||||
},
|
||||
"heritage": {
|
||||
"templates": ["default"]
|
||||
|
|
|
@ -92,51 +92,37 @@
|
|||
{{!-- Stress and Trauma --}}
|
||||
<div id="stress-trauma" class="section big-teeth-section">
|
||||
<div id="character-stress" class="big-teeth">
|
||||
{{#multiboxes data.stress}}
|
||||
{{#multiboxes data.stress.value}}
|
||||
|
||||
<input type="radio" id="character-stress-0" name="data.stress" value="0" dtype="Radio">
|
||||
<label class="black-label" for="character-stress-0">{{localize "BITD.Stress"}}</label>
|
||||
<input type="radio" id="character-stress-1" name="data.stress" value="1" dtype="Radio">
|
||||
<label for="character-stress-1"></label>
|
||||
<input type="radio" id="character-stress-2" name="data.stress" value="2" dtype="Radio">
|
||||
<label for="character-stress-2"></label>
|
||||
<input type="radio" id="character-stress-3" name="data.stress" value="3" dtype="Radio">
|
||||
<label for="character-stress-3"></label>
|
||||
<input type="radio" id="character-stress-4" name="data.stress" value="4" dtype="Radio">
|
||||
<label for="character-stress-4"></label>
|
||||
<input type="radio" id="character-stress-5" name="data.stress" value="5" dtype="Radio">
|
||||
<label for="character-stress-5"></label>
|
||||
<input type="radio" id="character-stress-6" name="data.stress" value="6" dtype="Radio">
|
||||
<label for="character-stress-6"></label>
|
||||
<input type="radio" id="character-stress-7" name="data.stress" value="7" dtype="Radio">
|
||||
<label for="character-stress-7"></label>
|
||||
<input type="radio" id="character-stress-8" name="data.stress" value="8" dtype="Radio">
|
||||
<label for="character-stress-8"></label>
|
||||
<input type="radio" id="character-stress-9" name="data.stress" value="9" dtype="Radio">
|
||||
<label for="character-stress-9"></label>
|
||||
<label class="black-label" for="character-stress-0">{{localize data.stress.name}}</label>
|
||||
|
||||
{{#times_from_1 data.stress.max}}
|
||||
<input type="radio" id="character-stress-{{this}}" name="data.stress" value="{{this}}" dtype="Radio">
|
||||
<label for="character-stress-{{this}}"></label>
|
||||
{{/times_from_1}}
|
||||
|
||||
{{/multiboxes}}
|
||||
|
||||
</div>
|
||||
<div id="character-trauma-container" class="small-teeth-container">
|
||||
{{#traumacounter data.traumas}}
|
||||
{{#traumacounter data.trauma.list}}
|
||||
<div id="character-trauma" class="small-teeth-wrap">
|
||||
<label class="black-label" for="character-trauma-counter-0">{{localize "BITD.Trauma"}}</label>
|
||||
<div id="trauma-teeth" class="small-teeth">
|
||||
<input type="radio" id="character-trauma-counter-0" name="trauma-counter" value="0">
|
||||
<input type="radio" id="character-trauma-counter-1" name="trauma-counter" value="1">
|
||||
<label for="character-trauma-counter-1"></label>
|
||||
<input type="radio" id="character-trauma-counter-2" name="trauma-counter" value="2">
|
||||
<label for="character-trauma-counter-2"></label>
|
||||
<input type="radio" id="character-trauma-counter-3" name="trauma-counter" value="3">
|
||||
<label for="character-trauma-counter-3"></label>
|
||||
<input type="radio" id="character-trauma-counter-4" name="trauma-counter" value="4">
|
||||
<label for="character-trauma-counter-4"></label>
|
||||
|
||||
{{#times_from_1 data.trauma.max}}
|
||||
<input type="radio" id="character-trauma-counter-{{this}}" name="trauma-counter" value="{{this}}">
|
||||
<label for="character-trauma-counter-{{this}}"></label>
|
||||
{{/times_from_1}}
|
||||
</div>
|
||||
</div>
|
||||
{{/traumacounter}}
|
||||
</div>
|
||||
|
||||
<div id="trauma-list">
|
||||
{{#multiboxes data.traumas}}
|
||||
{{#multiboxes data.trauma.list}}
|
||||
<label>
|
||||
<input type="checkbox" name="data.traumas" value="cold">
|
||||
<span class="checkmark">{{localize "BITD.TraumaCold"}}</span>
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
<div><i>- {{localize "BITD.ClassExpClue2"}}</i></div>
|
||||
<div><i>- {{localize "BITD.ClassExpClue3"}}</i></div>
|
||||
<textarea name="data.experience_clues">{{data.experience_clues}}</textarea>
|
||||
|
||||
{{isG}}
|
||||
<label class="label-stripe">{{localize "BITD.Logic"}}</label>
|
||||
<textarea name="data.logic">{{data.logic}}</textarea>
|
||||
</section>
|
||||
|
||||
</form>
|
||||
|
|
|
@ -15,6 +15,6 @@
|
|||
<label class="label-stripe">{{localize "BITD.Price"}}</label>
|
||||
<input type="text" name="data.price" value="{{data.price}}">
|
||||
<label class="label-stripe">{{localize "BITD.Logic"}}</label>
|
||||
<textarea name="data.logic">{{data.logic}}</textarea>
|
||||
{{editor content=data.logic target="data.logic" button=true owner=owner editable=editable}}
|
||||
</section>
|
||||
</form>
|
||||
|
|
Reference in a new issue