Skip to content

Commit

Permalink
Merge pull request #170 from sasquach45932/master
Browse files Browse the repository at this point in the history
Weapon - Ammo assigment
  • Loading branch information
ClipplerBlood authored Apr 15, 2024
2 parents 523825d + 6d24034 commit 04b42a3
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 20 deletions.
4 changes: 4 additions & 0 deletions src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@
"DL.WealthLifestyle": "Lifestyle: ",
"DL.WealthTitle": "Wealth",
"DL.WeaponAdd": "Add weapon",
"DL.WeaponAmmoRequired": "Ammunition required",
"DL.WeaponAttack20": "Extra Damage 20+",
"DL.WeaponAttack20Text": "Attack Roll 20+",
"DL.WeaponAttackModifier": "Attack Modifier",
Expand All @@ -744,6 +745,9 @@
"DL.WeaponModifiers": "Modifiers",
"DL.WeaponName": "Weapon name",
"DL.WeaponProperties": "Properties",
"DL.WeaponResourceComsumption": "Resource consumption",
"DL.WeaponRunOutOfAmmo": "{weaponName} has run out of its ammunition.",
"DL.WeaponNoAmmo": "{weaponName} has no assigned ammunition.",
"DL.WeaponTitle": "Weapons",
"DL.WeaponWear": "Equip weapon",
"DL.With": "with"
Expand Down
34 changes: 30 additions & 4 deletions src/module/actor/actor.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,27 @@ export class DemonlordActor extends Actor {
*/
async rollWeaponAttack(itemID, _options = {event: null}) {
const item = this.getEmbeddedDocument('Item', itemID)
let ammoItem

// Check if there is an ammo for weapon
if (item.system.consume.ammorequired) {
ammoItem = await this.ammo.find(x => x.id === item.system.consume.ammoitemid)
if (ammoItem) {
if (ammoItem.system.quantity === 0) {
return ui.notifications.warn(
game.i18n.format('DL.WeaponRunOutOfAmmo', {
weaponName: item.name,
}),
)
}
} else {
return ui.notifications.warn(
game.i18n.format('DL.WeaponNoAmmo', {
weaponName: item.name,
}),
)
}
}

// If no attribute to roll, roll without modifiers and boons
const attribute = item.system.action?.attack
Expand All @@ -427,11 +448,16 @@ export class DemonlordActor extends Actor {

// Check if actor is blocked by an affliction
if (!DLAfflictions.isActorBlocked(this, 'action', attribute))
launchRollDialog(game.i18n.localize('DL.DialogAttackRoll') + game.i18n.localize(item.name), async html =>
await this.rollAttack(item, html.find('[id="boonsbanes"]').val(), html.find('[id="modifier"]').val()),
)
launchRollDialog(game.i18n.localize('DL.DialogAttackRoll') + game.i18n.localize(item.name), async html => {
await this.rollAttack(item, html.find('[id="boonsbanes"]').val(), html.find('[id="modifier"]').val())
// Decrease ammo quantity
if (item.system.consume.ammorequired) {
await ammoItem.update({
'system.quantity': ammoItem.system.quantity - item.system.consume.amount,
})
}
})
}

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

async rollAttribute(attribute, inputBoons, inputModifier) {
Expand Down
14 changes: 12 additions & 2 deletions src/module/data/item/WeaponDataModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ export default class WeaponDataModel extends foundry.abstract.DataModel {
wear: makeBoolField(true),
quantity: makeIntField(1),
availability: makeStringField(),
value: makeStringField()
value: makeStringField(),
consume: new foundry.data.fields.SchemaField({
ammorequired: makeBoolField(false),
amount: makeIntField(1),
ammoitemid: makeStringField()
}),
}
}
}
Expand All @@ -37,6 +42,11 @@ export function makeWeaponSchema() {
wear: makeBoolField(true),
quantity: makeIntField(1),
availability: makeStringField(),
value: makeStringField()
value: makeStringField(),
consume: new foundry.data.fields.SchemaField({
ammorequired: makeBoolField(false),
amount: makeIntField(1),
ammoitemid: makeStringField()
}),
})
}
10 changes: 9 additions & 1 deletion src/module/item/sheets/base-item-sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export default class DLBaseItemSheet extends ItemSheet {
})
tippy('.dl-new-project-2.dropdown', {
content(reference) {
html = buildDropdownList(reference.attributes.name.value, reference.attributes.value.value)
html = buildDropdownList(reference.attributes.name.value, reference.attributes.value.value, data)
return html
},
allowHTML: true,
Expand All @@ -190,6 +190,14 @@ export default class DLBaseItemSheet extends ItemSheet {
inputs.focus(ev => ev.currentTarget.select())
}

// Weapon ammo required checkbox
html.find('.dl-ammorequired').click(async _ => {
await this.document.update({
'system.consume.ammorequired': !this.document.system.consume.ammorequired,
'system.consume.ammoitemid' : ''
})
})

// Item autoDestroy checkbox
html.find('.dl-autodestroy').click(async _ => {
await this.document.update({'system.autoDestroy': !this.document.system.autoDestroy})
Expand Down
79 changes: 66 additions & 13 deletions src/module/utils/handlebars-helpers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global fromUuidSync */
import {capitalize, enrichHTMLUnrolled, i18n} from "./utils";
import {handlebarsBuildEditor} from "./editor";

Expand Down Expand Up @@ -50,7 +51,9 @@ export function registerHandlebarsHelpers() {
)
Handlebars.registerHelper('dlAvailabilityDropdown', (groupName, checkedKey) => _buildAvailabilityDropdownItem(groupName, checkedKey))
Handlebars.registerHelper('dlConsumableDropdown', (groupName, checkedKey) => _buildConsumableDropdownItem(groupName, checkedKey))
Handlebars.registerHelper('dlCheckCharacteristicsIsNull', (actorData) => _CheckCharacteristicsIsNull(actorData));
Handlebars.registerHelper('dlAmmoDropdown', (groupName, checkedKey, weapon) => _buildAmmoDropdownItem(groupName, checkedKey, weapon))
Handlebars.registerHelper('dlCheckItemOnActor', (data) => _CheckItemOnActor(data))
Handlebars.registerHelper('dlCheckCharacteristicsIsNull', (actorData) => _CheckCharacteristicsIsNull(actorData))
}

// ----------------------------------------------------
Expand All @@ -69,10 +72,9 @@ function _getAttributes(groupName) {
attributes = ['', 'C', 'U', 'R', 'E']
} else if (groupName === 'system.requirement.attribute') {
attributes = ['', 'strength', 'agility', 'intellect', 'will', 'perception']
}
else if (groupName === 'system.consumabletype') {
} else if (groupName === 'system.consumabletype') {
attributes = ['', 'D', 'F', 'P', 'V', 'T']
}
}
return attributes
}

Expand All @@ -98,11 +100,19 @@ function _buildRadioBoxes(groupName, checkedKey) {
// ----------------------------------------------------

function _CheckCharacteristicsIsNull(actorData) {
if (actorData === null) {
return true
} else {
return false
}
if (actorData === null) {
return true
} else {
return false
}
}

function _CheckItemOnActor(data) {
if (data.indexOf('Actor.') === -1) {
return false
} else {
return true
}
}

function _buildDropdownItem(groupName, checkedKey) {
Expand Down Expand Up @@ -174,14 +184,15 @@ function _buildDropdownItemWithValue(groupName, checkedKey, valueName, valueKey)
}


export function buildDropdownList(groupName, checkedKey) {
export function buildDropdownList(groupName, checkedKey, data) {
let labelPrefix = 'DL.Attribute'
let iconPrefix = 'dl-icon-'
let useIcon = true

if (groupName === 'path-type') return _buildPathTypeDropdownList(checkedKey)
if (groupName === 'level.attributeSelect') return _buildPathAttributeSelectDropdownList(checkedKey)
if (groupName.startsWith('level.attributeSelectTwoSet')) return _buildPathAttributeTwoSetDropdownList(groupName, checkedKey)
if (groupName === 'system.consume.ammoitemid') return _buildAmmoDropdownList (groupName, checkedKey, data)
if (groupName === 'system.hands') {labelPrefix = 'DL.WeaponHands'; useIcon = false}
if (groupName === 'system.consumabletype') {labelPrefix = 'DL.ConsumableType'; useIcon = false}
if (groupName === 'system.availability') {labelPrefix = 'DL.Availability', iconPrefix = 'dl-icon-availability-'}
Expand Down Expand Up @@ -336,6 +347,28 @@ function _buildPathAttributeTwoSetViewSelector(attributeName, isSelected, select
return new Handlebars.SafeString(html)
}

function _buildAmmoDropdownList(groupName, checkedKey, data) {
let attributes = [{ id: '', name: i18n('DL.None') }]
let html = `<div class="dl-new-project-2-dropdown">`
if (!data.document) return ''
let baseItemUuid = data.document.uuid
let actor = fromUuidSync(baseItemUuid.substr(0, baseItemUuid.search('.Item.')))
actor.items.forEach(item => {
if (item.type === 'ammo') attributes.push({ id: item._id, name: item.name })
})
for (let attribute of attributes) {
const value = attribute.id
const checked = value === checkedKey ? 'checked' : ''
const label = value ? attribute.name : i18n('DL.None')
html += `<div class="${checked}">
<input type="radio" name="${groupName}" value="${value}" ${checked}/>
<span>${label}</span>
</div>`
}
html += `</div>`
return new Handlebars.SafeString(html)
}

// ----------------------------------------------------

function _buildAvailabilityDropdownItem(groupName, checkedKey) {
Expand All @@ -358,11 +391,31 @@ function _buildConsumableDropdownItem(groupName, checkedKey) {
const attributes = ['', 'D', 'F', 'P', 'V', 'T']
for (let attribute of attributes) {
if (checkedKey != attribute) continue
const label = attribute === '' ? i18n("DL.ConsumableNone") : i18n(`DL.ConsumableType${attribute}`)
let html =
`<div class="dl-new-project-2 dropdown" name="${groupName}" value="${checkedKey}">
const label = attribute === '' ? i18n('DL.ConsumableNone') : i18n(`DL.ConsumableType${attribute}`)
let html = `<div class="dl-new-project-2 dropdown" name="${groupName}" value="${checkedKey}">
<span style="width: 120px; text-align: center; text-overflow: ellipsis">${label} </span>
</div>`
return new Handlebars.SafeString(html)
}
}

function _buildAmmoDropdownItem(groupName, checkedKey, weapon) {
let actorUuid = weapon.parent.uuid
let actor = fromUuidSync(actorUuid.substr(0, actorUuid.search('.Item.')))
let attributes = [{ id: '', name: '' }]

actor.items.forEach(item => {
if (item.type === 'ammo') attributes.push({ id: item._id, name: item.name })
})

if (!attributes.find(x => x.id === checkedKey)) checkedKey = ''

for (let attribute of attributes) {
if (checkedKey != attribute.id) continue
const label = attribute.id === '' ? i18n('DL.None') : attribute.name
let html = `<div class="dl-new-project-2 dropdown" name="${groupName}" value="${checkedKey}">
<span style="width: 200px; text-align: center; overflow: hidden; text-overflow: ellipsis;">${label} </span>
</div>`
return new Handlebars.SafeString(html)
}
}
25 changes: 25 additions & 0 deletions src/templates/item/item-weapon-sheet.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@
</div>
<hr>

<div class="dl-item-section-section margin">
<div>
<b>{{localize "DL.WeaponAmmoRequired"}}</b>
<div class="dl-custom-checkbox dl-ammorequired {{checked system.consume.ammorequired}}"> </div>
</div>
{{#if (dlCheckItemOnActor system.parent.uuid)}}
{{#if system.consume.ammorequired}}
<div>
<b>{{localize "DL.WeaponResourceComsumption"}}</b>
<div>
<div class="dl-new-project-2">
<i class="dl-icon-amount"></i>
<span class="sep"></span>
<span style="width: 64px; text-align: center; text-overflow: ellipsis">{{localize "DL.AmmoAmount"}}</span>
<span class="sep"></span>
<input type="number" name="system.consume.amount" value="{{system.consume.amount}}" placeholder="1"/>
</div>
{{dlAmmoDropdown "system.consume.ammoitemid" system.consume.ammoitemid system}}
</div>
</div>
{{/if}}
{{/if}}
</div>
<hr>

{{#if system.description}}
<div class="dl-item-section-description">
<div><b>{{localize "DL.TabsDescription"}}</b></div>
Expand Down

0 comments on commit 04b42a3

Please sign in to comment.