Skip to content

Commit

Permalink
0.9.6
Browse files Browse the repository at this point in the history
  • Loading branch information
crnormand committed May 20, 2021
2 parents 7bf0860 + 321fdc7 commit 1a02829
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 42 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# [Users Guide](https://bit.ly/2JaSlQd) for GURPS 4e Game Aid for Foundry VTT
If you can't access the Google doc, here is a [PDF](https://github.com/crnormand/gurps/raw/main/docs/Guide%20for%20GURPS%204e%20on%20Foundry%20VTT.pdf) of the latest version.
# Current Release Version 0.9.5
# Current Release Version 0.9.6
### [Change Log](changelog.md)
The list was getting just too long, so it has been moved to a separate file. Click above to see what has changed.

Expand Down
11 changes: 9 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ If you can't access the Google doc, here is a [PDF](https://github.com/crnormand

This is what we are currently working on:

## History

0.9.6 - 5/20/2021

- Update migration code to remove possible infinite loop issue
- Make Skill/Spell/Attack (Melee/Ranged/Damage) OtF formulas case insensitive

0.9.5 - 5/19/2021

- Fixed /status command when token.actor == null
- Refactor regex pattern matching to utilities.js
- Added "apply condition" buttons to slam results chat messages. These buttons will select the affected combatant and either roll DX and apply the Prone condition if failed, or directly apply Prone if appropriate.
Expand Down Expand Up @@ -35,8 +44,6 @@ This is what we are currently working on:
- Added support for /qty detecting the current equipment
- Added support for parameters and return values from script macros (GURPS.chatargs & GURPS.chatreturn)

## History

0.9.4 - 5/06/2021

- Fixed /status command to accept either 't' or 'toggle'
Expand Down
38 changes: 38 additions & 0 deletions lib/migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { recurselist } from './utilities.js'
import * as Settings from './miscellaneous-settings.js'


export class Migration {

static async migrateTo096() {
ui.notifications.info("Please wait, migrating Actors to v0.9.6")
console.log("Migrating Actors to v0.9.6")
for ( let actor of game.actors.entities ) {
let commit = { "data.migrationversion" : '0.9.6' }
for (const attr in actor.data.data.attributes) {
if (actor.data.data.attributes[attr].import == null)
commit = { ...commit, ...{ ['data.attributes.' + attr + '.import']: actor.data.data.attributes[attr].value } }
}
recurselist(actor.data.data.skills, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.skills.' + k + '.import']: e.level || 1 } }
})
recurselist(actor.data.data.spells, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.spells.' + k + '.import']: e.level | 1 } }
})
recurselist(actor.data.data.melee, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.melee.' + k + '.import']: e.level | 1 } }
})
recurselist(actor.data.data.ranged, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.ranged.' + k + '.import']: e.level | 1} }
})
// We must delay the upgrade of older actor's 'import' keys, since upon startup, the actor may not know which collection it belongs to
if (Object.keys(commit).length > 0) {
console.log("Updating " + actor.name)
console.log(GURPS.objToString(commit))
await actor.update(commit)
}
}
ui.notifications.info("Migration to v0.9.6 complete!")
game.settings.set(Settings.SYSTEM_NAME, Settings.SETTING_MIGRATION_VERSION, '0.9.6')
}
}
11 changes: 11 additions & 0 deletions lib/miscellaneous-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Initiative from './initiative.js'
import { i18n } from '../lib/utilities.js'

export const SYSTEM_NAME = 'gurps'
export const SETTING_MIGRATION_VERSION = 'migration-version'
export const SETTING_DEFAULT_LOCATION = 'default-hitlocation'
export const SETTING_SIMPLE_DAMAGE = 'combat-simple-damage'
export const SETTING_APPLY_DIVISOR = 'combat-apply-divisor'
Expand Down Expand Up @@ -57,6 +58,16 @@ export function initializeSettings() {
onChange: value => console.log(`Change Log version : ${value}`),
})

// Keep track of the last version number
game.settings.register(SYSTEM_NAME, SETTING_MIGRATION_VERSION, {
name: 'Migration Version',
scope: 'world',
config: false,
type: String,
default: '0.0.0',
onChange: value => console.log(`Migration Log version : ${value}`),
})

// In case the user wants to see what changed between versions
game.settings.register(SYSTEM_NAME, SETTING_SHOW_CHANGELOG, {
name: "Show 'Read Me' on version change",
Expand Down
16 changes: 8 additions & 8 deletions lib/parselink.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,10 @@ export function parselink(str, htmldesc, clrdmods = false) {
// - ([^\|])* - COMMENT - zero or more run of characters that do not include |
// - (\|.*)? - REMAINDER - | followed by any run of characters (optional)
//
let parse = str.replace(/^S[pkPK]?:"([^"]+)" ?([-+]\d+)? ?([^\|]*)(\|.*)?/g, '$1~$2~$3~$4')
let parse = str.replace(/^S[pkPK]?:"([^"]+)" ?([-+]\d+)? ?([^\|]*)(\|.*)?/gi, '$1~$2~$3~$4')
if (parse == str) {
// Use quotes to capture skill/spell name (with as many * as they want to embed)
parse = str.replace(/^S[pkPK]?:([^\| \?\(+-]+\*?) ?([-+]\d+)? ?([^\|]*)(\|.*)?/g, '$1~$2~$3~$4')
parse = str.replace(/^S[pkPK]?:([^\| \?\(+-]+\*?) ?([-+]\d+)? ?([^\|]*)(\|.*)?/gi, '$1~$2~$3~$4')
}

if (parse != str) {
Expand All @@ -333,9 +333,9 @@ export function parselink(str, htmldesc, clrdmods = false) {
let floatingAttribute = null
let floatingLabel = null
let floatingType = null
let matches = comment.match(/(\((Based|Base|B): ?[^\)]+\))/g)
let matches = comment.match(/(\((Based|Base|B): ?[^\)]+\))/gi)
if (!!matches) {
floatingLabel = comment.replace(/.*\((Based|Base|B): ?([^\)]+)\).*/g, '$2')
floatingLabel = comment.replace(/.*\((Based|Base|B): ?([^\)]+)\).*/gi, '$2')
//console.log(`floating ${floatingLabel}`)

comment = comment
Expand Down Expand Up @@ -420,10 +420,10 @@ export function parselink(str, htmldesc, clrdmods = false) {
}

// Simple, no-spaces, no quotes melee/ranged name (with optional *s)
parse = str.replace(/^[MRAD]:([^ "+-]+\*?) ?([-+]\d+)? ?(.*)/g, '$1~$2~$3')
parse = str.replace(/^[MRAD]:([^ "+-]+\*?) ?([-+]\d+)? ?(.*)/gi, '$1~$2~$3')
if (parse == str) {
// Use quotes to capture skill/spell name (with optional *s)
parse = str.replace(/^[MRAD]:"([^"]+)" ?([-+]\d+)? ?(.*)/g, '$1~$2~$3')
parse = str.replace(/^[MRAD]:"([^"]+)" ?([-+]\d+)? ?(.*)/gi, '$1~$2~$3')
}
if (parse != str) {
let a = parse.split('~')
Expand Down Expand Up @@ -451,8 +451,8 @@ export function parselink(str, htmldesc, clrdmods = false) {
comment = ''
}
if (!!costs) spantext += ' ' + costs
let isMelee = !!str.match(/^[AMD]/)
let isRanged = !!str.match(/^[ARD]/)
let isMelee = !!str.match(/^[AMD]/i)
let isRanged = !!str.match(/^[ARD]/i)
let action = {
orig: str,
type: str.startsWith('D') ? 'attackdamage' : 'attack',
Expand Down
2 changes: 1 addition & 1 deletion module/actor-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export class GurpsActorSheet extends ActorSheet {
const w = 50;
const h = 50;
const preview = DragDrop.createDragImage(img, w, h);
ev.dataTransfer.setDragImage(preview, w/2, h/2);
ev.dataTransfer.setDragImage(preview, 0, 0);
}
let newd = {
actorid: this.actor.id,
Expand Down
49 changes: 21 additions & 28 deletions module/actor.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ResourceTrackerManager } from '../module/actor/resource-tracker-manager
import ApplyDamageDialog from './damage/applydamage.js'
import * as HitLocations from '../module/hitlocation/hitlocation.js'
import * as settings from '../lib/miscellaneous-settings.js'
import { SemanticVersion } from '../lib/semver.js'

export class GurpsActor extends Actor {
/** @override */
Expand Down Expand Up @@ -49,27 +50,22 @@ export class GurpsActor extends Actor {

// Initialize the attribute current values/levels. The code is expecting 'value' or 'level' for many things, and instead of changing all of the GUIs and OTF logic
// we are just going to switch the rug out from underneath. "Import" data will be in the 'import' key and then we will calculate value/level when the actor is loaded.
// If import keys don't exist, set them to the current value and commit to upgrade older actors
_initCurrents() {
let v = this.data.data.migrationversion
if (!v) return // currently, only need to check for the initial version, but in the future, we might need to check against SemanticVersion.fromString(v)
// Attributes need to have 'value' set because Foundry expects objs with value and max to be attributes (so we can't use currentvalue)
let commit = {}
for (const attr in this.data.data.attributes) {
if (this.data.data.attributes[attr].import == null)
commit = { ...commit, ...{ ['data.attributes.' + attr + '.import']: this.data.data.attributes[attr].value } }
// backward compat
else this.data.data.attributes[attr].value = this.data.data.attributes[attr].import
this.data.data.attributes[attr].value = this.data.data.attributes[attr].import
}
recurselist(this.data.data.skills, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.skills.' + k + '.import']: e.level } }
else e.level = parseInt(e.import)
e.level = parseInt(e.import)
})
recurselist(this.data.data.spells, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.spells.' + k + '.import']: e.level } }
else e.level = parseInt(e.import)
e.level = parseInt(e.import)
})
recurselist(this.data.data.melee, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.melee.' + k + '.import']: e.level } }
else e.level = parseInt(e.import)
e.level = parseInt(e.import)
if (!isNaN(parseInt(e.parry))) {
// allows for '14f' and 'no'
let base = 3 + Math.floor(e.level / 2)
Expand All @@ -87,11 +83,8 @@ export class GurpsActor extends Actor {
}
})
recurselist(this.data.data.ranged, (e, k, d) => {
if (e.import == null) commit = { ...commit, ...{ ['data.ranged.' + k + '.import']: e.level } }
else e.level = parseInt(e.import)
e.level = parseInt(e.import)
})
// We must delay the upgrade of older actor's 'import' keys, since upon startup, the actor may not know which collection it belongs to
if (Object.keys(commit).length > 0) setTimeout(() => this.update(commit), 1000)
}

_applyItemBonuses() {
Expand Down Expand Up @@ -372,7 +365,7 @@ export class GurpsActor extends Actor {
console.log("Importing '" + nm + "'")
// this is how you have to update the domain object so that it is synchronized.

let commit = {}
let commit = { "data.migrationversion" : game.system.data.version }

if (!game.settings.get(settings.SYSTEM_NAME, settings.SETTING_IGNORE_IMPORT_NAME)) {
commit = { ...commit, ...{ name: nm } }
Expand Down Expand Up @@ -2033,8 +2026,8 @@ export class Named {
}

export class NamedCost extends Named {
constructor() {
super()
constructor(n1) {
super(n1)
this.points = 0
}
}
Expand All @@ -2047,16 +2040,16 @@ export class Leveled extends NamedCost {
}

export class Skill extends Leveled {
constructor() {
super()
constructor(n1, lvl) {
super(n1, lvl)
this.type = '' // "DX/E";
this.relativelevel = '' // "DX+1";
}
}

export class Spell extends Leveled {
constructor() {
super()
constructor(n1, lvl) {
super(n1, lvl)
this.class = ''
this.college = ''
this.cost = ''
Expand All @@ -2069,8 +2062,8 @@ export class Spell extends Leveled {
}

export class Advantage extends NamedCost {
constructor() {
super()
constructor(n1) {
super(n1)
this.userdesc = ''
this.note = ''
}
Expand All @@ -2088,8 +2081,8 @@ export class Attack extends Named {
}

export class Melee extends Attack {
constructor() {
super()
constructor(n1, lvl, dmg) {
super(n1, lvl, dmg)

this.weight = ''
this.techlevel = ''
Expand All @@ -2101,8 +2094,8 @@ export class Melee extends Attack {
}

export class Ranged extends Attack {
constructor() {
super()
constructor(n1, lvl, dmg) {
super(n1, lvl, dmg)

this.bulk = ''
this.legalityclass = ''
Expand Down
11 changes: 11 additions & 0 deletions module/gurps.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { doRoll } from '../module/dierolls/dieroll.js'
import { ResourceTrackerManager } from './actor/resource-tracker-manager.js'
import { DamageTables, initializeDamageTables } from '../module/damage/damage-tables.js'
import RegisterChatProcessors from '../module/chat/chat-processors.js'
import { Migration } from '../lib/migration.js'

export const GURPS = {}
window.GURPS = GURPS // Make GURPS global!
Expand Down Expand Up @@ -871,6 +872,7 @@ function findSkillSpell(actor, sname, isSkillOnly = false, isSpellOnly = false)
if (!actor) return t
if (!!actor.data?.data?.additionalresources) actor = actor.data
sname = makeRegexPatternFrom(sname, false)
sname = new RegExp(sname, "i");
let best = 0
if (!isSpellOnly)
recurselist(actor.data.skills, s => {
Expand All @@ -896,6 +898,7 @@ function findAdDisad(actor, sname) {
if (!actor) return t
if (!!actor.data?.data?.additionalresources) actor = actor.data
sname = makeRegexPatternFrom(sname, false)
sname = new RegExp(sname, "i");
recurselist(actor.data.ads, s => {
if (s.name.match(sname)) {
t = s
Expand All @@ -910,6 +913,7 @@ function findAttack(actor, sname, isMelee = true, isRanged = true) {
if (!actor) return t
if (!!actor.data?.data?.additionalresources) actor = actor.data
sname = makeRegexPatternFrom(sname, false)
sname = new RegExp(sname, "i");
if (isMelee)
t = actor.data.melee?.findInProperties(a => (a.name + (!!a.mode ? ' (' + a.mode + ')' : '')).match(sname))
if (isRanged && !t)
Expand Down Expand Up @@ -1547,6 +1551,13 @@ Hooks.once('ready', async function () {
template: 'systems/gurps/templates/threed6.html',
classes: [],
}).render(true)

// Test for migration
const mv = game.settings.get(settings.SYSTEM_NAME, settings.SETTING_MIGRATION_VERSION) || '0.0.1'
console.log("Migration version: " + mv)
const migrationVersion = SemanticVersion.fromString(mv)
const v096 = SemanticVersion.fromString('0.9.6')
if (migrationVersion.isLowerThan(v096)) Migration.migrateTo096()

// Show changelog
const v = game.settings.get(settings.SYSTEM_NAME, settings.SETTING_CHANGELOG_VERSION) || '0.0.1'
Expand Down
4 changes: 2 additions & 2 deletions system.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "gurps",
"title": "GURPS 4th Edition Game Aid (Unofficial)",
"description": "A game aid to help play GURPS 4e for Foundry VTT",
"version": "0.9.4",
"version": "0.9.6",
"minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9",
"templateVersion": 2,
Expand Down Expand Up @@ -44,7 +44,7 @@
"secondaryTokenAttribute": "FP",
"url": "https://github.com/crnormand/gurps",
"manifest": "https://raw.githubusercontent.com/crnormand/gurps/release/system.json",
"download": "https://github.com/crnormand/gurps/archive/0.9.4.zip",
"download": "https://github.com/crnormand/gurps/archive/0.9.6.zip",
"socket": true,
"license": "LICENSE.txt"
}

0 comments on commit 1a02829

Please sign in to comment.