Compare commits
46 Commits
fvtt-dark-
...
main
Author | SHA1 | Date | |
---|---|---|---|
e92b2deacf | |||
dc4429f3e1 | |||
92684b0d32 | |||
9786c07f1b | |||
2520bec30f | |||
9ad34b4672 | |||
ae36be975d | |||
69eaa8fc66 | |||
b741cffd96 | |||
e5296a4bcd | |||
9f93849a9d | |||
14c7e54b3d | |||
ce3359b2f0 | |||
02bf6cc10a | |||
dc5a1056b7 | |||
c7ccc50db0 | |||
1f8275e153 | |||
e19e6df228 | |||
714485b688 | |||
ceed6efc0b | |||
06e265586b | |||
78edf6b80b | |||
60112d1a79 | |||
652f24b863 | |||
69322cccfe | |||
5d0c53f52b | |||
9557f18eb2 | |||
c3758da16b | |||
7dbc5e44b7 | |||
880109f189 | |||
2dbf8fc336 | |||
9b7519afa7 | |||
285d095d91 | |||
79333f8b14 | |||
5477e2be4b | |||
f98852c69f | |||
32b5868646 | |||
606271e725 | |||
2da3d19dbe | |||
7ceada98fb | |||
580b044c77 | |||
83119a2b82 | |||
04365a93d0 | |||
5f36a58805 | |||
55a2d3f4d4 | |||
4d6c0cdc4a |
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
.vscode/settings.json
|
||||
.idea
|
||||
.history
|
||||
todo.md
|
||||
/.vscode
|
||||
/ignored/
|
||||
/node_modules/
|
||||
/jsconfig.json
|
||||
/package.json
|
||||
/package-lock.json
|
BIN
images/icons/magic.webp
Normal file
BIN
images/icons/magic.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
BIN
images/icons/psychicpowers.webp
Normal file
BIN
images/icons/psychicpowers.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
19
lang/en.json
19
lang/en.json
@ -1,3 +1,20 @@
|
||||
{
|
||||
|
||||
"TYPES": {
|
||||
"Actor": {
|
||||
"character": "Character"
|
||||
},
|
||||
"Item": {
|
||||
"armor": "Armor",
|
||||
"weapon": "Weapon",
|
||||
"equipment": "Equipment",
|
||||
"skill": "Skill",
|
||||
"perk": "Perk",
|
||||
"ability": "Ability",
|
||||
"cumulativetask": "Cumulative Task",
|
||||
"genetic": "Genetic",
|
||||
"money": "Money",
|
||||
"cyber": "Cyber",
|
||||
"ammo": "Ammo"
|
||||
}
|
||||
}
|
||||
}
|
@ -11,12 +11,12 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-dark-stars", "sheet", "actor"],
|
||||
template: "systems/fvtt-dark-stars/templates/actor-sheet.hbs",
|
||||
template: "systems/fvtt-dark-stars/templates/actors/actor-sheet.hbs",
|
||||
width: 960,
|
||||
height: 720,
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "skills" }],
|
||||
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "main" }],
|
||||
dragDrop: [{ dragSelector: ".item-list .item", dropSelector: null }],
|
||||
editScore: true
|
||||
});
|
||||
@ -25,7 +25,7 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = this.object.system
|
||||
let actorData = duplicate(objectData)
|
||||
let actorData = foundry.utils.duplicate(objectData)
|
||||
|
||||
let formData = {
|
||||
title: this.title,
|
||||
@ -35,24 +35,27 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
name: this.actor.name,
|
||||
editable: this.isEditable,
|
||||
cssClass: this.isEditable ? "editable" : "locked",
|
||||
data: actorData,
|
||||
system: actorData,
|
||||
limited: this.object.limited,
|
||||
skills: this.actor.getSkills( ),
|
||||
weapons: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getWeapons()) ),
|
||||
armors: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getArmors())),
|
||||
shields: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getShields())),
|
||||
spells: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getLore())),
|
||||
equipments: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquipmentsOnly()) ),
|
||||
equippedWeapons: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquippedWeapons()) ),
|
||||
perks: this.actor.getPerks( ),
|
||||
weapons: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getWeapons()) ),
|
||||
ammos: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getAmmos()) ),
|
||||
spells: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getSpells()) ),
|
||||
powers: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getPowers()) ),
|
||||
armors: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getArmors())),
|
||||
shields: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getShields())),
|
||||
equipments: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getEquipmentsOnly()) ),
|
||||
equippedWeapons: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getEquippedWeapons()) ),
|
||||
cybers: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getCybers()) ),
|
||||
genetics: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getGenetics()) ),
|
||||
equippedArmor: this.actor.getEquippedArmor(),
|
||||
equippedShield: this.actor.getEquippedShield(),
|
||||
feats: duplicate(this.actor.getFeats()),
|
||||
subActors: duplicate(this.actor.getSubActors()),
|
||||
race: duplicate(this.actor.getRace()),
|
||||
moneys: duplicate(this.actor.getMoneys()),
|
||||
subActors: foundry.utils.duplicate(this.actor.getSubActors()),
|
||||
encCapacity: this.actor.getEncumbranceCapacity(),
|
||||
saveRolls: this.actor.getSaveRoll(),
|
||||
conditions: this.actor.getConditions(),
|
||||
extendedTests: this.actor.getExtendedTests(),
|
||||
config: game.system.darkstars.config,
|
||||
description: await TextEditor.enrichHTML(this.object.system.biodata.description, {async: true}),
|
||||
notes: await TextEditor.enrichHTML(this.object.system.biodata.notes, {async: true}),
|
||||
containersTree: this.actor.containersTree,
|
||||
@ -98,17 +101,6 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
this.actor.createEmbeddedDocuments('Item', [{ name: "NewItem", type: dataType }], { renderSheet: true })
|
||||
})
|
||||
|
||||
html.find('.equip-activate').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
let itemId = li.data("item-id")
|
||||
this.actor.equipActivate( itemId)
|
||||
});
|
||||
html.find('.equip-deactivate').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
let itemId = li.data("item-id")
|
||||
this.actor.equipDeactivate( itemId)
|
||||
});
|
||||
|
||||
html.find('.subactor-edit').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
let actorId = li.data("actor-id");
|
||||
@ -121,6 +113,17 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
let actorId = li.data("actor-id");
|
||||
this.actor.delSubActor(actorId);
|
||||
});
|
||||
|
||||
html.find('.edit-weapon-ammo').change(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item")
|
||||
let weaponId = li.data("item-id")
|
||||
this.actor.setWeaponAmmo( weaponId, ev.currentTarget.value )
|
||||
})
|
||||
html.find('.skill-used-id').change(event => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
this.actor.setSkillUsed( li.data("item-id"), event.currentTarget.checked );
|
||||
} );
|
||||
|
||||
html.find('.quantity-minus').click(event => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
this.actor.incDecQuantity( li.data("item-id"), -1 );
|
||||
@ -139,35 +142,31 @@ export class DarkStarsActorSheet extends ActorSheet {
|
||||
this.actor.incDecAmmo( li.data("item-id"), +1 )
|
||||
} );
|
||||
|
||||
html.find('.roll-ability').click((event) => {
|
||||
const abilityKey = $(event.currentTarget).data("ability-key");
|
||||
this.actor.rollAbility(abilityKey);
|
||||
});
|
||||
html.find('.roll-skill').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const skillId = li.data("item-id")
|
||||
this.actor.rollSkill(skillId)
|
||||
});
|
||||
html.find('.roll-attribute').click((event) => {
|
||||
const attrKey = $(event.currentTarget).data("attr-key")
|
||||
this.actor.rollAttribute(attrKey)
|
||||
})
|
||||
html.find('.start-extended-test').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const skillId = li.data("item-id")
|
||||
this.actor.rollSkill(skillId, true)
|
||||
})
|
||||
html.find('.roll-extended-test').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item")
|
||||
const testId = li.data("item-id")
|
||||
this.actor.continueExtendedTest(testId)
|
||||
})
|
||||
|
||||
html.find('.roll-weapon').click((event) => {
|
||||
const li = $(event.currentTarget).parents(".item");
|
||||
const skillId = li.data("item-id")
|
||||
this.actor.rollWeapon(skillId)
|
||||
});
|
||||
html.find('.roll-armor-die').click((event) => {
|
||||
this.actor.rollArmorDie()
|
||||
});
|
||||
html.find('.roll-shield-die').click((event) => {
|
||||
this.actor.rollShieldDie()
|
||||
});
|
||||
html.find('.roll-target-die').click((event) => {
|
||||
this.actor.rollDefenseRanged()
|
||||
});
|
||||
|
||||
html.find('.roll-save').click((event) => {
|
||||
const saveKey = $(event.currentTarget).data("save-key")
|
||||
this.actor.rollSave(saveKey)
|
||||
});
|
||||
|
||||
|
||||
html.find('.lock-unlock-sheet').click((event) => {
|
||||
|
@ -43,8 +43,6 @@ export class DarkStarsActor extends Actor {
|
||||
}
|
||||
|
||||
if (data.type == 'character') {
|
||||
const skills = await DarkStarsUtility.loadCompendium("fvtt-dark-stars.skills");
|
||||
data.items = skills.map(i => i.toObject())
|
||||
}
|
||||
if (data.type == 'npc') {
|
||||
}
|
||||
@ -64,26 +62,35 @@ export class DarkStarsActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
computeHitPoints() {
|
||||
if (this.type == "character") {
|
||||
let hp = duplicate(this.system.secondary.hp)
|
||||
let max = (this.system.abilities.str.value + this.system.abilities.con.value) * 6
|
||||
if (max != hp.max || hp.value > max) {
|
||||
hp.max = max
|
||||
hp.value = max // Init case
|
||||
this.update({ 'system.secondary.hp': hp })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
computeEffortPoints() {
|
||||
if (this.type == "character") {
|
||||
let effort = duplicate(this.system.secondary.effort)
|
||||
let max = (this.system.abilities.con.value + this.system.abilities.int.value) * 6
|
||||
if (max != effort.max || effort.value > max) {
|
||||
effort.max = max
|
||||
effort.value = max // Init case
|
||||
this.update({ 'system.secondary.effort': effort })
|
||||
}
|
||||
computeDerivated() {
|
||||
let attr = this.system.attributes
|
||||
let deriv = this.system.derivated
|
||||
let secondary = this.system.secondary
|
||||
|
||||
deriv.csb.value = Math.round((attr.dex.value + attr.sel.value) / 2) + deriv.csb.bonus
|
||||
deriv.asb.value = Math.round((attr.int.value + attr.edu.value) / 2) + deriv.asb.bonus
|
||||
deriv.ssb.value = Math.round((attr.cha.value + attr.emp.value + attr.att.value) / 3) + deriv.ssb.bonus
|
||||
deriv.msb.value = Math.round((attr.con.value + attr.str.value ) / 2) + deriv.msb.bonus
|
||||
deriv.psb.value = Math.round((attr.str.value + attr.dex.value + attr.con.value) / 3) + deriv.psb.bonus
|
||||
|
||||
deriv.ego.value = attr.str.value + attr.cha.value + attr.sel.value + attr.emp.value + deriv.ego.bonus
|
||||
deriv.hup.value = (attr.emp.value * 10) + deriv.hup.bonus
|
||||
deriv.ss.value = (attr.edu.value * 10) + (attr.int.value * 10) + 250 + deriv.ss.bonus
|
||||
|
||||
deriv.mcdb.value = Math.round( (attr.str.value + attr.siz.value) / 4) + deriv.mcdb.bonus
|
||||
deriv.si.value = Math.round( ((attr.dex.value + attr.sel.value) / 5) + 0.5) + deriv.si.bonus
|
||||
|
||||
secondary.hp.max = ((attr.con.value + attr.siz.value ) * 2) + secondary.hp.bonus
|
||||
for(let key in this.system.hitlocations) {
|
||||
let loc = this.system.hitlocations[key]
|
||||
loc.max = Math.floor(secondary.hp.max * loc.ratio)
|
||||
}
|
||||
|
||||
secondary.fp.max = 10 + attr.str.value + attr.con.value + secondary.fp.bonus
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -91,9 +98,9 @@ export class DarkStarsActor extends Actor {
|
||||
|
||||
if (this.type == 'character' || game.user.isGM) {
|
||||
this.system.encCapacity = this.getEncumbranceCapacity()
|
||||
this.computeDerivated()
|
||||
this.buildContainerTree()
|
||||
this.computeHitPoints()
|
||||
this.computeEffortPoints()
|
||||
}
|
||||
|
||||
super.prepareDerivedData();
|
||||
@ -110,73 +117,72 @@ export class DarkStarsActor extends Actor {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getMoneys() {
|
||||
let comp = this.items.filter(item => item.type == 'money');
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFeats() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'feat') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getFeatsWithDie() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'feat' && item.system.isfeatdie) || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getFeatsWithSL() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'feat' && item.system.issl) || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getLore() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'spell') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getEquippedWeapons() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'weapon' && item.system.equipped) || []);
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'weapon' && item.system.equipped) || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getArmors() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'armor') || []);
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'armor') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getSpells() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'spell') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getPowers() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'psychic') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getExtendedTests() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'extendedtest') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getEquippedArmor() {
|
||||
let comp = this.items.find(item => item.type == 'armor' && item.system.equipped)
|
||||
if (comp) {
|
||||
return duplicate(comp)
|
||||
return foundry.utils.duplicate(comp)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getCybers() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'cyber') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getGenetics() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'genetic') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getShields() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'shield') || []);
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'shield') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
getEquippedShield() {
|
||||
let comp = this.items.find(item => item.type == 'shield' && item.system.equipped)
|
||||
if (comp) {
|
||||
return duplicate(comp)
|
||||
return foundry.utils.duplicate(comp)
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getRace() {
|
||||
let race = this.items.filter(item => item.type == 'race')
|
||||
return race[0] ?? [];
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
checkAndPrepareEquipment(item) {
|
||||
// Dynamic assign ammo for the weapon
|
||||
if (item.type == "weapon" && item.system.needammo) {
|
||||
let ammo = this.items.find(ammo => ammo.type == "ammo" && item.system.ammoid == ammo.id)
|
||||
if (ammo) {
|
||||
item.ammo = foundry.utils.duplicate(ammo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -189,46 +195,78 @@ export class DarkStarsActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getConditions() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'condition') || []);
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'condition') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getWeapons() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'weapon') || []);
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'weapon') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getItemById(id) {
|
||||
let item = this.items.find(item => item.id == id);
|
||||
if (item) {
|
||||
item = duplicate(item)
|
||||
getAmmos() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'ammo') || []);
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getItemById(id, duplicate = true) {
|
||||
let item = this.items.find(it => it.id == id)
|
||||
if (item && duplicate) {
|
||||
item = foundry.utils.duplicate(item)
|
||||
}
|
||||
return item;
|
||||
return item
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getItem(id) {
|
||||
let item = this.items.get(id)
|
||||
return item
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
setWeaponAmmo(weaponId, ammoId) {
|
||||
let weapon = this.items.get(weaponId)
|
||||
if(weapon) {
|
||||
this.updateEmbeddedDocuments('Item', [ {_id: weapon.id, 'system.ammoid': ammoId} ])
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
setSkillUsed( skillId, checked) {
|
||||
let skill = this.items.get(skillId)
|
||||
if(skill) {
|
||||
this.updateEmbeddedDocuments('Item', [ {_id: skill.id, 'system.used': checked} ])
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
updateSkill(skill) {
|
||||
skill.derivated = foundry.utils.duplicate(this.system.derivated[skill.system.base])
|
||||
skill.total = skill.system.value + skill.derivated.value + skill.system.bonus
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSkills() {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'skill') || [])
|
||||
this.computeDerivated()
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'skill') || [])
|
||||
for (let skill of comp) {
|
||||
DarkStarsUtility.updateSkill(skill)
|
||||
this.updateSkill(skill)
|
||||
}
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getRelevantAbility(statKey) {
|
||||
let comp = duplicate(this.items.filter(item => item.type == 'skill' && item.system.ability == ability) || []);
|
||||
return comp;
|
||||
getPerks() {
|
||||
let comp = foundry.utils.duplicate(this.items.filter(item => item.type == 'perk') || [])
|
||||
DarkStarsUtility.sortArrayObjectsByName(comp)
|
||||
return comp
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async equipItem(itemId) {
|
||||
let item = this.items.find(item => item.id == itemId)
|
||||
if (item && item.system) {
|
||||
if (item?.system) {
|
||||
if (item.type == "armor") {
|
||||
let armor = this.items.find(item => item.id != itemId && item.type == "armor" && item.system.equipped)
|
||||
if (armor) {
|
||||
@ -265,7 +303,7 @@ export class DarkStarsActor extends Actor {
|
||||
}
|
||||
/* ------------------------------------------- */
|
||||
getEquipmentsOnly() {
|
||||
return duplicate(this.items.filter(item => item.type == "equipment") || [])
|
||||
return foundry.utils.duplicate(this.items.filter(item => item.type == "equipment") || [])
|
||||
}
|
||||
|
||||
/* ------------------------------------------- */
|
||||
@ -291,7 +329,7 @@ export class DarkStarsActor extends Actor {
|
||||
|
||||
/* ------------------------------------------- */
|
||||
async buildContainerTree() {
|
||||
let equipments = duplicate(this.items.filter(item => item.type == "equipment") || [])
|
||||
let equipments = foundry.utils.duplicate(this.items.filter(item => item.type == "equipment") || [])
|
||||
for (let equip1 of equipments) {
|
||||
if (equip1.system.iscontainer) {
|
||||
equip1.system.contents = []
|
||||
@ -343,9 +381,9 @@ export class DarkStarsActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async incDecHP(formula) {
|
||||
let dmgRoll = new Roll(formula+"[dark-starsorange]").roll({ async: false })
|
||||
let dmgRoll = new Roll(formula + "[dark-starsorange]").roll({ async: false })
|
||||
await DarkStarsUtility.showDiceSoNice(dmgRoll, game.settings.get("core", "rollMode"))
|
||||
let hp = duplicate(this.system.secondary.hp)
|
||||
let hp = foundry.utils.duplicate(this.system.secondary.hp)
|
||||
hp.value = Number(hp.value) + Number(dmgRoll.total)
|
||||
this.update({ 'system.secondary.hp': hp })
|
||||
return Number(dmgRoll.total)
|
||||
@ -372,7 +410,7 @@ export class DarkStarsActor extends Actor {
|
||||
} else {
|
||||
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': containerId }])
|
||||
}
|
||||
} else if (object && object.system.containerid) { // remove from container
|
||||
} else if (object?.system.containerid) { // remove from container
|
||||
console.log("Removeing: ", object)
|
||||
await this.updateEmbeddedDocuments("Item", [{ _id: object.id, 'system.containerid': "" }]);
|
||||
}
|
||||
@ -389,31 +427,34 @@ export class DarkStarsActor extends Actor {
|
||||
/* -------------------------------------------- */
|
||||
async equipGear(equipmentId) {
|
||||
let item = this.items.find(item => item.id == equipmentId);
|
||||
if (item && item.system) {
|
||||
if (item?.system) {
|
||||
let update = { _id: item.id, "system.equipped": !item.system.equipped };
|
||||
await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getInitiativeScore(combatId, combatantId) {
|
||||
if (this.type == 'character') {
|
||||
this.rollMR(true, combatId, combatantId)
|
||||
}
|
||||
console.log("Init required !!!!")
|
||||
return -1;
|
||||
hasLastWord() {
|
||||
return this.items.find(i => i.type == "perk" && i.name.toLowerCase() === "last word")
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async getInitiativeScore() {
|
||||
let initFormula = (this.system.derivated.si.value + this.system.derivated.si.bonus) + "d6"
|
||||
let initRoll = await new Roll(initFormula).roll()
|
||||
await DarkStarsUtility.showDiceSoNice(initRoll, game.settings.get("core", "rollMode"))
|
||||
return initRoll.total
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getSubActors() {
|
||||
let subActors = [];
|
||||
for (let id of this.system.subactors) {
|
||||
subActors.push(duplicate(game.actors.get(id)))
|
||||
subActors.push(foundry.utils.duplicate(game.actors.get(id)))
|
||||
}
|
||||
return subActors;
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async addSubActor(subActorId) {
|
||||
let subActors = duplicate(this.system.subactors);
|
||||
let subActors = foundry.utils.duplicate(this.system.subactors);
|
||||
subActors.push(subActorId);
|
||||
await this.update({ 'system.subactors': subActors });
|
||||
}
|
||||
@ -428,17 +469,11 @@ export class DarkStarsActor extends Actor {
|
||||
await this.update({ 'system.subactors': newArray });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
syncRoll(rollData) {
|
||||
this.lastRollId = rollData.rollId;
|
||||
DarkStarsUtility.saveRollData(rollData);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getOneSkill(skillId) {
|
||||
let skill = this.items.find(item => item.type == 'skill' && item.id == skillId)
|
||||
if (skill) {
|
||||
skill = duplicate(skill);
|
||||
skill = foundry.utils.duplicate(skill);
|
||||
}
|
||||
return skill;
|
||||
}
|
||||
@ -488,7 +523,7 @@ export class DarkStarsActor extends Actor {
|
||||
if (objetQ) {
|
||||
let newQ = objetQ.system.quantity + incDec
|
||||
if (newQ >= 0) {
|
||||
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]) // pdates one EmbeddedEntity
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.quantity': newQ }]) // pdates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -498,7 +533,7 @@ export class DarkStarsActor extends Actor {
|
||||
if (objetQ) {
|
||||
let newQ = objetQ.system.ammocurrent + incDec;
|
||||
if (newQ >= 0 && newQ <= objetQ.system.ammomax) {
|
||||
const updated = await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.ammocurrent': newQ }]); // pdates one EmbeddedEntity
|
||||
await this.updateEmbeddedDocuments('Item', [{ _id: objetQ.id, 'system.ammocurrent': newQ }]); // pdates one EmbeddedEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -532,6 +567,13 @@ export class DarkStarsActor extends Actor {
|
||||
return this.items.find(cond => cond.type == "condition" && cond.system.targetadvantage)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
modifyRerolls( value) {
|
||||
let rerolls = foundry.utils.duplicate(this.system.various.rerolls)
|
||||
rerolls.value += value
|
||||
this.update({ 'system.various.rerolls': rerolls })
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
getCommonRollData(abilityKey = undefined) {
|
||||
let noAction = this.isNoAction()
|
||||
@ -543,22 +585,14 @@ export class DarkStarsActor extends Actor {
|
||||
let rollData = DarkStarsUtility.getBasicRollData()
|
||||
rollData.alias = this.name
|
||||
rollData.actorImg = this.img
|
||||
rollData.actorId = this.id
|
||||
console.log("Prepare common roll data for actor", this)
|
||||
rollData.tokenId = this.token?.id
|
||||
rollData.actorId = this.id
|
||||
rollData.img = this.img
|
||||
rollData.featsDie = this.getFeatsWithDie()
|
||||
rollData.featsSL = this.getFeatsWithSL()
|
||||
rollData.armors = this.getArmors()
|
||||
rollData.conditions = this.getConditions()
|
||||
rollData.featDieName = "none"
|
||||
rollData.featSLName = "none"
|
||||
rollData.rollAdvantage = "none"
|
||||
rollData.advantage = "none"
|
||||
rollData.disadvantage = "none"
|
||||
rollData.forceAdvantage = this.isForcedAdvantage()
|
||||
rollData.forceDisadvantage = this.isForcedDisadvantage()
|
||||
rollData.forceRollAdvantage = this.isForcedRollAdvantage()
|
||||
rollData.forceRollDisadvantage = this.isForcedRollDisadvantage()
|
||||
rollData.noAdvantage = this.isNoAdvantage()
|
||||
rollData.rerolls = this.system.various.rerolls.value
|
||||
|
||||
if (rollData.defenderTokenId) {
|
||||
let defenderToken = game.canvas.tokens.get(rollData.defenderTokenId)
|
||||
let defender = defenderToken.actor
|
||||
@ -593,35 +627,69 @@ export class DarkStarsActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollAbility(abilityKey) {
|
||||
let rollData = this.getCommonRollData(abilityKey)
|
||||
rollData.mode = "ability"
|
||||
if (rollData.target) {
|
||||
ui.notifications.warn("You are targetting a token with a skill : please use a Weapon instead.")
|
||||
return
|
||||
rollAttribute(attrKey) {
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.attr = foundry.utils.duplicate(this.system.attributes[attrKey])
|
||||
rollData.mode = "attribute"
|
||||
rollData.title = "Attribute " + rollData.attr.label
|
||||
this.startRoll(rollData)
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
continueExtendedTest(testId) {
|
||||
let test = this.items.get(testId)
|
||||
if (test) {
|
||||
let skill = this.items.find(it => it.type == "skill" && it.name.toLowerCase() == test.system.skill.toLowerCase())
|
||||
if (skill) {
|
||||
skill = foundry.utils.duplicate(skill)
|
||||
this.updateSkill(skill)
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "extendedtest"
|
||||
rollData.isExtended = true
|
||||
rollData.extendedTest = test
|
||||
rollData.title = "Extended test " + skill.name
|
||||
rollData.skill = skill
|
||||
rollData.img = skill.img
|
||||
rollData.taskId = test.id
|
||||
if (rollData.target) {
|
||||
ui.notifications.warn("You are targetting a token with a skill : please use a Weapon instead.")
|
||||
return
|
||||
}
|
||||
this.startRoll(rollData)
|
||||
} else {
|
||||
console.log("Unable to find the relevant skill for extended test " + test.system.skill)
|
||||
}
|
||||
} else {
|
||||
console.log("Unable to find the extended test")
|
||||
}
|
||||
DarkStarsUtility.rollDarkStars(rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollSkill(skillId) {
|
||||
async rollSkill(skillId, isExtended = false, taskId = undefined) {
|
||||
let skill = this.items.get(skillId)
|
||||
if (skill) {
|
||||
if (skill.system.islore && skill.system.level == 0) {
|
||||
ui.notifications.warn("You can't use Lore Skills with a SL of 0.")
|
||||
return
|
||||
}
|
||||
skill = duplicate(skill)
|
||||
DarkStarsUtility.updateSkill(skill)
|
||||
let abilityKey = skill.system.ability
|
||||
let rollData = this.getCommonRollData(abilityKey)
|
||||
skill = foundry.utils.duplicate(skill)
|
||||
this.updateSkill(skill)
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "skill"
|
||||
rollData.isExtended = isExtended
|
||||
rollData.title = "Skill " + skill.name
|
||||
rollData.skill = skill
|
||||
rollData.img = skill.img
|
||||
if (rollData.target) {
|
||||
ui.notifications.warn("You are targetting a token with a skill : please use a Weapon instead.")
|
||||
return
|
||||
}
|
||||
if (isExtended) {
|
||||
rollData.title = "Extended Test " + skill.name
|
||||
if (!taskId) {
|
||||
let extendedTest = await this.createEmbeddedDocuments("Item", [{name: "Extended test " + skill.name, type: "extendedtest",
|
||||
'system.skill': skill.name}])
|
||||
//console.log("Task", cumulativeTask)
|
||||
rollData.taskId = extendedTest[0].id
|
||||
}else {
|
||||
rollData.taskId = extendedTest[0].id
|
||||
}
|
||||
}
|
||||
this.startRoll(rollData)
|
||||
}
|
||||
}
|
||||
@ -630,24 +698,17 @@ export class DarkStarsActor extends Actor {
|
||||
rollWeapon(weaponId) {
|
||||
let weapon = this.items.get(weaponId)
|
||||
if (weapon) {
|
||||
weapon = duplicate(weapon)
|
||||
weapon = foundry.utils.duplicate(weapon)
|
||||
let skill = this.items.find(item => item.name.toLowerCase() == weapon.system.skill.toLowerCase())
|
||||
if (skill) {
|
||||
skill = duplicate(skill)
|
||||
DarkStarsUtility.updateSkill(skill)
|
||||
let abilityKey = skill.system.ability
|
||||
let rollData = this.getCommonRollData(abilityKey)
|
||||
skill = foundry.utils.duplicate(skill)
|
||||
this.updateSkill(skill)
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "weapon"
|
||||
rollData.skill = skill
|
||||
rollData.weapon = weapon
|
||||
this.checkAndPrepareEquipment(weapon)
|
||||
rollData.img = weapon.img
|
||||
if (!rollData.forceDisadvantage) { // This is an attack, check if disadvantaged
|
||||
rollData.forceDisadvantage = this.isAttackDisadvantage()
|
||||
}
|
||||
/*if (rollData.weapon.system.isranged && rollData.tokensDistance > DarkStarsUtility.getWeaponMaxRange(rollData.weapon) ) {
|
||||
ui.notifications.warn(`Your target is out of range of your weapon (max: ${DarkStarsUtility.getWeaponMaxRange(rollData.weapon)} - current : ${rollData.tokensDistance})` )
|
||||
return
|
||||
}*/
|
||||
this.startRoll(rollData)
|
||||
} else {
|
||||
ui.notifications.warn("Unable to find the relevant skill for weapon " + weapon.name)
|
||||
@ -655,152 +716,8 @@ export class DarkStarsActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollDefenseMelee(attackRollData) {
|
||||
let weapon = this.items.get(attackRollData.defenseWeaponId)
|
||||
if (weapon) {
|
||||
weapon = duplicate(weapon)
|
||||
let skill = this.items.find(item => item.name.toLowerCase() == weapon.system.skill.toLowerCase())
|
||||
if (skill) {
|
||||
skill = duplicate(skill)
|
||||
DarkStarsUtility.updateSkill(skill)
|
||||
let abilityKey = skill.system.ability
|
||||
let rollData = this.getCommonRollData(abilityKey)
|
||||
rollData.defenderTokenId = undefined // Cleanup
|
||||
rollData.mode = "weapondefense"
|
||||
rollData.shield = this.getEquippedShield()
|
||||
rollData.attackRollData = duplicate(attackRollData)
|
||||
rollData.skill = skill
|
||||
rollData.weapon = weapon
|
||||
rollData.img = weapon.img
|
||||
if (!rollData.forceDisadvantage) { // This is an attack, check if disadvantaged
|
||||
rollData.forceDisadvantage = this.isDefenseDisadvantage()
|
||||
}
|
||||
|
||||
this.startRoll(rollData)
|
||||
} else {
|
||||
ui.notifications.warn("Unable to find the relevant skill for weapon " + weapon.name)
|
||||
}
|
||||
} else {
|
||||
ui.notifications.warn("Weapon not found ! ")
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollDefenseRanged(attackRollData) {
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.defenderTokenId = undefined // Cleanup
|
||||
rollData.mode = "rangeddefense"
|
||||
if ( attackRollData) {
|
||||
rollData.attackRollData = duplicate(attackRollData)
|
||||
rollData.effectiveRange = DarkStarsUtility.getWeaponRange(attackRollData.weapon)
|
||||
rollData.tokensDistance = attackRollData.tokensDistance // QoL copy
|
||||
}
|
||||
rollData.sizeDice = DarkStarsUtility.getSizeDice(this.system.biodata.size)
|
||||
rollData.distanceBonusDice = 0 //Math.max(0, Math.floor((rollData.tokensDistance - rollData.effectiveRange) + 0.5))
|
||||
rollData.hasCover = "none"
|
||||
rollData.situational = "none"
|
||||
rollData.useshield = false
|
||||
rollData.shield = this.getEquippedShield()
|
||||
this.startRoll(rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollShieldDie() {
|
||||
let shield = this.getEquippedShield()
|
||||
if (shield) {
|
||||
shield = duplicate(shield)
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "shield"
|
||||
rollData.shield = shield
|
||||
rollData.useshield = true
|
||||
rollData.img = shield.img
|
||||
this.startRoll(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollArmorDie(rollData = undefined) {
|
||||
let armor = this.getEquippedArmor()
|
||||
if (armor) {
|
||||
armor = duplicate(armor)
|
||||
let reduce = 0
|
||||
let multiply = 1
|
||||
let disadvantage = false
|
||||
let advantage = false
|
||||
let messages = ["Armor applied"]
|
||||
|
||||
if (rollData) {
|
||||
if (DarkStarsUtility.isArmorLight(armor) && DarkStarsUtility.isWeaponPenetrating(rollData.attackRollData.weapon)) {
|
||||
return { armorIgnored: true, nbSuccess: 0, messages: ["Armor ignored : Penetrating weapons ignore Light Armors."] }
|
||||
}
|
||||
if (DarkStarsUtility.isWeaponPenetrating(rollData.attackRollData.weapon)) {
|
||||
messages.push("Armor reduced by 1 (Penetrating weapon)")
|
||||
reduce = 1
|
||||
}
|
||||
if (DarkStarsUtility.isWeaponLight(rollData.attackRollData.weapon)) {
|
||||
messages.push("Armor with advantage (Light weapon)")
|
||||
advantage = true
|
||||
}
|
||||
if (DarkStarsUtility.isWeaponHeavy(rollData.attackRollData.weapon)) {
|
||||
messages.push("Armor with disadvantage (Heavy weapon)")
|
||||
disadvantage = true
|
||||
}
|
||||
if (DarkStarsUtility.isWeaponHack(rollData.attackRollData.weapon)) {
|
||||
messages.push("Armor reduced by 1 (Hack weapon)")
|
||||
reduce = 1
|
||||
}
|
||||
if (DarkStarsUtility.isWeaponUndamaging(rollData.attackRollData.weapon)) {
|
||||
messages.push("Armor multiplied by 2 (Undamaging weapon)")
|
||||
multiply = 2
|
||||
}
|
||||
}
|
||||
let diceColor = armor.system.absorprionroll
|
||||
let armorResult = await DarkStarsUtility.getRollTableFromDiceColor(diceColor, false)
|
||||
console.log("Armor log", armorResult)
|
||||
let armorValue = Math.max(0, (Number(armorResult.text) + reduce) * multiply)
|
||||
if (advantage || disadvantage) {
|
||||
let armorResult2 = await DarkStarsUtility.getRollTableFromDiceColor(diceColor, false)
|
||||
let armorValue2 = Math.max(0, (Number(armorResult2.text) + reduce) * multiply)
|
||||
if (advantage) {
|
||||
armorValue = (armorValue2 > armorValue) ? armorValue2 : armorValue
|
||||
messages.push(`Armor advantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`)
|
||||
}
|
||||
if (disadvantage) {
|
||||
armorValue = (armorValue2 < armorValue) ? armorValue2 : armorValue
|
||||
messages.push(`Armor disadvantage - Roll 1 = ${armorValue} - Roll 2 = ${armorValue2}`)
|
||||
}
|
||||
}
|
||||
armorResult.armorValue = armorValue
|
||||
if (!rollData) {
|
||||
ChatMessage.create({ content: "Armor result : " + armorValue })
|
||||
}
|
||||
messages.push("Armor result : " + armorValue)
|
||||
return { armorIgnored: false, nbSuccess: armorValue, rawArmor: armorResult.text, messages: messages }
|
||||
}
|
||||
return { armorIgnored: true, nbSuccess: 0, messages: ["No armor equipped."] }
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
rollSave(saveKey) {
|
||||
let saves = this.getSaveRoll()
|
||||
let save = saves[saveKey]
|
||||
if (save) {
|
||||
save = duplicate(save)
|
||||
let rollData = this.getCommonRollData()
|
||||
rollData.mode = "save"
|
||||
rollData.save = save
|
||||
if (rollData.target) {
|
||||
ui.notifications.warn("You are targetting a token with a save roll - Not authorized.")
|
||||
return
|
||||
}
|
||||
this.startRoll(rollData)
|
||||
}
|
||||
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
async startRoll(rollData) {
|
||||
this.syncRoll(rollData)
|
||||
let rollDialog = await DarkStarsRollDialog.create(this, rollData)
|
||||
rollDialog.render(true)
|
||||
}
|
||||
|
@ -4,27 +4,44 @@ import { DarkStarsUtility } from "./dark-stars-utility.js";
|
||||
export class DarkStarsCombat extends Combat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollInitiative(ids, formula = undefined, messageOptions = {} ) {
|
||||
ids = typeof ids === "string" ? [ids] : ids;
|
||||
for (let cId = 0; cId < ids.length; cId++) {
|
||||
const c = this.combatants.get(ids[cId]);
|
||||
let id = c._id || c.id;
|
||||
let initBonus = c.actor ? c.actor.getInitiativeScore( this.id, id ) : -1;
|
||||
await this.updateEmbeddedDocuments("Combatant", [ { _id: id, initiative: initBonus } ]);
|
||||
processOtherTurns(c, initScore) {
|
||||
let toCreate = []
|
||||
let token = canvas.tokens.get(c.tokenId)
|
||||
let hasLastWord = token.actor.hasLastWord()
|
||||
while ( (initScore > 5) || (hasLastWord && initScore >= 5)) {
|
||||
initScore -= 5;
|
||||
toCreate.push({tokenId: c.tokenId, sceneId: c.sceneId, actorId: c.actorId, hidden: c.hidden, initiative: initScore, flags: { world: { isDuplicated: true} } } );
|
||||
}
|
||||
this.createEmbeddedDocuments("Combatant", toCreate);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async rollInitiative(ids, formula = undefined, messageOptions = {}) {
|
||||
ids = typeof ids === "string" ? [ids] : ids;
|
||||
for (let cId of ids) {
|
||||
const c = this.combatants.get(cId);
|
||||
let id = c._id || c.id;
|
||||
let initScore = c.actor ? await c.actor.getInitiativeScore(this.id, id) : -1;
|
||||
await this.updateEmbeddedDocuments("Combatant", [{ _id: id, initiative: initScore }]);
|
||||
setTimeout(() => this.processOtherTurns(c, initScore), 400)
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
nextRound() {
|
||||
super.nextRound()
|
||||
let toDelete = []
|
||||
for (let c of this.combatants) {
|
||||
if (c.flags?.world?.isDuplicated) {
|
||||
toDelete.push(c._id)
|
||||
}
|
||||
}
|
||||
this.deleteEmbeddedDocuments("Combatant", toDelete);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
_onUpdate(changed, options, userId) {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async checkTurnPosition() {
|
||||
while (game.combat.turn > 0) {
|
||||
await game.combat.previousTurn()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,74 @@
|
||||
|
||||
export const DARKSTARS_CONFIG = {
|
||||
|
||||
sizeOptions: {
|
||||
"1": "Tiny",
|
||||
"2": "Small",
|
||||
"3": "Medium",
|
||||
"4": "Large",
|
||||
"5": "Huge",
|
||||
"6": "Gargantuan"
|
||||
},
|
||||
classNPC: {
|
||||
"none": "None",
|
||||
"chaplain": "Chaplain",
|
||||
"magus": "Magus",
|
||||
"martial": "Martial",
|
||||
"skalawag": "Skalawag",
|
||||
"warden": "Warden"
|
||||
},
|
||||
synergyBonus: {
|
||||
"0": "0",
|
||||
"5": "+5%",
|
||||
"+6": "+6%",
|
||||
"+7": "+7%",
|
||||
"+8": "+8%",
|
||||
"+9": "+9%",
|
||||
"+10": "+10%"
|
||||
},
|
||||
attributeModifier: [
|
||||
{value: "0", label: "None"},
|
||||
{value: "-1", label: "Difficult (-1)"},
|
||||
{value: "-3", label: "Hard (-3)"},
|
||||
{value: "-6", label: "Very Hard (-6)"},
|
||||
{value: "-9", label: "Impossible (-9)"}
|
||||
],
|
||||
weaponAiming: {
|
||||
"none": "None",
|
||||
" arm": "Arm (-50)",
|
||||
"head": "Head (-50)",
|
||||
"torso": "Torso(-30)",
|
||||
"leg": "Leg (-30)",
|
||||
"hand": "Hand/Weapon (-70)"
|
||||
},
|
||||
rollModifiers: [
|
||||
{ "value": "-80", "label": "-80%" },
|
||||
{ "value": "-70", "label": "-70%" },
|
||||
{ "value": "-60", "label": "-60%" },
|
||||
{ "value": "-50", "label": "-50%" },
|
||||
{ "value": "-40", "label": "-40%" },
|
||||
{ "value": "-30", "label": "-30%" },
|
||||
{ "value": "-20", "label": "-20%" },
|
||||
{ "value": "-10", "label": "-10%" },
|
||||
{ "value": "0", "label": "0%" },
|
||||
{ "value": "+10", "label": "+10%" },
|
||||
{ "value": "+20", "label": "+20%" },
|
||||
{ "value": "+30", "label": "+30%" },
|
||||
{ "value": "+40", "label": "+40%" }
|
||||
],
|
||||
abilityValues: {
|
||||
"0": "0",
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": "3",
|
||||
"4": "4",
|
||||
"5": "5",
|
||||
"6": "6",
|
||||
"7": "7",
|
||||
"8": "8"
|
||||
},
|
||||
basebonus : {
|
||||
"csb": "CSB",
|
||||
"asb": "SSB",
|
||||
"ssb": "SSB",
|
||||
"msb": "MSB",
|
||||
"psb": "PSB",
|
||||
@ -30,6 +95,26 @@ export const DARKSTARS_CONFIG = {
|
||||
"slug": "Slug throwers",
|
||||
"energy": "Energy"
|
||||
},
|
||||
perktypes: {
|
||||
"normal": "Normal",
|
||||
"advanced": "Advanced",
|
||||
"role": "Role",
|
||||
"job": "Job"
|
||||
},
|
||||
magicTypes: {
|
||||
"lemurian": "Lemurian",
|
||||
"bloodmagic": "Blood Magic Ritual",
|
||||
"ritual": "Ritual",
|
||||
"miracle": "Miracle"
|
||||
},
|
||||
cyberTypes: {
|
||||
"I": "I",
|
||||
"P": "P",
|
||||
"U": "U",
|
||||
"W": "W",
|
||||
"E": "E",
|
||||
"GS": "GS"
|
||||
},
|
||||
range: {
|
||||
"1": "Close",
|
||||
"2": "Short",
|
||||
|
@ -9,7 +9,7 @@ export class DarkStarsItemSheet extends ItemSheet {
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["fvtt-dark-stars", "sheet", "item"],
|
||||
template: "systems/fvtt-dark-stars/templates/items/item-sheet.hbs",
|
||||
dragDrop: [{ dragSelector: null, dropSelector: null }],
|
||||
@ -49,7 +49,7 @@ export class DarkStarsItemSheet extends ItemSheet {
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
|
||||
let objectData = duplicate(this.object.system)
|
||||
let objectData = foundry.utils.duplicate(this.object.system)
|
||||
|
||||
let formData = {
|
||||
title: this.title,
|
||||
@ -87,7 +87,7 @@ export class DarkStarsItemSheet extends ItemSheet {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
postItem() {
|
||||
let chatData = duplicate(DarkStarsUtility.data(this.item));
|
||||
let chatData = foundry.utils.duplicate(DarkStarsUtility.data(this.item));
|
||||
if (this.actor) {
|
||||
chatData.actor = { id: this.actor.id };
|
||||
}
|
||||
@ -132,21 +132,9 @@ export class DarkStarsItemSheet extends ItemSheet {
|
||||
this.deleteSubitem(ev);
|
||||
});
|
||||
|
||||
// Update Inventory Item
|
||||
html.find('.item-delete').click(ev => {
|
||||
const li = $(ev.currentTarget).parents(".item");
|
||||
let itemId = li.data("item-id");
|
||||
let itemType = li.data("item-type");
|
||||
});
|
||||
|
||||
html.find('.view-subitem').click(ev => {
|
||||
this.viewSubitem(ev);
|
||||
});
|
||||
|
||||
html.find('.view-spec').click(ev => {
|
||||
this.manageSpec();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,9 @@ export const defaultItemImg = {
|
||||
perk: "systems/fvtt-dark-stars/images/icons/perk.webp",
|
||||
ability: "systems/fvtt-dark-stars/images/icons/ability.webp",
|
||||
genetic: "systems/fvtt-dark-stars/images/icons/genetic.webp",
|
||||
cyber: "systems/fvtt-dark-stars/images/icons/cyber.webp"
|
||||
cyber: "systems/fvtt-dark-stars/images/icons/cyber.webp",
|
||||
spell: "systems/fvtt-dark-stars/images/icons/magic.webp",
|
||||
psychic: "systems/fvtt-dark-stars/images/icons/psychicpowers.webp",
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ import { DarkStarsItem } from "./dark-stars-item.js";
|
||||
import { DarkStarsHotbar } from "./dark-stars-hotbar.js"
|
||||
import { DarkStarsCommands } from "./dark-stars-commands.js"
|
||||
import { DARKSTARS_CONFIG } from "./dark-stars-config.js";
|
||||
import { ClassCounter} from "https://www.uberwald.me/fvtt_appcount/count-class-ready.js"
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
@ -91,15 +92,11 @@ Hooks.once("ready", function () {
|
||||
});
|
||||
}
|
||||
|
||||
// CSS patch for v9
|
||||
if (game.version) {
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
sidebar.style.width = "min-content";
|
||||
}
|
||||
|
||||
welcomeMessage();
|
||||
DarkStarsUtility.ready()
|
||||
DarkStarsCommands.init()
|
||||
ClassCounter.registerUsageCount()
|
||||
})
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -11,7 +11,7 @@ export class DarkStarsNPCSheet extends ActorSheet {
|
||||
/** @override */
|
||||
static get defaultOptions() {
|
||||
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
classes: ["dark-stars-rpg", "sheet", "actor"],
|
||||
template: "systems/fvtt-dark-stars/templates/npc-sheet.hbs",
|
||||
width: 640,
|
||||
@ -25,7 +25,7 @@ export class DarkStarsNPCSheet extends ActorSheet {
|
||||
/* -------------------------------------------- */
|
||||
async getData() {
|
||||
const objectData = this.object.system
|
||||
let actorData = duplicate(objectData)
|
||||
let actorData = foundry.utils.duplicate(objectData)
|
||||
|
||||
let formData = {
|
||||
title: this.title,
|
||||
@ -38,21 +38,22 @@ export class DarkStarsNPCSheet extends ActorSheet {
|
||||
data: actorData,
|
||||
limited: this.object.limited,
|
||||
skills: this.actor.getSkills( ),
|
||||
weapons: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getWeapons()) ),
|
||||
armors: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getArmors())),
|
||||
shields: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getShields())),
|
||||
spells: this.actor.checkAndPrepareEquipments( duplicate(this.actor.getLore())),
|
||||
equipments: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquipmentsOnly()) ),
|
||||
equippedWeapons: this.actor.checkAndPrepareEquipments(duplicate(this.actor.getEquippedWeapons()) ),
|
||||
weapons: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getWeapons()) ),
|
||||
armors: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getArmors())),
|
||||
shields: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getShields())),
|
||||
spells: this.actor.checkAndPrepareEquipments( foundry.utils.duplicate(this.actor.getLore())),
|
||||
equipments: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getEquipmentsOnly()) ),
|
||||
equippedWeapons: this.actor.checkAndPrepareEquipments(foundry.utils.duplicate(this.actor.getEquippedWeapons()) ),
|
||||
equippedArmor: this.actor.getEquippedArmor(),
|
||||
equippedShield: this.actor.getEquippedShield(),
|
||||
feats: duplicate(this.actor.getFeats()),
|
||||
subActors: duplicate(this.actor.getSubActors()),
|
||||
race: duplicate(this.actor.getRace()),
|
||||
moneys: duplicate(this.actor.getMoneys()),
|
||||
feats: foundry.utils.duplicate(this.actor.getFeats()),
|
||||
subActors: foundry.utils.duplicate(this.actor.getSubActors()),
|
||||
race: foundry.utils.duplicate(this.actor.getRace()),
|
||||
moneys: foundry.utils.duplicate(this.actor.getMoneys()),
|
||||
encCapacity: this.actor.getEncumbranceCapacity(),
|
||||
saveRolls: this.actor.getSaveRoll(),
|
||||
conditions: this.actor.getConditions(),
|
||||
config: game.system.darkstars.config,
|
||||
containersTree: this.actor.containersTree,
|
||||
encCurrent: this.actor.encCurrent,
|
||||
options: this.options,
|
||||
|
@ -5,8 +5,8 @@ export class DarkStarsRollDialog extends Dialog {
|
||||
/* -------------------------------------------- */
|
||||
static async create(actor, rollData) {
|
||||
|
||||
let options = { classes: ["DarkStarsDialog"], width: 540, height: 340, 'z-index': 99999 };
|
||||
let html = await renderTemplate('systems/fvtt-dark-stars/templates/roll-dialog-generic.hbs', rollData);
|
||||
let options = { classes: ["DarkStarsDialog"], width: 420, height: 'fit-content', 'z-index': 99999 };
|
||||
let html = await renderTemplate('systems/fvtt-dark-stars/templates/apps/roll-dialog-generic.hbs', rollData);
|
||||
|
||||
return new DarkStarsRollDialog(actor, rollData, html, options);
|
||||
}
|
||||
@ -58,27 +58,23 @@ export class DarkStarsRollDialog extends Dialog {
|
||||
}
|
||||
$(function () { onLoad(); });
|
||||
|
||||
html.find('#advantage').change((event) => {
|
||||
this.rollData.advantage = event.currentTarget.value
|
||||
html.find('#bonusMalus').change((event) => {
|
||||
this.rollData.bonusMalus = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#disadvantage').change((event) => {
|
||||
this.rollData.disadvantage = event.currentTarget.value
|
||||
html.find('#above-effective-range').change((event) => {
|
||||
this.rollData.isAboveEffectiveRange = event.currentTarget.checked
|
||||
})
|
||||
html.find('#rollAdvantage').change((event) => {
|
||||
this.rollData.rollAdvantage = event.currentTarget.value
|
||||
html.find('#weapon-aiming').change((event) => {
|
||||
this.rollData.weaponAiming = String(event.currentTarget.value)
|
||||
})
|
||||
html.find('#useshield').change((event) => {
|
||||
this.rollData.useshield = event.currentTarget.checked
|
||||
html.find('#synergy-bonus').change((event) => {
|
||||
this.rollData.synergyBonus = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#hasCover').change((event) => {
|
||||
this.rollData.hasCover = event.currentTarget.value
|
||||
html.find('#extra-time').change((event) => {
|
||||
this.rollData.extraTime = event.currentTarget.checked
|
||||
})
|
||||
html.find('#situational').change((event) => {
|
||||
this.rollData.situational = event.currentTarget.value
|
||||
html.find('#attribute-modifier').change((event) => {
|
||||
this.rollData.attributeModifier = Number(event.currentTarget.value)
|
||||
})
|
||||
html.find('#distanceBonusDice').change((event) => {
|
||||
this.rollData.distanceBonusDice = Number(event.currentTarget.value)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
@ -11,9 +11,7 @@ export class DarkStarsUtility {
|
||||
/* -------------------------------------------- */
|
||||
static async init() {
|
||||
Hooks.on('renderChatLog', (log, html, data) => DarkStarsUtility.chatListeners(html));
|
||||
/*Hooks.on("dropCanvasData", (canvas, data) => {
|
||||
DarkStarsUtility.dropItemOnToken(canvas, data)
|
||||
});*/
|
||||
Hooks.on('renderChatMessage', (message, html, data) => DarkStarsUtility.chatMessageHandler(message, html, data))
|
||||
|
||||
DarkStarsCommands.init();
|
||||
|
||||
@ -43,29 +41,28 @@ export class DarkStarsUtility {
|
||||
return __locationNames[key]
|
||||
})
|
||||
|
||||
|
||||
this.gameSettings()
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
static gameSettings() {
|
||||
/*game.settings.register("fvtt-dark-stars", "dice-color-skill", {
|
||||
name: "Dice color for skills",
|
||||
hint: "Set the dice color for skills",
|
||||
scope: "world",
|
||||
config: true,
|
||||
requiresReload: true ,
|
||||
default: "#101010",
|
||||
type: String
|
||||
})
|
||||
|
||||
Hooks.on('renderSettingsConfig', (event) => {
|
||||
const element = event.element[0].querySelector(`[name='fvtt-dark-stars.dice-color-skill']`)
|
||||
if (!element) return
|
||||
// Replace placeholder element
|
||||
console.log("Element Found !!!!")
|
||||
}) */
|
||||
static async processOpposed(rollData) {
|
||||
if (this.currentOpposition) {
|
||||
let opposed = {
|
||||
winner: this.currentOpposition,
|
||||
looser: rollData,
|
||||
isOpposed : true
|
||||
}
|
||||
if (rollData.degrees > this.currentOpposition.degrees ) {
|
||||
opposed.winner = rollData
|
||||
opposed.looser = this.currentOpposition
|
||||
}
|
||||
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat/chat-opposition-result.hbs`, opposed)
|
||||
})
|
||||
await msg.setFlag("world", "darkstars-roll-data", opposed)
|
||||
} else {
|
||||
this.currentOpposition = rollData
|
||||
ui.notifications.info("Opposed rolls started with " + rollData.alias );
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------- */
|
||||
@ -76,14 +73,13 @@ export class DarkStarsUtility {
|
||||
|
||||
/*-------------------------------------------- */
|
||||
static getSkills() {
|
||||
return duplicate(this.skills)
|
||||
return foundry.utils.duplicate(this.skills)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async ready() {
|
||||
const skills = await DarkStarsUtility.loadCompendium("fvtt-dark-stars.skills")
|
||||
this.skills = skills.map(i => i.toObject())
|
||||
|
||||
const skills = await DarkStarsUtility.loadCompendium("fvtt-dark-stars.sprawl");
|
||||
this.skills = skills.filter(i => i.type == "skill").map(i => i.toObject());
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -103,24 +99,21 @@ export class DarkStarsUtility {
|
||||
static async chatListeners(html) {
|
||||
|
||||
html.on("click", '.view-item-from-chat', event => {
|
||||
game.system.crucible.creator.openItemView(event)
|
||||
game.system.darkstars.creator.openItemView(event)
|
||||
})
|
||||
html.on("click", '.roll-defense-melee', event => {
|
||||
let rollId = $(event.currentTarget).data("roll-id")
|
||||
let rollData = DarkStarsUtility.getRollData(rollId)
|
||||
rollData.defenseWeaponId = $(event.currentTarget).data("defense-weapon-id")
|
||||
let actor = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||
if (actor && (game.user.isGM || actor.isOwner)) {
|
||||
actor.rollDefenseMelee(rollData)
|
||||
}
|
||||
html.on("click", '.chat-reroll', event => {
|
||||
let messageId = this.findChatMessageId(event.currentTarget)
|
||||
let message = game.messages.get(messageId)
|
||||
let rollData = message.getFlag("world", "darkstars-roll-data")
|
||||
rollData.reroll = true
|
||||
rollData.roll = undefined
|
||||
this.rollDarkStars(rollData)
|
||||
})
|
||||
html.on("click", '.roll-defense-ranged', event => {
|
||||
let rollId = $(event.currentTarget).data("roll-id")
|
||||
let rollData = DarkStarsUtility.getRollData(rollId)
|
||||
let defender = game.canvas.tokens.get(rollData.defenderTokenId).actor
|
||||
if (defender && (game.user.isGM || defender.isOwner)) {
|
||||
defender.rollDefenseRanged(rollData)
|
||||
}
|
||||
html.on("click", '.chat-roll-opposed', event => {
|
||||
let messageId = this.findChatMessageId(event.currentTarget)
|
||||
let message = game.messages.get(messageId)
|
||||
let rollData = message.getFlag("world", "darkstars-roll-data")
|
||||
this.processOpposed(rollData)
|
||||
})
|
||||
|
||||
}
|
||||
@ -130,10 +123,8 @@ export class DarkStarsUtility {
|
||||
|
||||
const templatePaths = [
|
||||
'systems/fvtt-dark-stars/templates/partials/editor-notes-gm.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-roll-select.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-actor-ability-block.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-actor-status.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-options-abilities.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-item-nav.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-item-description.hbs',
|
||||
'systems/fvtt-dark-stars/templates/partials/partial-actor-equipment.hbs'
|
||||
@ -265,176 +256,141 @@ export class DarkStarsUtility {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getAimingMalus(location) {
|
||||
if (location == "arm" || location == "head") {
|
||||
return -50
|
||||
}
|
||||
if (location == "torso" || location == "leg") {
|
||||
return -30
|
||||
}
|
||||
if (location == "hand") {
|
||||
return -70
|
||||
}
|
||||
return 0
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static getAimingLocation(roll) {
|
||||
if (roll == 1) return "head"
|
||||
if (roll >= 2 && roll <= 4) return "chest"
|
||||
if (roll >= 5 && roll <= 6) return "abdomen"
|
||||
if (roll == 7) return "leftarm"
|
||||
if (roll == 8) return "rightarm"
|
||||
if (roll == 9) return "rightleg"
|
||||
if (roll == 10) return "leftleg"
|
||||
return "abdomen"
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static locationMultiplier(location) {
|
||||
if (location == "head") return 0.3
|
||||
if (location.includes("arm")) return 0.2
|
||||
if (location.includes("leg")) return 0.4
|
||||
if (location == "chest") return 0.5
|
||||
return 0.3 // Abdomen case
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollDarkStars(rollData) {
|
||||
|
||||
let actor = game.actors.get(rollData.actorId)
|
||||
if (rollData.tokenId) {
|
||||
actor = game.canvas.tokens.get(rollData.tokenId).actor
|
||||
}
|
||||
|
||||
// Specific attribute
|
||||
if (rollData.attr) {
|
||||
rollData.isSuccess = false
|
||||
rollData.isFailure = false
|
||||
rollData.targetNumber = Math.max( rollData.attr.value + rollData.attributeModifier, 0)
|
||||
let myRoll = await new Roll("1d10").roll()
|
||||
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
||||
if (myRoll.total <= rollData.targetNumber) {
|
||||
rollData.isSuccess = true
|
||||
rollData.isFailure = false
|
||||
}
|
||||
rollData.roll = foundry.utils.duplicate(myRoll)
|
||||
rollData.diceResult = myRoll.total
|
||||
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat/chat-attribute-result.hbs`, rollData)
|
||||
})
|
||||
msg.setFlag("world", "darkstars-roll-data", rollData)
|
||||
return
|
||||
}
|
||||
|
||||
// ability/save/size => 0
|
||||
let diceFormula
|
||||
let startFormula = "0d6cs>=5[blue]"
|
||||
if (rollData.ability) {
|
||||
startFormula = String(rollData.ability.value) + "d6cs>=5[blue]"
|
||||
}
|
||||
if (rollData.save) {
|
||||
startFormula = String(rollData.save.value) + "d6cs>=5[blue]"
|
||||
}
|
||||
if (rollData.sizeDice) {
|
||||
let nb = rollData.sizeDice.nb + rollData.distanceBonusDice + this.getDiceFromCover(rollData.hasCover) + this.getDiceFromSituational(rollData.situational)
|
||||
startFormula = String(nb) + String(rollData.sizeDice.dice) + "cs>=5[blue]"
|
||||
}
|
||||
diceFormula = startFormula
|
||||
|
||||
// skill => 2
|
||||
// feat => 4
|
||||
// bonus => 6
|
||||
rollData.percentValue = 0
|
||||
if (rollData.skill) {
|
||||
let level = rollData.skill.system.level
|
||||
if (rollData.skill.system.issl2) {
|
||||
rollData.hasSLBonus = true
|
||||
level += 2
|
||||
if (level > 7) { level = 7 }
|
||||
}
|
||||
rollData.skill.system.skilldice = __skillLevel2Dice[level]
|
||||
diceFormula += "+" + String(rollData.skill.system.skilldice) + "cs>=5[black]"
|
||||
rollData.percentValue = rollData.skill.total
|
||||
}
|
||||
if (rollData.synergyBonus) {
|
||||
rollData.percentValue += rollData.synergyBonus
|
||||
}
|
||||
if (rollData.extraTime) {
|
||||
rollData.percentValue += 30
|
||||
}
|
||||
rollData.percentValue += rollData.bonusMalus
|
||||
rollData.diceFormula = "1d100"
|
||||
|
||||
if (rollData.skill.system.skilltype == "complex" && rollData.skill.system.level == 0) {
|
||||
rollData.complexSkillDisadvantage = true
|
||||
rollData.rollAdvantage = "roll-disadvantage"
|
||||
}
|
||||
|
||||
if (rollData.skill.system.isfeatdie) {
|
||||
rollData.hasFeatDie = true
|
||||
diceFormula += "+ 1d10cs>=5[dark-stars-purple]"
|
||||
} else {
|
||||
diceFormula += `+ 0d10cs>=5[dark-stars-purple]`
|
||||
}
|
||||
if (rollData.skill.system.bonusdice != "none") {
|
||||
rollData.hasBonusDice = rollData.skill.system.bonusdice
|
||||
diceFormula += `+ ${rollData.hasBonusDice}cs>=5[black]`
|
||||
} else {
|
||||
diceFormula += `+ 0d6cs>=5[black]`
|
||||
}
|
||||
} else {
|
||||
diceFormula += `+ 0d8cs=>5 + 0d10cs>=5 + 0d6cs>=5`
|
||||
if (rollData.isAboveEffectiveRange) {
|
||||
rollData.percentValue -= 30
|
||||
rollData.percentValue = Math.max(0, rollData.percentValue)
|
||||
}
|
||||
|
||||
// advantage => 8
|
||||
let advFormula = "+ 0d8cs>=5"
|
||||
if (rollData.advantage == "advantage1" || rollData.forceAdvantage) {
|
||||
advFormula = "+ 1d8cs>=5[dark-stars-darkgreen]"
|
||||
}
|
||||
if (rollData.advantage == "advantage2") {
|
||||
advFormula = "+ 2d8cs>=5[dark-stars-darkgreen]"
|
||||
}
|
||||
diceFormula += advFormula
|
||||
|
||||
// disadvantage => 10
|
||||
let disFormula = "- 0d8cs>=5"
|
||||
if (rollData.disadvantage == "disadvantage1" || rollData.forceDisadvantage) {
|
||||
disFormula = "- 1d8cs>=5[red]"
|
||||
}
|
||||
if (rollData.disadvantage == "disadvantage2") {
|
||||
disFormula = "- 2d8cs>=5[red]"
|
||||
}
|
||||
diceFormula += disFormula
|
||||
|
||||
// armor => 12
|
||||
let skillArmorPenalty = 0
|
||||
for (let armor of rollData.armors) {
|
||||
if (armor.system.equipped) {
|
||||
skillArmorPenalty += armor.system.skillpenalty
|
||||
}
|
||||
}
|
||||
if (rollData.skill && rollData.skill.system.armorpenalty && skillArmorPenalty > 0) {
|
||||
rollData.skillArmorPenalty = skillArmorPenalty
|
||||
diceFormula += `- ${skillArmorPenalty}d8cs>=5`
|
||||
} else {
|
||||
diceFormula += `- 0d8cs>=5`
|
||||
}
|
||||
|
||||
// shield => 14
|
||||
if (rollData.useshield && rollData.shield) {
|
||||
diceFormula += "+ 1" + String(rollData.shield.system.shielddie) + "cs>=5[yellow]"
|
||||
} else {
|
||||
diceFormula += " + 0d6cs>=5"
|
||||
if (rollData.mode == "weapon") {
|
||||
rollData.locationMalus = this.getAimingMalus(rollData.weaponAiming)
|
||||
rollData.percentValue += rollData.locationMalus
|
||||
}
|
||||
rollData.percentValue = Math.max(rollData.percentValue, 0)
|
||||
|
||||
// Performs roll
|
||||
console.log("Roll formula", diceFormula)
|
||||
let myRoll = rollData.roll
|
||||
if (!myRoll) { // New rolls only of no rerolls
|
||||
myRoll = new Roll(diceFormula).roll({ async: false })
|
||||
myRoll = await new Roll(rollData.diceFormula).roll()
|
||||
await this.showDiceSoNice(myRoll, game.settings.get("core", "rollMode"))
|
||||
}
|
||||
rollData.rollOrder = 0
|
||||
rollData.roll = myRoll
|
||||
rollData.nbSuccess = myRoll.total
|
||||
rollData.roll = foundry.utils.duplicate(myRoll)
|
||||
rollData.diceResult = myRoll.total
|
||||
rollData.isCriticalSuccess = rollData.diceResult <= rollData.skill.derivated.value
|
||||
rollData.isCriticalFailure = rollData.diceResult == 100
|
||||
rollData.isSuccess = rollData.diceResult == 1 || rollData.diceResult <= rollData.percentValue
|
||||
rollData.isFailure = rollData.diceResult == 100 || rollData.diceResult > rollData.percentValue
|
||||
rollData.degrees = Math.floor((rollData.percentValue - rollData.diceResult) / 10)
|
||||
rollData.damageMultiplier = rollData.isCriticalSuccess ? 2 : 1
|
||||
|
||||
if (rollData.rollAdvantage == "none" && rollData.forceRollAdvantage) {
|
||||
rollData.rollAdvantage = "roll-advantage"
|
||||
if (rollData.reroll) {
|
||||
actor.modifyRerolls(-1)
|
||||
rollData.rerolls = 0 // DIsable rerolls
|
||||
}
|
||||
if (rollData.rollAdvantage == "none" && rollData.forceRollDisadvantage) {
|
||||
rollData.rollAdvantage = "roll-disadvantage"
|
||||
}
|
||||
if (rollData.rollAdvantage != "none") {
|
||||
|
||||
rollData.rollOrder = 1
|
||||
rollData.rollType = (rollData.rollAdvantage == "roll-advantage") ? "Advantage" : "Disadvantage"
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat-generic-result.hbs`, rollData)
|
||||
})
|
||||
|
||||
rollData.rollOrder = 2
|
||||
let myRoll2 = new Roll(diceFormula).roll({ async: false })
|
||||
await this.showDiceSoNice(myRoll2, game.settings.get("core", "rollMode"))
|
||||
|
||||
rollData.roll = myRoll2 // Tmp switch to display the proper results
|
||||
rollData.nbSuccess = myRoll2.total
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat-generic-result.hbs`, rollData)
|
||||
})
|
||||
rollData.roll = myRoll // Revert the tmp switch
|
||||
rollData.nbSuccess = myRoll.total
|
||||
|
||||
if (rollData.rollAdvantage == "roll-advantage") {
|
||||
if (myRoll2.total > rollData.nbSuccess) {
|
||||
hasChanged = true
|
||||
rollData.roll = myRoll2
|
||||
rollData.nbSuccess = myRoll2.total
|
||||
}
|
||||
} else {
|
||||
if (myRoll2.total < rollData.nbSuccess) {
|
||||
rollData.roll = myRoll2
|
||||
rollData.nbSuccess = myRoll2.total
|
||||
}
|
||||
if (rollData.mode == "weapon") {
|
||||
if (rollData.weaponAiming == "none") {
|
||||
let rollLoc = new Roll("1d10").roll({ async: false })
|
||||
rollData.weaponAiming = this.getAimingLocation(rollLoc.total)
|
||||
}
|
||||
rollData.rollOrder = 3
|
||||
// Compute
|
||||
rollData.locationMultiplier = this.locationMultiplier(rollData.weaponAiming)
|
||||
}
|
||||
rollData.nbSuccess = Math.max(0, rollData.nbSuccess)
|
||||
|
||||
rollData.isFirstRollAdvantage = false
|
||||
// Manage exp
|
||||
if (rollData.skill && rollData.skill.system.level > 0) {
|
||||
let nbSkillSuccess = rollData.roll.terms[2].total
|
||||
if (nbSkillSuccess == 0 || nbSkillSuccess == rollData.skill.system.level) {
|
||||
actor.incrementSkillExp(rollData.skill.id, 1)
|
||||
// Task management
|
||||
if (rollData.taskId) {
|
||||
let task = actor.getItem(rollData.taskId)
|
||||
console.log(" Task", task, rollData.taskId)
|
||||
if (task) {
|
||||
let newCumulated = rollData.degrees + task.system.cumulated
|
||||
let nbrolls = task.system.nbrolls + 1
|
||||
task.update({ 'system.cumulated': newCumulated, 'system.nbrolls': nbrolls })
|
||||
rollData.taskName = task.name
|
||||
rollData.taskCumulated = newCumulated
|
||||
rollData.taskNbrolls = nbrolls
|
||||
}
|
||||
}
|
||||
|
||||
this.saveRollData(rollData)
|
||||
actor.lastRoll = rollData
|
||||
|
||||
this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat-generic-result.hbs`, rollData)
|
||||
let msg = await this.createChatWithRollMode(rollData.alias, {
|
||||
content: await renderTemplate(`systems/fvtt-dark-stars/templates/chat/chat-generic-result.hbs`, rollData)
|
||||
})
|
||||
|
||||
console.log("Rolldata result", rollData)
|
||||
|
||||
// Message response
|
||||
this.displayDefenseMessage(rollData)
|
||||
|
||||
// Manage defense result
|
||||
this.processAttackDefense(rollData)
|
||||
msg.setFlag("world", "darkstars-roll-data", rollData)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -456,6 +412,19 @@ export class DarkStarsUtility {
|
||||
static getUsers(filter) {
|
||||
return game.users.filter(filter).map(user => user.id);
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static async chatMessageHandler(message, html, data) {
|
||||
const chatCard = html.find('.gm-actions')
|
||||
if (chatCard.length > 0) {
|
||||
// If the user is the message author or the actor owner, proceed
|
||||
const actor = game.actors.get(data.message.speaker.actor)
|
||||
if (actor?.isOwner) return
|
||||
else if (game.user.isGM || data.author.id === game.user.id) return
|
||||
const divButtons = chatCard.find('.gm-actions')
|
||||
divButtons.hide()
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getWhisperRecipients(rollMode, name) {
|
||||
switch (rollMode) {
|
||||
@ -473,7 +442,7 @@ export class DarkStarsUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static blindMessageToGM(chatOptions) {
|
||||
let chatGM = duplicate(chatOptions);
|
||||
let chatGM = foundry.utils.duplicate(chatOptions);
|
||||
chatGM.whisper = this.getUsers(user => user.isGM);
|
||||
chatGM.content = "Blinde message of " + game.user.name + "<br>" + chatOptions.content;
|
||||
console.log("blindMessageToGM", chatGM);
|
||||
@ -528,15 +497,21 @@ export class DarkStarsUtility {
|
||||
break;
|
||||
}
|
||||
chatOptions.alias = chatOptions.alias || name;
|
||||
ChatMessage.create(chatOptions);
|
||||
return ChatMessage.create(chatOptions);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getBasicRollData() {
|
||||
let rollData = {
|
||||
rollId: randomID(16),
|
||||
rollId: foundry.utils.randomID(16),
|
||||
rollMode: game.settings.get("core", "rollMode"),
|
||||
advantage: "none"
|
||||
bonusMalus: 0,
|
||||
isAboveEffectiveRange: false,
|
||||
weaponAiming: "none",
|
||||
synergyBonus: 0,
|
||||
extraTime: false,
|
||||
attributeModifier: 0,
|
||||
config: game.system.darkstars.config,
|
||||
}
|
||||
DarkStarsUtility.updateWithTarget(rollData)
|
||||
return rollData
|
||||
@ -552,7 +527,7 @@ export class DarkStarsUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static createChatWithRollMode(name, chatOptions) {
|
||||
this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions)
|
||||
return this.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions)
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
6
packs/.directory
Normal file
6
packs/.directory
Normal file
@ -0,0 +1,6 @@
|
||||
[Dolphin]
|
||||
HeaderColumnWidths=301,118,148,122
|
||||
Timestamp=2024,1,26,8,35,29.906
|
||||
Version=4
|
||||
ViewMode=1
|
||||
VisibleRoles=Details_text,Details_size,Details_modificationtime,Details_creationtime,CustomizedDetails
|
BIN
packs/aldebaran/000119.ldb
Normal file
BIN
packs/aldebaran/000119.ldb
Normal file
Binary file not shown.
1
packs/aldebaran/CURRENT
Normal file
1
packs/aldebaran/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000208
|
7
packs/aldebaran/LOG
Normal file
7
packs/aldebaran/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:40.413261 7f3f0d6006c0 Recovering log #206
|
||||
2024/06/12-11:13:40.424230 7f3f0d6006c0 Delete type=3 #204
|
||||
2024/06/12-11:13:40.424287 7f3f0d6006c0 Delete type=0 #206
|
||||
2024/06/12-11:16:23.489560 7f3f060006c0 Level-0 table #211: started
|
||||
2024/06/12-11:16:23.489605 7f3f060006c0 Level-0 table #211: 0 bytes OK
|
||||
2024/06/12-11:16:23.520840 7f3f060006c0 Delete type=0 #209
|
||||
2024/06/12-11:16:23.590686 7f3f060006c0 Manual compaction at level-0 from '!folders!MA6uFJMVebGeayIk' @ 72057594037927935 : 1 .. '!items!zhjdppKgrON7wJn7' @ 0 : 0; will stop at (end)
|
7
packs/aldebaran/LOG.old
Normal file
7
packs/aldebaran/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:16.247740 7f3f0ea006c0 Recovering log #202
|
||||
2024/06/12-11:13:16.258091 7f3f0ea006c0 Delete type=3 #200
|
||||
2024/06/12-11:13:16.258153 7f3f0ea006c0 Delete type=0 #202
|
||||
2024/06/12-11:13:34.719686 7f3f060006c0 Level-0 table #207: started
|
||||
2024/06/12-11:13:34.719708 7f3f060006c0 Level-0 table #207: 0 bytes OK
|
||||
2024/06/12-11:13:34.726803 7f3f060006c0 Delete type=0 #205
|
||||
2024/06/12-11:13:34.733250 7f3f060006c0 Manual compaction at level-0 from '!folders!MA6uFJMVebGeayIk' @ 72057594037927935 : 1 .. '!items!zhjdppKgrON7wJn7' @ 0 : 0; will stop at (end)
|
BIN
packs/aldebaran/MANIFEST-000208
Normal file
BIN
packs/aldebaran/MANIFEST-000208
Normal file
Binary file not shown.
@ -1,15 +0,0 @@
|
||||
{"name":"Neo Soviet Hard Shell","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal 2","locations":{"head":{"protected":true,"max":30,"value":0},"abdomen":{"protected":true,"max":30,"value":0},"chest":{"protected":true,"max":30,"value":0},"leftleg":{"protected":true,"max":30,"value":0},"rightleg":{"protected":true,"max":30,"value":0},"leftarm":{"protected":true,"max":30,"value":0},"rightarm":{"protected":false,"max":0,"value":0}},"si":2,"skillbonus":"","availability":"P","equipped":false,"bulk":0,"cost":null,"description":"<p>Blocks 12 sieverts per hour. If it receives more than 12 sieverts per hour, after use must be destroyed.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.DndZ0pCGyR8y8SJK"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672108403022,"modifiedTime":1672108686724,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"3O3MjRkrmX4HeaPY"}
|
||||
{"name":"Marine Armour","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal","locations":{"head":{"protected":true,"max":20,"value":0},"abdomen":{"protected":true,"max":20,"value":0},"chest":{"protected":true,"max":20,"value":0},"leftleg":{"protected":true,"max":16,"value":0},"rightleg":{"protected":true,"max":16,"value":0},"leftarm":{"protected":true,"max":16,"value":0},"rightarm":{"protected":true,"max":16,"value":0}},"si":1,"skillbonus":"","availability":"P","equipped":false,"bulk":0,"cost":null,"description":"<p>Marine Armour Includes comm and integral PCM, quick repair.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.gCMeXdaHyaNcfHHl"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092447361,"modifiedTime":1672108683847,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"3YqWrfVwifB9S1Gm"}
|
||||
{"name":"Security Helmet","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Ridgy Plast","locations":{"head":{"protected":true,"max":8,"value":0},"abdomen":{"protected":false,"max":0,"value":0},"chest":{"protected":false,"max":0,"value":0},"leftleg":{"protected":false,"max":0,"value":0},"rightleg":{"protected":false,"max":0,"value":0},"leftarm":{"protected":false,"max":0,"value":0},"rightarm":{"protected":false,"max":0,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":null,"description":"<p>A high protection security helmet</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.iFryJgG9edVdkhG6"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091636317,"modifiedTime":1672108691719,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"5FuYpmCKk28QGqwR"}
|
||||
{"name":"Heavy Jacket","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Flexi Plast","locations":{"head":{"protected":false,"max":0,"value":0},"abdomen":{"protected":true,"max":1,"value":0},"chest":{"protected":true,"max":1,"value":0},"leftleg":{"protected":false,"max":0,"value":0},"rightleg":{"protected":false,"max":0,"value":0},"leftarm":{"protected":true,"max":1,"value":0},"rightarm":{"protected":true,"max":1,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":null,"description":"<p>Heavy Jacket flexi plast jacket, provides some protection small arms and knives.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.Lq6vGsSbxP5B5ZRu"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091382680,"modifiedTime":1672108681860,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"8MZj41jbtAfDh6qU"}
|
||||
{"name":"Yokohama Security Armour","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal 2","locations":{"head":{"protected":true,"max":30,"value":0},"abdomen":{"protected":true,"max":30,"value":0},"chest":{"protected":true,"max":30,"value":0},"leftleg":{"protected":true,"max":30,"value":0},"rightleg":{"protected":true,"max":30,"value":0},"leftarm":{"protected":true,"max":30,"value":0},"rightarm":{"protected":true,"max":30,"value":0}},"si":0,"skillbonus":"","availability":"R","equipped":false,"bulk":0,"cost":120000,"description":"<p>Yokohama Security Armour Blocks 14 sieverts per hour. If it receives more than 14 sieverts per hour, after use must be destroyed. </p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.UbZt9a1OXk9s5MMM"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092872594,"modifiedTime":1672108709989,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"9MXqrbGCmj4wReOW"}
|
||||
{"name":"Tycon Arms Defender","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal 2","locations":{"head":{"protected":true,"max":30,"value":0},"abdomen":{"protected":false,"max":0,"value":0},"chest":{"protected":false,"max":0,"value":0},"leftleg":{"protected":false,"max":0,"value":0},"rightleg":{"protected":false,"max":0,"value":0},"leftarm":{"protected":false,"max":0,"value":0},"rightarm":{"protected":false,"max":0,"value":0}},"si":0,"skillbonus":"","availability":"R","equipped":false,"bulk":0,"cost":35000,"description":"<p>Tycon Arms Defender helmet Comm, PCM, self sealing, space worthy. Blocks 8 sieverts per hour. If it receives more than 8 sieverts per hour, after use must be destroyed. 2 hours of life support. </p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.VhRHbN3AtY8Pwqdo"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092595651,"modifiedTime":1672108701910,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"G2AnAOPyeQlWghN5"}
|
||||
{"name":"Thebus Armoured Work Wear","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Flexi Plast","locations":{"head":{"protected":true,"max":5,"value":0},"abdomen":{"protected":true,"max":5,"value":0},"chest":{"protected":true,"max":5,"value":0},"leftleg":{"protected":true,"max":5,"value":0},"rightleg":{"protected":true,"max":5,"value":0},"leftarm":{"protected":true,"max":5,"value":0},"rightarm":{"protected":true,"max":5,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":3000,"description":"<p>Thebus Armoured Work Wear provides +10% to all technical tests.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.8tfxeZcBJfxBsmIM"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091984261,"modifiedTime":1672108699813,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"IHxpPrGqdl56dMpt"}
|
||||
{"name":"YiggRiff Hard Shell","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal 2","locations":{"head":{"protected":true,"max":17,"value":0},"abdomen":{"protected":true,"max":17,"value":0},"chest":{"protected":true,"max":17,"value":0},"leftleg":{"protected":true,"max":17,"value":0},"rightleg":{"protected":true,"max":17,"value":0},"leftarm":{"protected":true,"max":17,"value":0},"rightarm":{"protected":true,"max":17,"value":0}},"si":2,"skillbonus":"","availability":"P","equipped":false,"bulk":0,"cost":15000,"description":"<p>Blocks 8 sieverts per hour. If it receives more than 8 sieverts per hour, after use must be destroyed.</p>\n<p> </p>\n<p> </p>\n<p> </p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.qTQIYUntdBFU1KLd"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672108514253,"modifiedTime":1672108705709,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"IQ7sj2hD5yh73TRx"}
|
||||
{"name":"Skin Suit (environmentally sealed)","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Flexi Plast","locations":{"head":{"protected":true,"max":1,"value":0},"abdomen":{"protected":true,"max":1,"value":0},"chest":{"protected":true,"max":1,"value":0},"leftleg":{"protected":true,"max":1,"value":0},"rightleg":{"protected":true,"max":1,"value":0},"leftarm":{"protected":true,"max":1,"value":0},"rightarm":{"protected":true,"max":1,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":500,"description":"<p>A thin layer of sealed armour primarly for environmental protection from toxins, low level radiation, and acid rain. Provides 10 hours of independant oxygen supply and lifesupport often worn under heavier armour. </p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.lUSc6c6D1tqSqojK"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091705245,"modifiedTime":1672108693300,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"NJIXgxTSU3xTolyQ"}
|
||||
{"name":"Raider Armour (scrounged together)","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Flexi Plast","locations":{"head":{"protected":true,"max":3,"value":0},"abdomen":{"protected":true,"max":3,"value":0},"chest":{"protected":true,"max":3,"value":0},"leftleg":{"protected":true,"max":2,"value":0},"rightleg":{"protected":true,"max":2,"value":0},"leftarm":{"protected":true,"max":2,"value":0},"rightarm":{"protected":true,"max":2,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":800,"description":"<p>Raider armour is scrounged and contains off cuts and scrips from armour or tires, bits of plastic or metal. Can also be purchased as a gang suit manufactured by gangs in the mega cities. </p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.ZZK3R7s7NhuxjmUP"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091485957,"modifiedTime":1672108688229,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"OnVLyi5Tz2Of7LCP"}
|
||||
{"name":"Military Hard Shell","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Cermetal 2","locations":{"head":{"protected":true,"max":25,"value":0},"abdomen":{"protected":true,"max":25,"value":0},"chest":{"protected":true,"max":25,"value":0},"leftleg":{"protected":true,"max":25,"value":0},"rightleg":{"protected":true,"max":25,"value":0},"leftarm":{"protected":true,"max":25,"value":0},"rightarm":{"protected":true,"max":25,"value":0}},"si":2,"skillbonus":"","availability":"P","equipped":false,"bulk":0,"cost":null,"description":"<p>Military Hard Shell Blocks 10 sieverts per hour. If it receives more than 10 sieverts per hour, after use must be destroyed.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.UZ2CjvWmbIkFIj23"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092706892,"modifiedTime":1672108685294,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"YXFJ4D4pJDoZWSw5"}
|
||||
{"name":"Yokohama Mobile Security Suit","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"","locations":{"head":{"protected":true,"max":15,"value":0},"abdomen":{"protected":true,"max":15,"value":0},"chest":{"protected":true,"max":15,"value":0},"leftleg":{"protected":true,"max":15,"value":0},"rightleg":{"protected":true,"max":15,"value":0},"leftarm":{"protected":true,"max":15,"value":0},"rightarm":{"protected":true,"max":15,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":null,"description":"<p>Yokohama Mobile Security Suit provides +10% intimidation.<br><br></p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.dKcY7rwZY3XewoAW"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092155187,"modifiedTime":1672108708302,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"eNEC6AHRYrwGgS6I"}
|
||||
{"name":"Ridgy Security Armour","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Ridgy Plast","locations":{"head":{"protected":true,"max":12,"value":0},"abdomen":{"protected":true,"max":12,"value":0},"chest":{"protected":true,"max":12,"value":0},"leftleg":{"protected":true,"max":12,"value":0},"rightleg":{"protected":true,"max":12,"value":0},"leftarm":{"protected":true,"max":12,"value":0},"rightarm":{"protected":true,"max":12,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":7000,"description":"<p>Ridgy Security Armour</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.DUcIIRnBywEYtE3c"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092084700,"modifiedTime":1672108689908,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"pOhc7ydvFhJ29gvE"}
|
||||
{"name":"Tycon Mobile Security Suit","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"Ridgy Plast","locations":{"head":{"protected":true,"max":15,"value":0},"abdomen":{"protected":true,"max":15,"value":0},"chest":{"protected":true,"max":15,"value":0},"leftleg":{"protected":true,"max":12,"value":0},"rightleg":{"protected":true,"max":12,"value":0},"leftarm":{"protected":true,"max":12,"value":0},"rightarm":{"protected":true,"max":12,"value":0}},"si":1,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":22000,"description":""},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.fDmEK9nfCtV3AVR2"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672092242012,"modifiedTime":1672108703462,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"pU3vlWEAWRamT58h"}
|
||||
{"name":"Skin Suit Rad Proof (environmentally sealed)","type":"armor","img":"systems/fvtt-dark-stars/images/icons/armor.webp","system":{"armortype":"","locations":{"head":{"protected":true,"max":2,"value":0},"abdomen":{"protected":true,"max":2,"value":0},"chest":{"protected":true,"max":2,"value":0},"leftleg":{"protected":true,"max":2,"value":0},"rightleg":{"protected":true,"max":2,"value":0},"leftarm":{"protected":true,"max":2,"value":0},"rightarm":{"protected":true,"max":2,"value":0}},"si":0,"skillbonus":"","availability":"C","equipped":false,"bulk":0,"cost":null,"description":"<p>Skin Suit Rad Proof (environmentally sealed)</p>\n<p>10 hours life support, often worn under armour. Blocks 5 sieverts per hour. If it receives more than 5 sieverts per hour, after use must be destroyed.</p>"},"effects":[],"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3},"flags":{"core":{"sourceId":"Item.Q156jztUqVkicxaF"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672091868386,"modifiedTime":1672108697085,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"folder":null,"sort":0,"_id":"q9JGWL4y4udYrzvD"}
|
BIN
packs/armor/000186.ldb
Normal file
BIN
packs/armor/000186.ldb
Normal file
Binary file not shown.
1
packs/armor/CURRENT
Normal file
1
packs/armor/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000199
|
8
packs/armor/LOG
Normal file
8
packs/armor/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:11:04.806524 7f0422a006c0 Recovering log #197
|
||||
2024/02/25-13:11:04.817703 7f0422a006c0 Delete type=3 #195
|
||||
2024/02/25-13:11:04.817799 7f0422a006c0 Delete type=0 #197
|
||||
2024/02/25-13:14:07.532693 7f0421a006c0 Level-0 table #202: started
|
||||
2024/02/25-13:14:07.532731 7f0421a006c0 Level-0 table #202: 0 bytes OK
|
||||
2024/02/25-13:14:07.539153 7f0421a006c0 Delete type=0 #200
|
||||
2024/02/25-13:14:07.539281 7f0421a006c0 Manual compaction at level-0 from '!items!0JWjCJaD6OOouqTj' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:14:07.539306 7f0421a006c0 Manual compaction at level-1 from '!items!0JWjCJaD6OOouqTj' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
8
packs/armor/LOG.old
Normal file
8
packs/armor/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:04:05.224949 7f0428e006c0 Recovering log #193
|
||||
2024/02/25-13:04:05.236046 7f0428e006c0 Delete type=3 #191
|
||||
2024/02/25-13:04:05.236134 7f0428e006c0 Delete type=0 #193
|
||||
2024/02/25-13:10:09.480522 7f0421a006c0 Level-0 table #198: started
|
||||
2024/02/25-13:10:09.480555 7f0421a006c0 Level-0 table #198: 0 bytes OK
|
||||
2024/02/25-13:10:09.486678 7f0421a006c0 Delete type=0 #196
|
||||
2024/02/25-13:10:09.493365 7f0421a006c0 Manual compaction at level-0 from '!items!0JWjCJaD6OOouqTj' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:10:09.499939 7f0421a006c0 Manual compaction at level-1 from '!items!0JWjCJaD6OOouqTj' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
BIN
packs/armor/MANIFEST-000199
Normal file
BIN
packs/armor/MANIFEST-000199
Normal file
Binary file not shown.
BIN
packs/beyondtheblacksea/000124.ldb
Normal file
BIN
packs/beyondtheblacksea/000124.ldb
Normal file
Binary file not shown.
1
packs/beyondtheblacksea/CURRENT
Normal file
1
packs/beyondtheblacksea/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000201
|
0
packs/beyondtheblacksea/LOCK
Normal file
0
packs/beyondtheblacksea/LOCK
Normal file
7
packs/beyondtheblacksea/LOG
Normal file
7
packs/beyondtheblacksea/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:40.426654 7f3f0ea006c0 Recovering log #199
|
||||
2024/06/12-11:13:40.437435 7f3f0ea006c0 Delete type=3 #197
|
||||
2024/06/12-11:13:40.437506 7f3f0ea006c0 Delete type=0 #199
|
||||
2024/06/12-11:16:23.521086 7f3f060006c0 Level-0 table #204: started
|
||||
2024/06/12-11:16:23.521151 7f3f060006c0 Level-0 table #204: 0 bytes OK
|
||||
2024/06/12-11:16:23.553911 7f3f060006c0 Delete type=0 #202
|
||||
2024/06/12-11:16:23.590700 7f3f060006c0 Manual compaction at level-0 from '!folders!47aGmBuk1mHtbFFU' @ 72057594037927935 : 1 .. '!items!zwMpjsE84sk26eej' @ 0 : 0; will stop at (end)
|
7
packs/beyondtheblacksea/LOG.old
Normal file
7
packs/beyondtheblacksea/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:16.262812 7f3f0d6006c0 Recovering log #195
|
||||
2024/06/12-11:13:16.272606 7f3f0d6006c0 Delete type=3 #193
|
||||
2024/06/12-11:13:16.272662 7f3f0d6006c0 Delete type=0 #195
|
||||
2024/06/12-11:13:34.727044 7f3f060006c0 Level-0 table #200: started
|
||||
2024/06/12-11:13:34.727098 7f3f060006c0 Level-0 table #200: 0 bytes OK
|
||||
2024/06/12-11:13:34.733076 7f3f060006c0 Delete type=0 #198
|
||||
2024/06/12-11:13:34.733265 7f3f060006c0 Manual compaction at level-0 from '!folders!47aGmBuk1mHtbFFU' @ 72057594037927935 : 1 .. '!items!zwMpjsE84sk26eej' @ 0 : 0; will stop at (end)
|
BIN
packs/beyondtheblacksea/MANIFEST-000201
Normal file
BIN
packs/beyondtheblacksea/MANIFEST-000201
Normal file
Binary file not shown.
0
packs/conditions/000256.log
Normal file
0
packs/conditions/000256.log
Normal file
1
packs/conditions/CURRENT
Normal file
1
packs/conditions/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000254
|
0
packs/conditions/LOCK
Normal file
0
packs/conditions/LOCK
Normal file
7
packs/conditions/LOG
Normal file
7
packs/conditions/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:40.356313 7f3f0d6006c0 Recovering log #252
|
||||
2024/06/12-11:13:40.366003 7f3f0d6006c0 Delete type=3 #250
|
||||
2024/06/12-11:13:40.366126 7f3f0d6006c0 Delete type=0 #252
|
||||
2024/06/12-11:16:23.317811 7f3f060006c0 Level-0 table #257: started
|
||||
2024/06/12-11:16:23.317841 7f3f060006c0 Level-0 table #257: 0 bytes OK
|
||||
2024/06/12-11:16:23.355645 7f3f060006c0 Delete type=0 #255
|
||||
2024/06/12-11:16:23.460439 7f3f060006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
7
packs/conditions/LOG.old
Normal file
7
packs/conditions/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:16.189039 7f3f0ea006c0 Recovering log #248
|
||||
2024/06/12-11:13:16.200829 7f3f0ea006c0 Delete type=3 #246
|
||||
2024/06/12-11:13:16.200927 7f3f0ea006c0 Delete type=0 #248
|
||||
2024/06/12-11:13:34.657802 7f3f060006c0 Level-0 table #253: started
|
||||
2024/06/12-11:13:34.657837 7f3f060006c0 Level-0 table #253: 0 bytes OK
|
||||
2024/06/12-11:13:34.663971 7f3f060006c0 Delete type=0 #251
|
||||
2024/06/12-11:13:34.681143 7f3f060006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
BIN
packs/conditions/MANIFEST-000254
Normal file
BIN
packs/conditions/MANIFEST-000254
Normal file
Binary file not shown.
0
packs/currency/000256.log
Normal file
0
packs/currency/000256.log
Normal file
1
packs/currency/CURRENT
Normal file
1
packs/currency/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000254
|
0
packs/currency/LOCK
Normal file
0
packs/currency/LOCK
Normal file
7
packs/currency/LOG
Normal file
7
packs/currency/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:40.368093 7f3f0ea006c0 Recovering log #252
|
||||
2024/06/12-11:13:40.379978 7f3f0ea006c0 Delete type=3 #250
|
||||
2024/06/12-11:13:40.380078 7f3f0ea006c0 Delete type=0 #252
|
||||
2024/06/12-11:16:23.408873 7f3f060006c0 Level-0 table #257: started
|
||||
2024/06/12-11:16:23.408929 7f3f060006c0 Level-0 table #257: 0 bytes OK
|
||||
2024/06/12-11:16:23.460072 7f3f060006c0 Delete type=0 #255
|
||||
2024/06/12-11:16:23.460493 7f3f060006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
7
packs/currency/LOG.old
Normal file
7
packs/currency/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:16.204139 7f3f0d6006c0 Recovering log #248
|
||||
2024/06/12-11:13:16.215399 7f3f0d6006c0 Delete type=3 #246
|
||||
2024/06/12-11:13:16.215490 7f3f0d6006c0 Delete type=0 #248
|
||||
2024/06/12-11:13:34.692534 7f3f060006c0 Level-0 table #253: started
|
||||
2024/06/12-11:13:34.692577 7f3f060006c0 Level-0 table #253: 0 bytes OK
|
||||
2024/06/12-11:13:34.698872 7f3f060006c0 Delete type=0 #251
|
||||
2024/06/12-11:13:34.713306 7f3f060006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
BIN
packs/currency/MANIFEST-000254
Normal file
BIN
packs/currency/MANIFEST-000254
Normal file
Binary file not shown.
BIN
packs/cybernetics/000115.ldb
Normal file
BIN
packs/cybernetics/000115.ldb
Normal file
Binary file not shown.
0
packs/cybernetics/000130.log
Normal file
0
packs/cybernetics/000130.log
Normal file
1
packs/cybernetics/CURRENT
Normal file
1
packs/cybernetics/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000128
|
0
packs/cybernetics/LOCK
Normal file
0
packs/cybernetics/LOCK
Normal file
8
packs/cybernetics/LOG
Normal file
8
packs/cybernetics/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:11:04.911848 7f0422a006c0 Recovering log #126
|
||||
2024/02/25-13:11:04.922320 7f0422a006c0 Delete type=3 #124
|
||||
2024/02/25-13:11:04.922392 7f0422a006c0 Delete type=0 #126
|
||||
2024/02/25-13:14:07.578457 7f0421a006c0 Level-0 table #131: started
|
||||
2024/02/25-13:14:07.578513 7f0421a006c0 Level-0 table #131: 0 bytes OK
|
||||
2024/02/25-13:14:07.585654 7f0421a006c0 Delete type=0 #129
|
||||
2024/02/25-13:14:07.592632 7f0421a006c0 Manual compaction at level-0 from '!items!0SbSmYdxJSlcNr6x' @ 72057594037927935 : 1 .. '!items!yyCPVVl8vmMOfPcN' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:14:07.592676 7f0421a006c0 Manual compaction at level-1 from '!items!0SbSmYdxJSlcNr6x' @ 72057594037927935 : 1 .. '!items!yyCPVVl8vmMOfPcN' @ 0 : 0; will stop at (end)
|
8
packs/cybernetics/LOG.old
Normal file
8
packs/cybernetics/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:04:05.332283 7f0428e006c0 Recovering log #122
|
||||
2024/02/25-13:04:05.343337 7f0428e006c0 Delete type=3 #120
|
||||
2024/02/25-13:04:05.343387 7f0428e006c0 Delete type=0 #122
|
||||
2024/02/25-13:10:09.539934 7f0421a006c0 Level-0 table #127: started
|
||||
2024/02/25-13:10:09.539956 7f0421a006c0 Level-0 table #127: 0 bytes OK
|
||||
2024/02/25-13:10:09.546327 7f0421a006c0 Delete type=0 #125
|
||||
2024/02/25-13:10:09.552649 7f0421a006c0 Manual compaction at level-0 from '!items!0SbSmYdxJSlcNr6x' @ 72057594037927935 : 1 .. '!items!yyCPVVl8vmMOfPcN' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:10:09.552755 7f0421a006c0 Manual compaction at level-1 from '!items!0SbSmYdxJSlcNr6x' @ 72057594037927935 : 1 .. '!items!yyCPVVl8vmMOfPcN' @ 0 : 0; will stop at (end)
|
BIN
packs/cybernetics/MANIFEST-000128
Normal file
BIN
packs/cybernetics/MANIFEST-000128
Normal file
Binary file not shown.
BIN
packs/darkstars-sf/000005.ldb
Normal file
BIN
packs/darkstars-sf/000005.ldb
Normal file
Binary file not shown.
0
packs/darkstars-sf/000068.log
Normal file
0
packs/darkstars-sf/000068.log
Normal file
1
packs/darkstars-sf/CURRENT
Normal file
1
packs/darkstars-sf/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000066
|
0
packs/darkstars-sf/LOCK
Normal file
0
packs/darkstars-sf/LOCK
Normal file
8
packs/darkstars-sf/LOG
Normal file
8
packs/darkstars-sf/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/06/12-11:13:40.398008 7f3f0d6006c0 Recovering log #64
|
||||
2024/06/12-11:13:40.408278 7f3f0d6006c0 Delete type=3 #62
|
||||
2024/06/12-11:13:40.408353 7f3f0d6006c0 Delete type=0 #64
|
||||
2024/06/12-11:16:23.554104 7f3f060006c0 Level-0 table #69: started
|
||||
2024/06/12-11:16:23.554144 7f3f060006c0 Level-0 table #69: 0 bytes OK
|
||||
2024/06/12-11:16:23.590465 7f3f060006c0 Delete type=0 #67
|
||||
2024/06/12-11:16:23.590737 7f3f060006c0 Manual compaction at level-0 from '!folders!La3YsNYFddQnmsba' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
||||
2024/06/12-11:16:23.590756 7f3f060006c0 Manual compaction at level-1 from '!folders!La3YsNYFddQnmsba' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
8
packs/darkstars-sf/LOG.old
Normal file
8
packs/darkstars-sf/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/06/12-11:13:16.233304 7f3f0ea006c0 Recovering log #60
|
||||
2024/06/12-11:13:16.243341 7f3f0ea006c0 Delete type=3 #58
|
||||
2024/06/12-11:13:16.243395 7f3f0ea006c0 Delete type=0 #60
|
||||
2024/06/12-11:13:34.713340 7f3f060006c0 Level-0 table #65: started
|
||||
2024/06/12-11:13:34.713379 7f3f060006c0 Level-0 table #65: 0 bytes OK
|
||||
2024/06/12-11:13:34.719558 7f3f060006c0 Delete type=0 #63
|
||||
2024/06/12-11:13:34.733213 7f3f060006c0 Manual compaction at level-0 from '!folders!La3YsNYFddQnmsba' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
||||
2024/06/12-11:13:34.733290 7f3f060006c0 Manual compaction at level-1 from '!folders!La3YsNYFddQnmsba' @ 72057594037927935 : 1 .. '!items!zzDfuUJpQzzz262R' @ 0 : 0; will stop at (end)
|
BIN
packs/darkstars-sf/MANIFEST-000066
Normal file
BIN
packs/darkstars-sf/MANIFEST-000066
Normal file
Binary file not shown.
BIN
packs/equipment/000186.ldb
Normal file
BIN
packs/equipment/000186.ldb
Normal file
Binary file not shown.
0
packs/equipment/000201.log
Normal file
0
packs/equipment/000201.log
Normal file
1
packs/equipment/CURRENT
Normal file
1
packs/equipment/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000199
|
0
packs/equipment/LOCK
Normal file
0
packs/equipment/LOCK
Normal file
8
packs/equipment/LOG
Normal file
8
packs/equipment/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:11:04.819236 7f0428e006c0 Recovering log #197
|
||||
2024/02/25-13:11:04.829162 7f0428e006c0 Delete type=3 #195
|
||||
2024/02/25-13:11:04.829232 7f0428e006c0 Delete type=0 #197
|
||||
2024/02/25-13:14:07.545758 7f0421a006c0 Level-0 table #202: started
|
||||
2024/02/25-13:14:07.545813 7f0421a006c0 Level-0 table #202: 0 bytes OK
|
||||
2024/02/25-13:14:07.552067 7f0421a006c0 Delete type=0 #200
|
||||
2024/02/25-13:14:07.565492 7f0421a006c0 Manual compaction at level-0 from '!items!05RVU3UcRabogEvL' @ 72057594037927935 : 1 .. '!items!zaxcUsWUZ1vvl0p8' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:14:07.565529 7f0421a006c0 Manual compaction at level-1 from '!items!05RVU3UcRabogEvL' @ 72057594037927935 : 1 .. '!items!zaxcUsWUZ1vvl0p8' @ 0 : 0; will stop at (end)
|
8
packs/equipment/LOG.old
Normal file
8
packs/equipment/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:04:05.239972 7f0423e006c0 Recovering log #193
|
||||
2024/02/25-13:04:05.249512 7f0423e006c0 Delete type=3 #191
|
||||
2024/02/25-13:04:05.249560 7f0423e006c0 Delete type=0 #193
|
||||
2024/02/25-13:10:09.473431 7f0421a006c0 Level-0 table #198: started
|
||||
2024/02/25-13:10:09.473459 7f0421a006c0 Level-0 table #198: 0 bytes OK
|
||||
2024/02/25-13:10:09.480345 7f0421a006c0 Delete type=0 #196
|
||||
2024/02/25-13:10:09.493344 7f0421a006c0 Manual compaction at level-0 from '!items!05RVU3UcRabogEvL' @ 72057594037927935 : 1 .. '!items!zaxcUsWUZ1vvl0p8' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:10:09.499930 7f0421a006c0 Manual compaction at level-1 from '!items!05RVU3UcRabogEvL' @ 72057594037927935 : 1 .. '!items!zaxcUsWUZ1vvl0p8' @ 0 : 0; will stop at (end)
|
BIN
packs/equipment/MANIFEST-000199
Normal file
BIN
packs/equipment/MANIFEST-000199
Normal file
Binary file not shown.
BIN
packs/genetics/000014.ldb
Normal file
BIN
packs/genetics/000014.ldb
Normal file
Binary file not shown.
0
packs/genetics/000077.log
Normal file
0
packs/genetics/000077.log
Normal file
1
packs/genetics/CURRENT
Normal file
1
packs/genetics/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000075
|
0
packs/genetics/LOCK
Normal file
0
packs/genetics/LOCK
Normal file
8
packs/genetics/LOG
Normal file
8
packs/genetics/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:11:04.925036 7f0428e006c0 Recovering log #73
|
||||
2024/02/25-13:11:04.935090 7f0428e006c0 Delete type=3 #71
|
||||
2024/02/25-13:11:04.935353 7f0428e006c0 Delete type=0 #73
|
||||
2024/02/25-13:14:07.585843 7f0421a006c0 Level-0 table #78: started
|
||||
2024/02/25-13:14:07.585896 7f0421a006c0 Level-0 table #78: 0 bytes OK
|
||||
2024/02/25-13:14:07.592513 7f0421a006c0 Delete type=0 #76
|
||||
2024/02/25-13:14:07.592640 7f0421a006c0 Manual compaction at level-0 from '!items!56A3sVsiN7KI6a45' @ 72057594037927935 : 1 .. '!items!zJiASbV3QqH2oHb1' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:14:07.592670 7f0421a006c0 Manual compaction at level-1 from '!items!56A3sVsiN7KI6a45' @ 72057594037927935 : 1 .. '!items!zJiASbV3QqH2oHb1' @ 0 : 0; will stop at (end)
|
8
packs/genetics/LOG.old
Normal file
8
packs/genetics/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:04:05.347457 7f0423e006c0 Recovering log #69
|
||||
2024/02/25-13:04:05.356885 7f0423e006c0 Delete type=3 #67
|
||||
2024/02/25-13:04:05.356934 7f0423e006c0 Delete type=0 #69
|
||||
2024/02/25-13:10:09.533502 7f0421a006c0 Level-0 table #74: started
|
||||
2024/02/25-13:10:09.533526 7f0421a006c0 Level-0 table #74: 0 bytes OK
|
||||
2024/02/25-13:10:09.539823 7f0421a006c0 Delete type=0 #72
|
||||
2024/02/25-13:10:09.552630 7f0421a006c0 Manual compaction at level-0 from '!items!56A3sVsiN7KI6a45' @ 72057594037927935 : 1 .. '!items!zJiASbV3QqH2oHb1' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:10:09.552738 7f0421a006c0 Manual compaction at level-1 from '!items!56A3sVsiN7KI6a45' @ 72057594037927935 : 1 .. '!items!zJiASbV3QqH2oHb1' @ 0 : 0; will stop at (end)
|
BIN
packs/genetics/MANIFEST-000075
Normal file
BIN
packs/genetics/MANIFEST-000075
Normal file
Binary file not shown.
BIN
packs/nightborough/000132.ldb
Normal file
BIN
packs/nightborough/000132.ldb
Normal file
Binary file not shown.
0
packs/nightborough/000223.log
Normal file
0
packs/nightborough/000223.log
Normal file
1
packs/nightborough/CURRENT
Normal file
1
packs/nightborough/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000221
|
0
packs/nightborough/LOCK
Normal file
0
packs/nightborough/LOCK
Normal file
7
packs/nightborough/LOG
Normal file
7
packs/nightborough/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:40.440639 7f3f0d6006c0 Recovering log #219
|
||||
2024/06/12-11:13:40.450523 7f3f0d6006c0 Delete type=3 #217
|
||||
2024/06/12-11:13:40.450593 7f3f0d6006c0 Delete type=0 #219
|
||||
2024/06/12-11:16:23.645974 7f3f060006c0 Level-0 table #224: started
|
||||
2024/06/12-11:16:23.646004 7f3f060006c0 Level-0 table #224: 0 bytes OK
|
||||
2024/06/12-11:16:23.683161 7f3f060006c0 Delete type=0 #222
|
||||
2024/06/12-11:16:23.683408 7f3f060006c0 Manual compaction at level-0 from '!folders!2iZtDz80npHPIwkS' @ 72057594037927935 : 1 .. '!items!zyFR9C1jBTeFzbxg' @ 0 : 0; will stop at (end)
|
7
packs/nightborough/LOG.old
Normal file
7
packs/nightborough/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/06/12-11:13:16.276335 7f3f0ea006c0 Recovering log #215
|
||||
2024/06/12-11:13:16.287074 7f3f0ea006c0 Delete type=3 #213
|
||||
2024/06/12-11:13:16.287130 7f3f0ea006c0 Delete type=0 #215
|
||||
2024/06/12-11:13:34.733411 7f3f060006c0 Level-0 table #220: started
|
||||
2024/06/12-11:13:34.733492 7f3f060006c0 Level-0 table #220: 0 bytes OK
|
||||
2024/06/12-11:13:34.741601 7f3f060006c0 Delete type=0 #218
|
||||
2024/06/12-11:13:34.741825 7f3f060006c0 Manual compaction at level-0 from '!folders!2iZtDz80npHPIwkS' @ 72057594037927935 : 1 .. '!items!zyFR9C1jBTeFzbxg' @ 0 : 0; will stop at (end)
|
BIN
packs/nightborough/MANIFEST-000221
Normal file
BIN
packs/nightborough/MANIFEST-000221
Normal file
Binary file not shown.
BIN
packs/perks/000186.ldb
Normal file
BIN
packs/perks/000186.ldb
Normal file
Binary file not shown.
0
packs/perks/000201.log
Normal file
0
packs/perks/000201.log
Normal file
1
packs/perks/CURRENT
Normal file
1
packs/perks/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000199
|
0
packs/perks/LOCK
Normal file
0
packs/perks/LOCK
Normal file
8
packs/perks/LOG
Normal file
8
packs/perks/LOG
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:11:04.899830 7f0428e006c0 Recovering log #197
|
||||
2024/02/25-13:11:04.909890 7f0428e006c0 Delete type=3 #195
|
||||
2024/02/25-13:11:04.909976 7f0428e006c0 Delete type=0 #197
|
||||
2024/02/25-13:14:07.614576 7f0421a006c0 Level-0 table #202: started
|
||||
2024/02/25-13:14:07.614602 7f0421a006c0 Level-0 table #202: 0 bytes OK
|
||||
2024/02/25-13:14:07.621467 7f0421a006c0 Delete type=0 #200
|
||||
2024/02/25-13:14:07.628014 7f0421a006c0 Manual compaction at level-0 from '!items!0K3CVEKsq67oKiYE' @ 72057594037927935 : 1 .. '!items!zwZoHMkWYtMCNx9f' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:14:07.628055 7f0421a006c0 Manual compaction at level-1 from '!items!0K3CVEKsq67oKiYE' @ 72057594037927935 : 1 .. '!items!zwZoHMkWYtMCNx9f' @ 0 : 0; will stop at (end)
|
8
packs/perks/LOG.old
Normal file
8
packs/perks/LOG.old
Normal file
@ -0,0 +1,8 @@
|
||||
2024/02/25-13:04:05.318599 7f0423e006c0 Recovering log #193
|
||||
2024/02/25-13:04:05.328529 7f0423e006c0 Delete type=3 #191
|
||||
2024/02/25-13:04:05.328597 7f0423e006c0 Delete type=0 #193
|
||||
2024/02/25-13:10:09.519595 7f0421a006c0 Level-0 table #198: started
|
||||
2024/02/25-13:10:09.519645 7f0421a006c0 Level-0 table #198: 0 bytes OK
|
||||
2024/02/25-13:10:09.526863 7f0421a006c0 Delete type=0 #196
|
||||
2024/02/25-13:10:09.527031 7f0421a006c0 Manual compaction at level-0 from '!items!0K3CVEKsq67oKiYE' @ 72057594037927935 : 1 .. '!items!zwZoHMkWYtMCNx9f' @ 0 : 0; will stop at (end)
|
||||
2024/02/25-13:10:09.527062 7f0421a006c0 Manual compaction at level-1 from '!items!0K3CVEKsq67oKiYE' @ 72057594037927935 : 1 .. '!items!zwZoHMkWYtMCNx9f' @ 0 : 0; will stop at (end)
|
BIN
packs/perks/MANIFEST-000199
Normal file
BIN
packs/perks/MANIFEST-000199
Normal file
Binary file not shown.
0
packs/shields/000200.log
Normal file
0
packs/shields/000200.log
Normal file
1
packs/shields/CURRENT
Normal file
1
packs/shields/CURRENT
Normal file
@ -0,0 +1 @@
|
||||
MANIFEST-000198
|
0
packs/shields/LOCK
Normal file
0
packs/shields/LOCK
Normal file
7
packs/shields/LOG
Normal file
7
packs/shields/LOG
Normal file
@ -0,0 +1,7 @@
|
||||
2024/02/25-13:11:04.832847 7f0422a006c0 Recovering log #196
|
||||
2024/02/25-13:11:04.844534 7f0422a006c0 Delete type=3 #194
|
||||
2024/02/25-13:11:04.844584 7f0422a006c0 Delete type=0 #196
|
||||
2024/02/25-13:14:07.539362 7f0421a006c0 Level-0 table #201: started
|
||||
2024/02/25-13:14:07.539386 7f0421a006c0 Level-0 table #201: 0 bytes OK
|
||||
2024/02/25-13:14:07.545589 7f0421a006c0 Delete type=0 #199
|
||||
2024/02/25-13:14:07.565459 7f0421a006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
7
packs/shields/LOG.old
Normal file
7
packs/shields/LOG.old
Normal file
@ -0,0 +1,7 @@
|
||||
2024/02/25-13:04:05.255291 7f0428e006c0 Recovering log #192
|
||||
2024/02/25-13:04:05.265834 7f0428e006c0 Delete type=3 #190
|
||||
2024/02/25-13:04:05.265885 7f0428e006c0 Delete type=0 #192
|
||||
2024/02/25-13:10:09.486767 7f0421a006c0 Level-0 table #197: started
|
||||
2024/02/25-13:10:09.486786 7f0421a006c0 Level-0 table #197: 0 bytes OK
|
||||
2024/02/25-13:10:09.493210 7f0421a006c0 Delete type=0 #195
|
||||
2024/02/25-13:10:09.499919 7f0421a006c0 Manual compaction at level-0 from 'undefined' @ 72057594037927935 : 1 .. 'undefined' @ 0 : 0; will stop at (end)
|
BIN
packs/shields/MANIFEST-000198
Normal file
BIN
packs/shields/MANIFEST-000198
Normal file
Binary file not shown.
@ -1,23 +0,0 @@
|
||||
{"name":"Vehicle Weapons","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is skilled in the use of indirect and direct artillery including missiles, howitzers<br>and auto cannons, any vehicle weapons.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086342604,"modifiedTime":1672086575155,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"5YJWuGaagmi1dgbv","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Engineering (Name of Field)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"asb","bonus":0,"used":false,"description":"<p>The character has a university-level education in an Engineering skill chosen from the list<br>below. The character can design and direct construction in the field. For example, Sam has Engineering (Computer Systems) 60%. He decides to make a supercomputer out of several<br>desktop PCs – he can do this. Furthermore, he can direct people who can help him.</p>\n<p><br>Civil, Electrical and Power, Computer Systems, Naval and Life Support, Mechanical, Propulsion Systems, Architecture, Robotics & Mechatronics, Genetics, Cybernetic Design, Nanomachines, Weapons Systems, Personal Weapons and Armour Design.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085548127,"modifiedTime":1672086575152,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"9a1riW3iSabgr4sH","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Basic Ground Navigation","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"asb","bonus":0,"used":false,"description":"<p>The character can navigate by map and compass, by land or sea. Navigation can be by the sun, stars or compass.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085470278,"modifiedTime":1672086575152,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"ESvBNzSQ6UVa2Hdj","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Persuasion & Manipulation","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"ssb","bonus":0,"used":false,"description":"<p>The character can persuade others to do what he or she wants or to provide information. This<br>is non-violent persuasion. The game master may oppose the skill check using the NPC persuasion<br>skill. Role-playing well may provide a bonus to the use of this skill; however, not roleplaying may attract a penalty. This skill must be carefully refereed by the game master. Typical Persuasion checks may be used to ask someone for information or help in some way. It is not possible to persuade someone to knowingly harm themselves; however, it could be used to trick a person into doing something against their best interests. This skill is not mind control; it is careful persuasion. When a character chooses to manipulate a person, it is similar to persuasion; however, rather than truthful reasoning, manipulation is deceitful.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085115239,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"EZV7SCG4WbkervUv","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Projectile Weapons","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is trained in the use and maintenance of projectile weapons like rifles, pistols and dart launchers. The character is trained in the use and maintenance of rail weapons like rail rifles, rail SMGs and rail assault weapons.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086276980,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"I8HWWCwhF7R19u6x","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Speak & Read (Language)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"ssb","bonus":0,"used":false,"description":"<p>Speak Language is used whenever a character is not very good at the dialect he or she is trying to communicate in. If the language skills of both participants total 50%, then communication is assured, and no Language roll is necessary.</p>\n<p>Reading a language allows the character to read and understand the written word. Characters may need to roll at the GM’s suggestion on their Speak and Read Language skill. Otherwise, understanding is assured. The following list of languages and scripts can be used, although there are of course more languages.<br><br>Spoken and Written Languages Examples<br>English, Spanish, Portuguese, Mandarin, Hindi, Chinese, German, Russian, Italian, Korean, Japanese.</p>"},"effects":[],"flags":{"core":{"sheetClass":"fvtt-dark-stars.DarkStarsItemSheet"}},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1671852339032,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"IW0nw7bk83QQItjF","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Stealth","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"psb","bonus":0,"used":false,"description":"<p>The Stealth skill involves hiding, sneaking and generally moving without being detected by sound or sight. A roll is always required for this skill whenever it is attempted.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085657806,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"JB8ItSbIQ4nnQk9U","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Heavy Weapons","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is skilled in the use of RPGs, grenade launchers and machine guns, and artillery pieces.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086320348,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"JGtOg9mUP0pZievc","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Science (Name of Science)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"asb","bonus":0,"used":false,"description":"<p>The character has a university-level education in a Science skill chosen from the list below.<br>Science skills are theoretical in nature. A Science skill can be used for an Engineering skill at half the value.</p>\n<p><br>Mathematics, Computer Science, Economics, Physics, Biology, Chemistry, Biochemistry, Medicine, Genetics, Archaeology, Astronomy, Geology, Psychology, Cybernetics, Pharmacology.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085504870,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"O6Gxntfqt0hGXvYW","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Energy Weapons","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is trained in the use and maintenance of personal lasers, ion guns, neural stunners and plasma weapons.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086249716,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"OB4khIPwWYlRXt6t","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Professional Skill (Name of Field/Role)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"asb","bonus":0,"used":false,"description":"<p>A variety of professions, usually learned through apprenticeship. Professions are usually<br>skills that involve acquiring the resource or crafting items from resources.<br><br>Includes <br>Medicine, Surgery*, Pharmaceuticals, Psychiatry+, Horticulture, Animal Husbandry, Forensic Examiner, Politics, Computer Security, Communications Specialist, Business, Military Tactics, Logistics, Manufacturing, Robot Brains, Armourer. <br><br>* requires Medicine + requires Psychology</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085414469,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"Sf4375GLeaEdXjz0","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Empathy","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"ssb","bonus":0,"used":false,"description":"<p>The character can perceive other people’s motives and motivations. This skill is useful when gathering information about likely actions and motivational options.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085187959,"modifiedTime":1672086575152,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"TAgwGCqdB61eBDJ3","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Recon","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"psb","bonus":0,"used":false,"description":"<p>Recon is basically observation. Characters have a basic level in this skill, and trained characters should have a higher rating in the skill. This skill is used whenever a character wishes to find something out or whenever the GM wishes to roll to see if the character spots or hears something.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085691670,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"Wiy2P34tbpFLpK7e","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Pilot (Vehicle Type)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"msb","bonus":0,"used":false,"description":"<p>The character is skilled in the use of vehicles. They can operate and perform basic maintenance and repairs. Examples of vehicles are wheeled vehicle, watercraft, spaceship, airplane, tracked vehicle, gravcraft, power armour and drones.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086377747,"modifiedTime":1672086575155,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"XmyIaZ07ngWvnIAD","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Social & Style","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"ssb","bonus":0,"used":false,"description":"<p>This skill is designed to enable a character to know what is fashionable in any given social<br>group. It also enables the character to behave with the correct etiquette for the social group<br>they are in at the time. This skill is used to determine advance actions. This is not a pursued<br>skill, however, if a role is played well it can provide a bonus in such situations.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1671852578894,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"dDzdnXRcwZRQZ5RG","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Drive Ground Car and Ride Motorcycle","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"msb","bonus":0,"used":false,"description":"<p>The character can drive cars and motorcycles. This is not a professional level of driving, just<br>everyday driving.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086514348,"modifiedTime":1672086575155,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"gQ7bFMrV47R02z3i","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Melee Combat","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is skilled at using riot shields, melee weapons and bladed weapons. If the game master chooses, this can be broken up into multiple skills; however, for simplicity we refer to this skill as melee combat.</p>\n<p>The character can use shields to block attacks. The character is skilled at knife and sword fighting. The character is also skilled in the use of mass weapons such as axes, two-handed swords, maces, hammers, batons, truncheons, clubs and polearms. Styles are: Kendo, Single Stick, Fencing etc.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086188534,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"hdOSBK7SwELJMzZb","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Demolitions","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"msb","bonus":0,"used":false,"description":"<p>The character is skilled in the art of laying explosives, creatively setting fuses and generally blowing stuff up.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086436924,"modifiedTime":1672086575155,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"kNVEnbgz68l5H6F7","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Basic Education","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"asb","bonus":0,"used":false,"description":"<p>This skill includes a variety of catch-all skills from simple mathematics to geography, history, literacy and general knowhow. This skill is also special in that it starts as the character’s Education x 2, and then points may be spent to increase it. All characters start with this skill just as they have their native language. Spending points on this skill means the character has more depth to their knowledge. More educated characters know more about a variety of subjects. Game masters must decide if this skill can be used for any given task.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085276422,"modifiedTime":1672086575152,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"lCcvKGDWbmNqZmM4","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Unarmed Combat","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"csb","bonus":0,"used":false,"description":"<p>The character is skilled in the use of unarmed combat. They are practised and professional, and know how to use their body, fists and feet to devastating effect.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085777245,"modifiedTime":1672086575154,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"ouxLcHbuWWKhJQg9","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Athletics","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"psb","bonus":0,"used":false,"description":"<p>The Athletics skill is used for any form of physical activity. Jumping, dodging, climbing, abseiling, running, throwing, swimming and others can be chosen. This skill is very broad and represents the education characters received in school and while they were growing up. Rolls are required at the GM’s discretion. Athletics can be substituted for Unarmed Combat, but at half value.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085605799,"modifiedTime":1672086575152,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"wPq70BdgDHP6H4lD","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"Graft (Type)","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"ssb","bonus":0,"used":false,"description":"<p>Graft refers to all forms of illegal activities. This skill includes bribery, streetwise, gambling,<br>racketeering, sales, bureaucracy, fencing and pimping.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672085235048,"modifiedTime":1672086575153,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"xVquq7UFdm1S4FdJ","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
||||
{"name":"First Aid","type":"skill","img":"systems/fvtt-dark-stars/images/icons/skill.webp","system":{"base":"msb","bonus":0,"used":false,"description":"<p>The character can perform basic first aid, stop bleeding and perform CPR. This skill enables the character to dress wounds and apply bandages.</p>"},"effects":[],"flags":{},"_stats":{"systemId":"fvtt-dark-stars","systemVersion":"10.0.4","coreVersion":"10.291","createdTime":1672086482524,"modifiedTime":1672086575155,"lastModifiedBy":"LUaXSjYdxSzrwCtU"},"_id":"yo7mOkfbbOogx8na","folder":null,"sort":0,"ownership":{"default":0,"LUaXSjYdxSzrwCtU":3}}
|
BIN
packs/skills/000186.ldb
Normal file
BIN
packs/skills/000186.ldb
Normal file
Binary file not shown.
0
packs/skills/000201.log
Normal file
0
packs/skills/000201.log
Normal file
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user