#6 : Skill experience management

This commit is contained in:
sladecraven 2021-03-12 20:57:41 +01:00
parent 3285bd416e
commit 9d610215d4
12 changed files with 113 additions and 15 deletions

View File

@ -1,10 +1,7 @@
# FoundryVTT - Shadows Over Sol # FoundryVTT - Shadows Over Sol
**STILL IN ALPHA, DO NOT USE IT !!**
Shadows Over Sol ( https://www.tabcreations.com/shadows-over-sol/ ) implementation for FoundryVTT . Shadows Over Sol ( https://www.tabcreations.com/shadows-over-sol/ ) implementation for FoundryVTT .
This system is developed under authorization of Tab Creations. This system is developed under authorization of Tab Creations.
Shadows Over Sol is Property of Tab Creations, all related copyright belongs to Tab Creations. Shadows Over Sol is Property of Tab Creations, all related copyright belongs to Tab Creations.
**STILL IN ALPHA, DO NOT USE IT !!**

View File

@ -1,5 +1,6 @@
[Dolphin] [Dolphin]
Timestamp=2021,3,12,15,41,28.086 SortRole=creationtime
Timestamp=2021,3,12,18,53,49.303
Version=4 Version=4
ViewMode=1 ViewMode=1
VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails

1
img/icons/skill_xp.svg Normal file
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-upgrade-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-upgrade-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="M256 29.816l-231 154v106.368l231-154 231 154V183.816zm0 128.043L105 259.783v90.283l151-101.925 151 101.925v-90.283zm0 112l-87 58.725v67.6l87-58 87 58v-67.6zm0 89.957l-87 58v64.368l87-58 87 58v-64.368z" 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: 851 B

View File

@ -160,6 +160,11 @@ export class SoSActor extends Actor {
return Math.ceil( (this.data.data.stats.strength.value + this.data.data.stats.endurance.value) / 2) + this.data.data.scores.wound.bonusmalus; return Math.ceil( (this.data.data.stats.strength.value + this.data.data.stats.endurance.value) / 2) + this.data.data.scores.wound.bonusmalus;
} }
/* -------------------------------------------- */
getSkillExperience( skillName ) {
return this.data.items.filter( item => item.type == 'skillexperience' && item.data.skill == skillName);
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async wornObject( itemID) { async wornObject( itemID) {
let item = this.getOwnedItem(itemID); let item = this.getOwnedItem(itemID);
@ -262,13 +267,15 @@ export class SoSActor extends Actor {
selectedStat: 'strength', selectedStat: 'strength',
consequencesList: duplicate( this.getApplicableConsequences() ), consequencesList: duplicate( this.getApplicableConsequences() ),
wounds: duplicate( this.data.data.wounds), wounds: duplicate( this.data.data.wounds),
skillExperienceList: this.getSkillExperience( skill.name),
skill: duplicate(skill), skill: duplicate(skill),
actor: this, actor: this,
modifierList: SoSUtility.fillRange(-10, +10), modifierList: SoSUtility.fillRange(-10, +10),
tnList: SoSUtility.fillRange(6, 20), tnList: SoSUtility.fillRange(6, 20),
malusConsequence: 0, malusConsequence: 0,
bonusConsequence: 0, bonusConsequence: 0,
woundMalus: 0 woundMalus: 0,
bonusSkillXP: 0
} }
flipData.statList['nostat'] = { label: "No stat (ie defaulting skills)", value: 0, cardsuit: "none" } 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 renderTemplate('systems/foundryvtt-shadows-over-sol/templates/dialog-flip.html', flipData);
@ -297,6 +304,7 @@ export class SoSActor extends Actor {
target: target, target: target,
selectedStat: selectedStatName, selectedStat: selectedStatName,
consequencesList: duplicate( this.getApplicableConsequences() ), consequencesList: duplicate( this.getApplicableConsequences() ),
skillExperienceList: this.getSkillExperience( skill.name),
wounds: duplicate( this.data.data.wounds), wounds: duplicate( this.data.data.wounds),
skill: duplicate(skill), skill: duplicate(skill),
actor: this, actor: this,
@ -304,7 +312,8 @@ export class SoSActor extends Actor {
tnList: SoSUtility.fillRange(6, 20), tnList: SoSUtility.fillRange(6, 20),
malusConsequence: 0, malusConsequence: 0,
bonusConsequence: 0, bonusConsequence: 0,
woundMalus: 0 woundMalus: 0,
bonusSkillXP: 0
} }
console.log(flipData); console.log(flipData);

View File

@ -45,7 +45,12 @@ export class SoSItemSheet extends ItemSheet {
async getData() { async getData() {
let data = super.getData(); let data = super.getData();
data.isGM = game.user.isGM; data.isGM = game.user.isGM;
if ( data.item.type == 'skillexperience') {
data.skillList = await SoSUtility.loadCompendiumNames("foundryvtt-shadows-over-sol.skills");
}
if ( data.item.type == 'skill' && this.object.options?.actor) {
data.skillExperienceList = this.object.options.actor.getSkillExperience( data.item.name );
}
return data; return data;
} }
@ -57,6 +62,19 @@ export class SoSItemSheet extends ItemSheet {
// Everything below here is only needed if the sheet is editable // Everything below here is only needed if the sheet is editable
if (!this.options.editable) return; if (!this.options.editable) return;
// Update Inventory Item
html.find('.item-edit').click(ev => {
const li = $(ev.currentTarget).parents(".item");
const item = this.object.options.actor.getOwnedItem(li.data("item-id"));
console.log("ITEM", item, li.data("item-id"), li);
item.sheet.render(true);
});
// Update Inventory Item
html.find('.item-delete').click(ev => {
const li = $(ev.currentTarget).parents(".item");
this.object.options.actor.deleteOwnedItem( li.data("item-id") ).then( this.render(true));
//this.render(true);
});
} }

View File

@ -43,6 +43,7 @@ export class SoSFlipDialog extends Dialog {
scoreBase += this.flipData.malusConsequence; scoreBase += this.flipData.malusConsequence;
scoreBase += this.flipData.bonusConsequence; scoreBase += this.flipData.bonusConsequence;
scoreBase += this.flipData.woundMalus; scoreBase += this.flipData.woundMalus;
scoreBase += this.flipData.bonusSkillXP;
$('#wound-malus').text(this.flipData.woundMalus); $('#wound-malus').text(this.flipData.woundMalus);
$('#score-base').text( scoreBase); $('#score-base').text( scoreBase);
} }
@ -74,7 +75,18 @@ export class SoSFlipDialog extends Dialog {
}); });
} }
/* -------------------------------------------- */
updateSkillXPBonus(event) {
this.flipData.skillXPSelected = $('#skillXPBonus').val();
let bonusSkillXP = 0;
for (let skillXPId of this.flipData.skillXPSelected) {
bonusSkillXP += 1;
}
$('#skillxp-bonus').text(bonusSkillXP);
this.flipData.bonusSkillXP = bonusSkillXP;
this.updateScoreBase();
}
/* -------------------------------------------- */ /* -------------------------------------------- */
updateConsequenceMalus(event) { updateConsequenceMalus(event) {
this.flipData.consequencesSelected = $('#consequenceSelectMalus').val(); this.flipData.consequencesSelected = $('#consequenceSelectMalus').val();
@ -122,7 +134,9 @@ export class SoSFlipDialog extends Dialog {
html.find('#statSelect').change((event) => { html.find('#statSelect').change((event) => {
this.updateFlip(dialog.flipData ); this.updateFlip(dialog.flipData );
} ); } );
html.find('#skillXPBonus').change((event) => {
this.updateSkillXPBonus( event );
} );
html.find('#consequenceSelectMalus').change((event) => { html.find('#consequenceSelectMalus').change((event) => {
this.updateConsequenceMalus( event ); this.updateConsequenceMalus( event );
} ); } );

View File

@ -34,7 +34,7 @@ export class SoSUtility extends Entity {
static fillRange (start, end) { static fillRange (start, end) {
return Array(end - start + 1).fill().map((item, index) => start + index); return Array(end - start + 1).fill().map((item, index) => start + index);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static onSocketMesssage( msg ) { static onSocketMesssage( msg ) {
if( !game.user.isGM ) return; // Only GM if( !game.user.isGM ) return; // Only GM

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.12", "version": "0.1.13",
"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": 22, "templateVersion": 23,
"author": "LeRatierBretonnien", "author": "LeRatierBretonnien",
"esmodules": [ "module/sos-main.js" ], "esmodules": [ "module/sos-main.js" ],
"styles": ["styles/simple.css"], "styles": ["styles/simple.css"],

View File

@ -145,7 +145,7 @@
}, },
"Item": { "Item": {
"types": ["gear", "weapon", "armor", "container", "skill", "language", "weakness", "geneline", "types": ["gear", "weapon", "armor", "container", "skill", "language", "weakness", "geneline",
"subculture", "consequence", "action", "injury", "malady", "vehicle" ], "subculture", "consequence", "action", "injury", "malady", "vehicle", "skillexperience"],
"templates": { "templates": {
"commongear": { "commongear": {
"big": 0, "big": 0,

View File

@ -27,6 +27,18 @@
</span> </span>
{{/if}} {{/if}}
</div> </div>
<div class="flexcol">
<div class="tab" data-group="primary">
<select name="skillXPSelect" id="skillXPBonus" data-dtype="String" multiple size="5" width="200">
{{#select skillExperienceList}}
{{#each skillExperienceList as |skillXP key|}}
<option value={{skillXP._id}}>{{skillXP.name}}</option>
{{/each}}
{{/select}}
</select>
<h3 class="dialog-label" id="flipSkillXPBonus">Skill XP Bonus : <span id='skillxp-bonus'>0</span> </h3>
</div>
</div>
<div class="flexcol"> <div class="flexcol">
<div class="tab" data-group="primary"> <div class="tab" data-group="primary">
<select name="consequenceSelect" id="consequenceSelectMalus" data-dtype="String" multiple size="5" width="200"> <select name="consequenceSelect" id="consequenceSelectMalus" data-dtype="String" multiple size="5" width="200">

View File

@ -12,8 +12,20 @@
<div class="tab" data-group="primary"> <div class="tab" data-group="primary">
<ul> <ul>
<li class="flexrow"><label class="generic-label">Value</label><input type="text" name="data.value" value="{{data.value}}" data-dtype="Number"/></li> <li class="flexrow"><label class="generic-label">Value</label><input type="text" name="data.value" value="{{data.value}}" data-dtype="Number"/></li>
<li class="flexrow"><label class="generic-label">XP</label><input type="text" name="data.xp" value="{{data.xp}}" data-dtype="Number"/></li> <ul class="stat-list alternate-list">
</ul> <li class="stat flexrow list-item" data-attribute="{{key}}">
<span class="generic-label flexrow tooltip tooltip-nobottom" name="">Experiences list : </span>
</li>
{{#each skillExperienceList as |skillXP key|}}
<li class="stat flexrow list-item item" data-item-id="{{skillXP._id}}">
<span class="generic-label flexrow tooltip tooltip-nobottom" name="">{{skillXP.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>
<label class="generic-label">Description</label> <label class="generic-label">Description</label>
{{editor content=data.description target="data.description" button=true owner=owner editable=editable}} {{editor content=data.description target="data.description" button=true owner=owner editable=editable}}
</div> </div>

View File

@ -0,0 +1,34 @@
<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.skill" value="{{data.skill}}" data-dtype="String">
{{#select data.skill}}
{{#each skillList as |skill key|}}
<option value="{{skill.name}}">{{skill.name}}</option>
{{/each}}
{{/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>