Skip to content
This repository has been archived by the owner on Jan 18, 2022. It is now read-only.

Commit

Permalink
Merge branch '0.84.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
Rughalt committed Sep 16, 2020
2 parents fe40f36 + 579f8c7 commit a1b6d7c
Show file tree
Hide file tree
Showing 10 changed files with 536 additions and 50 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# Changelog
## 0.84.2
### SRD
- Added various missing Enhancements from SRD

### Features
- Added ability to use Magic Item Abilities directly from Char Sheet
- Added ability to create Enhancements from Spells and Buffs

## 0.84.1
### SRD
- Additional Spells have full implementation, thanks to BixSexy#9434
Expand Down
2 changes: 2 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,8 @@
"D35E.ListDragAndDropClassFeature": "Class Details - Special Features",
"D35E.ListDragAndDropRacialTrait": "Race Details - Special Features",
"D35E.ListDragAndDropNone": "",
"D35E.CreateEnhForSpell": "Create Enhancement from Spell",
"D35E.CreateEnhForSpellD": "You can create Enhancement from Spell either as Charges (eg. for Wands) or per Day use.",


"SETTINGS.D35EShowPartyHudN": "Party HUD type",
Expand Down
59 changes: 59 additions & 0 deletions module/actor/sheets/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ export class ActorSheetPF extends ActorSheet {
// Quick Item Action control
html.find(".item-actions a").mouseup(ev => this._quickItemActionControl(ev));


// Roll Skill Checks
html.find(".skill > .skill-name > .rollable").click(this._onRollSkillCheck.bind(this));
html.find(".sub-skill > .skill-name > .rollable").click(this._onRollSubSkillCheck.bind(this));
Expand Down Expand Up @@ -538,6 +539,7 @@ export class ActorSheetPF extends ActorSheet {

// Item Rolling
html.find('.item .item-image').click(event => this._onItemRoll(event));
html.find('.item .item-enh-image').click(event => this._onEnhRoll(event));

// Quick add item quantity
html.find("a.item-control.item-quantity-add").click(ev => { this._quickChangeItemQuantity(ev, 1); });
Expand Down Expand Up @@ -854,15 +856,72 @@ export class ActorSheetPF extends ActorSheet {
summary.slideUp(200, () => summary.remove());
} else {
let div = $(`<div class="item-summary">${chatData.description.value}</div>`);
let enhList = $(`<ul class="item-enh-list"></ul>`);
let props = $(`<div class="item-properties"></div>`);
chatData.properties.forEach(p => props.append(`<span class="tag">${p}</span>`));
(getProperty(item.data, `data.enhancements.items`) || []).forEach(enh => {
if (enh.hasAction) {
let enhString = `<li class="item enh-item item-box flexrow" data-item-id="${item._id}" data-enh-id="${enh._id}">
<div class="item-name flexrow">
<div class="item-image item-enh-image" style="background-image: url('${enh.img}')"></div>
<h4 class="rollable{{#if item.incorrect}} strikethrough-text{{/if}}">
${enh.name} <em style="opacity: 0.7">${enh.data.uses.per}</em>
</h4>
</div>
<div class="item-detail item-actions">
<div class="item-attack">
<a class="item-control item-enh-attack"><img class="icon"
src="systems/D35E/icons/actions/gladius.svg"></a>
</div>
</div>`+ (enh.isCharged ? `
<div class="item-detail item-uses flexrow {{#if item.isCharged}}tooltip{{/if}}">
<input type="text" class="uses" disabled value="${enh.data.uses.value}" data-dtype="Number"/>
<span class="sep"> of </span>
<input type="text" class="maxuses" disabled value="${enh.data.uses.max}" data-dtype="Number"/>
</div>
<div class="item-detail item-per-use flexrow {{#if item.isCharged}}tooltip{{/if}}" style="flex: 0 48px">
<input type="text" disabled value="${enh.data.uses.chargesPerUse}" data-dtype="Number"/>
</div>
</li>` : `</li>`)
enhList.append(enhString)
}
})
div.append(enhList);
div.append(props);

div.find(".item-enh-attack").mouseup(ev => this._quickItemEnhActionControl(ev));
div.find(".item-enh-image").mouseup(ev => this._onEnhRoll(ev));
li.append(div.hide());
div.slideDown(200);

}
li.toggleClass("expanded");
}

async _quickItemEnhActionControl(event) {
event.preventDefault();
const a = event.currentTarget;
const itemId = $(event.currentTarget).parents(".enh-item").attr("data-item-id");
const enhId = $(event.currentTarget).parents(".enh-item").attr("data-enh-id");
const item = this.actor.getOwnedItem(itemId);

// Quick Attack
if (a.classList.contains("item-enh-attack")) {
item.useEnhancementItem(item.getEnhancementItem(enhId));
}
}


_onEnhRoll(event) {
event.preventDefault();
const itemId = $(event.currentTarget).parents(".enh-item").attr("data-item-id");
const enhId = $(event.currentTarget).parents(".enh-item").attr("data-enh-id");
const item = this.actor.getOwnedItem(itemId);
let enh = item.getEnhancementItem(enhId);
return enh.roll({}, this.actor);
}

/* -------------------------------------------- */

_onArbitrarySkillCreate(event) {
Expand Down
197 changes: 196 additions & 1 deletion module/item/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export class ItemPF extends Item {
return this.constructor.getTypeColor(this.type, 1);
}


/**
* Generic charge addition (or subtraction) function that either adds charges
* or quantity, based on item data.
Expand Down Expand Up @@ -1208,7 +1209,7 @@ export class ItemPF extends Item {
};

// Post message
if (this.data.type === "spell") await this.roll({rollMode: rollMode});
if (this.data.type === "spell" || this.data.data.isFromSpell) await this.roll({rollMode: rollMode});
if (this.hasAttack || this.hasDamage || this.hasEffect || getProperty(this.data, "data.actionType") === "special") {
// Get extra text and properties
let props = [],
Expand Down Expand Up @@ -2296,6 +2297,159 @@ export class ItemPF extends Item {
return data;
}

static async toEnhancement(origData, type) {
let data = duplicate(game.system.template.Item.enhancement);
for (let t of data.templates) {
mergeObject(data, duplicate(game.system.template.Item.templates[t]));
}
delete data.templates;
data = {
type: "enhancement",
name: origData.name,
data: data,
};

const slcl = this.getMinimumCasterLevelBySpellData(origData.data);

data.data.enhancementType = "misc";

// Set name
data.name = `${origData.name}`;
data.img = origData.img;
data.id = origData._id
if (type === 'command' || type === 'use') {
data.data.uses.per = "day";
data.data.uses.maxFormula = "1";
data.data.uses.value = 1;
data.data.uses.max = 1;
} else {
data.data.uses.per = "charges";
data.data.uses.maxFormula = "50";
data.data.uses.value = 50;
data.data.uses.max = 50;
}

data.data.uses.chargesPerUse = 1


data.data.enh = slcl[1]
data.data.enhIncreaseFormula = ""
data.data.priceFormula = ""
data.data.price = 0

data.data.isFromSpell = true;

// Set activation method
data.data.activation.type = "standard";

data.data.measureTemplate = getProperty(origData, "data.measureTemplate");


// Set damage formula
data.data.actionType = origData.data.actionType;
for (let d of getProperty(origData, "data.damage.parts")) {
d[0] = d[0].replace(/@sl/g, slcl[0]);
d[0] = d[0].replace(/@cl/g, '@enhancement');
data.data.damage.parts.push(d);
}

// Set saves
data.data.save.description = origData.data.save.description;
data.data.save.dc = 10 + slcl[0] + Math.floor(slcl[0] / 2);

// Copy variables
data.data.attackNotes = origData.data.attackNotes;
data.data.effectNotes = origData.data.effectNotes;
data.data.attackBonus = origData.data.attackBonus;
data.data.critConfirmBonus = origData.data.critConfirmBonus;
data.data.specialActions = origData.data.specialActions;

// Determine aura power
let auraPower = "faint";
for (let a of CONFIG.D35E.magicAuraByLevel.item) {
if (a.level <= slcl[1]) auraPower = a.power;
}
let clLabel;
switch (slcl[1]) {
case 1:
clLabel = "1st";
break;
case 2:
clLabel = "2nd";
break;
case 3:
clLabel = "3rd";
break;
default:
clLabel = `${slcl[1]}th`;
break;
}
// Determine spell level label
let slLabel;
switch (slcl[0]) {
case 1:
slLabel = "1st";
break;
case 2:
slLabel = "2nd";
break;
case 3:
slLabel = "3rd";
break;
default:
slLabel = `${slcl[1]}th`;
break;
}

// Set description
data.data.description.value = getProperty(origData, "data.description.value");

return data;
}

static async toEnhancementBuff(origData) {
let data = duplicate(game.system.template.Item.enhancement);
for (let t of data.templates) {
mergeObject(data, duplicate(game.system.template.Item.templates[t]));
}
delete data.templates;
data = {
type: "enhancement",
name: origData.name,
data: data,
};


data.data.enhancementType = "misc";

// Set name
data.name = `${origData.name}`;
data.img = origData.img;
data.id = origData._id

data.data.isFromBuff = true;

data.data.enh = 1
data.data.enhIncreaseFormula = ""
data.data.priceFormula = ""
data.data.price = 0


data.data.changes = origData.data.changes;
for (const c of data.data.changes) {
c[0] = c[0].replace(new RegExp('@item.level', 'g'), '@enhancement');
}
data.data.contextNotes = origData.data.contextNotes;
for (const c of data.data.contextNotes) {
c[0] = c[0].replace(new RegExp('@item.level', 'g'), '@enhancement');
}


data.data.description.value = getProperty(origData, "data.description.value");

return data;
}

static async toConsumable(origData, type) {
let data = duplicate(game.system.template.Item.consumable);
for (let t of data.templates) {
Expand Down Expand Up @@ -2394,6 +2548,7 @@ export class ItemPF extends Item {
data.data.effectNotes = origData.data.effectNotes;
data.data.attackBonus = origData.data.attackBonus;
data.data.critConfirmBonus = origData.data.critConfirmBonus;
data.data.specialActions = origData.data.specialActions;

// Determine aura power
let auraPower = "faint";
Expand Down Expand Up @@ -2455,4 +2610,44 @@ export class ItemPF extends Item {
return data;
}


getEnhancementItem(id) {
let itemData = (getProperty(this.data, `data.enhancements.items`) || []).find(i => i._id === id)
if (itemData != null)
return new ItemPF(itemData, {owner: this.owner})
else
return itemData;
}

async useEnhancementItem(item) {
if (this.data.data.enhancements.uses.commonPool) {
if (this.data.data.enhancements.uses.value < item.chargeCost) {
return ui.notifications.warn(game.i18n.localize("D35E.ErrorNoCharges").format(this.name));
}
}
let roll = await item.use({ev: event, skipDialog: event.shiftKey},this.actor,this.data.data.enhancements.uses.commonPool === true);
if (roll) {
if (this.data.data.enhancements.uses.commonPool) {
let updateData = {}
updateData[`data.enhancements.uses.value`] = this.data.data.enhancements.uses.value - item.chargeCost;
await this.update(updateData);
} else {
await this.addEnhancementCharges(item, -1*item.chargeCost)
}
}
}


async addEnhancementCharges(item, charges) {
let updateData = {}
let _enhancements = duplicate(getProperty(this.data, `data.enhancements.items`) || []);
_enhancements.filter(function( obj ) {
return obj._id === item._id
}).forEach(i => {
i.data.uses.value = i.data.uses.value + charges;
});
updateData[`data.enhancements.items`] = _enhancements;
await this.update(updateData);
}

}
Loading

0 comments on commit a1b6d7c

Please sign in to comment.