mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-06 04:44:16 +02:00
Compare commits
3 commits
6a2d09caac
...
b23095cb2f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b23095cb2f | ||
|
|
2f589c1b8e | ||
|
|
10a608a1a5 |
8 changed files with 128 additions and 112 deletions
|
|
@ -718,7 +718,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
? {
|
||||
'system.linkedClass.uuid': {
|
||||
key: 'system.linkedClass.uuid',
|
||||
value: this.document.system.class.value._stats.compendiumSource
|
||||
value: this.document.system.class.value?._stats.compendiumSource
|
||||
}
|
||||
}
|
||||
: undefined,
|
||||
|
|
|
|||
|
|
@ -56,38 +56,30 @@ export default class DHSubclass extends BaseDataItem {
|
|||
if (allowed === false) return;
|
||||
|
||||
if (this.actor?.type === 'character') {
|
||||
const dataUuid = data.uuid ?? data._stats.compendiumSource ?? `Item.${data._id}`;
|
||||
if (this.actor.system.class.subclass) {
|
||||
if (this.actor.system.multiclass.subclass) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent'));
|
||||
return false;
|
||||
} else {
|
||||
const multiclass = this.actor.items.find(x => x.type === 'class' && x.system.isMulticlass);
|
||||
if (!multiclass) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingMulticlass'));
|
||||
return false;
|
||||
}
|
||||
const { value: actorClass, subclass: existingSubclass } = this.actor.system.class;
|
||||
const { value: multiclass, subclass: existingMultisubclass } = this.actor.system.multiclass;
|
||||
if (!actorClass && !multiclass) {
|
||||
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingClass', { localize: true });
|
||||
return false;
|
||||
}
|
||||
if (existingSubclass && existingMultisubclass) {
|
||||
ui.notifications.warn('DAGGERHEART.UI.Notifications.subclassesAlreadyPresent', { localize: true });
|
||||
return false;
|
||||
}
|
||||
if (existingSubclass && !multiclass) {
|
||||
ui.notifications.warn('DAGGERHEART.UI.Notifications.missingMulticlass', { localize: true });
|
||||
return false;
|
||||
}
|
||||
|
||||
if (multiclass.system.subclasses.every(x => x.uuid !== dataUuid)) {
|
||||
ui.notifications.error(
|
||||
game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInMulticlass')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
await this.updateSource({ isMulticlass: true });
|
||||
}
|
||||
} else {
|
||||
const actorClass = this.actor.items.find(x => x.type === 'class' && !x.system.isMulticlass);
|
||||
if (!actorClass) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.missingClass'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((await actorClass.system.fetchSubclasses()).every(x => x.uuid !== dataUuid)) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.subclassNotInClass'));
|
||||
return false;
|
||||
}
|
||||
const match = [multiclass, actorClass].find(
|
||||
c => c && (c._stats.compendiumSource ?? c.uuid) === this.linkedClass
|
||||
);
|
||||
if (!match) {
|
||||
const key = multiclass ? 'subclassNotInMulticlass' : 'subclassNotInClass';
|
||||
ui.notifications.warn(`DAGGERHEART.UI.Notifications.${key}`, { localize: true });
|
||||
return false;
|
||||
} else if (match.system.isMulticlass) {
|
||||
await this.updateSource({ isMulticlass: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,10 +153,13 @@ export default class DhpActor extends Actor {
|
|||
async updateLevel(newLevel) {
|
||||
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
|
||||
|
||||
const tiers = Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers);
|
||||
const maxLevel = tiers.reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
|
||||
const multiclassMinLevel = Math.min(
|
||||
maxLevel,
|
||||
...tiers.filter(t => t.options.multiclass).map(t => t.levels.start)
|
||||
);
|
||||
if (newLevel > this.system.levelData.level.current) {
|
||||
const maxLevel = Object.values(
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers
|
||||
).reduce((acc, tier) => Math.max(acc, tier.levels.end), 0);
|
||||
if (newLevel > maxLevel) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.tooHighLevel'));
|
||||
}
|
||||
|
|
@ -231,18 +234,19 @@ export default class DhpActor extends Actor {
|
|||
this.system.multiclass.subclass.update({ 'system.featureState': subclassFeatureState.multiclass });
|
||||
}
|
||||
|
||||
if (multiclass) {
|
||||
const multiclassItem = this.items.find(x => x.uuid === multiclass.itemUuid);
|
||||
const multiclassFeatures = this.items.filter(
|
||||
x => x.system.originItemType === 'class' && x.system.multiclassOrigin
|
||||
);
|
||||
const subclassFeatures = this.items.filter(
|
||||
x => x.system.originItemType === 'subclass' && x.system.multiclassOrigin
|
||||
// Remove multiclass if we're removing a multiclass feature or if we're below the multiclass minimum level
|
||||
// Multclasses cannot be manually removed on the sheet, so this allows recovering in the case of errors
|
||||
if (multiclass || newLevel < multiclassMinLevel) {
|
||||
const multiclassItems = this.items.filter(
|
||||
x =>
|
||||
x.uuid === multiclass?.itemUuid ||
|
||||
x.system.isMulticlass ||
|
||||
(['class', 'subclass'].includes(x.system.originItemType) && x.system.multiclassOrigin)
|
||||
);
|
||||
|
||||
this.deleteEmbeddedDocuments(
|
||||
'Item',
|
||||
[multiclassItem, ...multiclassFeatures, ...subclassFeatures].map(x => x.id)
|
||||
multiclassItems.map(x => x.id)
|
||||
);
|
||||
|
||||
this.update({
|
||||
|
|
@ -281,6 +285,7 @@ export default class DhpActor extends Actor {
|
|||
|
||||
async levelUp(levelupData) {
|
||||
const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
const getStatsWithSource = document => ({ ...(document._stats ?? {}), compendiumSource: document.uuid });
|
||||
|
||||
const levelups = {};
|
||||
for (var levelKey of Object.keys(levelupData)) {
|
||||
|
|
@ -393,8 +398,8 @@ export default class DhpActor extends Actor {
|
|||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...multiclassData,
|
||||
uuid: multiclassItem.uuid,
|
||||
_stats: multiclassItem._stats,
|
||||
uuid: multiclassItem.uuid, // todo: replace with setting an id and using keepId
|
||||
_stats: getStatsWithSource(multiclassItem),
|
||||
system: {
|
||||
...multiclassData.system,
|
||||
features: multiclassData.system.features.filter(x => x.type !== 'hope'),
|
||||
|
|
@ -407,8 +412,8 @@ export default class DhpActor extends Actor {
|
|||
await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...subclassData,
|
||||
uuid: subclassItem.uuid,
|
||||
_stats: subclassItem._stats,
|
||||
uuid: subclassItem.uuid, // todo: replace with setting an id and using keepId
|
||||
_stats: getStatsWithSource(subclassItem),
|
||||
system: {
|
||||
...subclassData.system,
|
||||
isMulticlass: true
|
||||
|
|
@ -428,8 +433,8 @@ export default class DhpActor extends Actor {
|
|||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...cardData,
|
||||
uuid: cardItem.uuid,
|
||||
_stats: cardItem._stats,
|
||||
uuid: cardItem.uuid, // todo: replace with setting an id and using keepId
|
||||
_stats: getStatsWithSource(cardItem),
|
||||
system: {
|
||||
...cardData.system,
|
||||
inVault: true
|
||||
|
|
@ -450,8 +455,7 @@ export default class DhpActor extends Actor {
|
|||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
||||
{
|
||||
...cardData,
|
||||
uuid: cardItem.uuid,
|
||||
_stats: cardItem._stats,
|
||||
_stats: getStatsWithSource(cardItem),
|
||||
system: {
|
||||
...cardData.system,
|
||||
inVault: true
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
input[type='text'],
|
||||
input[type='number'],
|
||||
textarea,
|
||||
file-picker,
|
||||
.input[contenteditable] {
|
||||
background: light-dark(transparent, transparent);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 30px @soft-shadow;
|
||||
backdrop-filter: blur(9.5px);
|
||||
-webkit-backdrop-filter: blur(9.5px);
|
||||
outline: 2px solid transparent;
|
||||
color: light-dark(@dark-blue, @golden);
|
||||
border: 1px solid light-dark(@dark, @beige);
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
color: light-dark(@dark, @beige);
|
||||
}
|
||||
|
||||
button:where(:not(.plain)) {
|
||||
button:where(:not(.plain, color-picker *, file-picker *)) {
|
||||
background: light-dark(transparent, @golden);
|
||||
border: 1px solid light-dark(@dark-blue, @dark-blue);
|
||||
color: light-dark(@dark-blue, @dark-blue);
|
||||
|
|
@ -252,6 +252,15 @@
|
|||
text-shadow: 0 0 1px currentColor, 0 0 1px currentColor, 0 0 8px light-dark(@dark-blue, @golden);
|
||||
}
|
||||
|
||||
file-picker, color-picker {
|
||||
> input[type=text] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
outline: none;
|
||||
backdrop-filter: unset;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
align-items: center;
|
||||
margin-top: 5px;
|
||||
|
|
@ -597,59 +606,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.application.setting.dh-style {
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
margin: 8px 0 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.25rem 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
label {
|
||||
font-size: var(--font-size-14);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.setting-two-values {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.25rem 0.5rem;
|
||||
|
||||
.form-group {
|
||||
justify-content: end;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.hint {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.system-daggerheart {
|
||||
.tagify {
|
||||
background: light-dark(transparent, transparent);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
.resource-icons-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
|
||||
.resource-icon-container {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,67 @@
|
|||
@import '../../utils/colors.less';
|
||||
|
||||
.daggerheart.dh-style.setting {
|
||||
--color-form-label: var(--color-text-primary);
|
||||
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
margin: 8px 0 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.standard-form {
|
||||
gap: var(--spacer-8);
|
||||
.form-group .form-fields {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.25rem 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
|
||||
label {
|
||||
font-size: var(--font-size-14);
|
||||
font-weight: normal;
|
||||
line-height: var(--input-height);
|
||||
}
|
||||
|
||||
.form-fields {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&.setting-two-values {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.25rem 0.5rem;
|
||||
|
||||
.form-group {
|
||||
justify-content: end;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.hint {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -19,7 +80,10 @@
|
|||
&.three-columns {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 2px;
|
||||
gap: 4px;
|
||||
.form-group label {
|
||||
line-height: unset;
|
||||
}
|
||||
}
|
||||
|
||||
&.six-columns {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div>
|
||||
<div class="standard-form">
|
||||
{{formGroup settingFields.schema.fields.hideObserverPermissionInChat value=settingFields._source.hideObserverPermissionInChat localize=true}}
|
||||
{{formGroup settingFields.schema.fields.hidePartyStats value=settingFields._source.hidePartyStats localize=true}}
|
||||
</div>
|
||||
{{formGroup settingFields.schema.fields.hidePartyStats value=settingFields._source.hidePartyStats localize=true}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
</div>
|
||||
{{else}}
|
||||
<div class='status-value'>
|
||||
<input class="bar-input armor-marks-input" value="{{document.system.armorScore.value}}" type="number">
|
||||
<input class="bar-input armor-marks-input" value="{{document.system.armorScore.value}}" type="number" id="{{document.uuid}}-armor-slots">
|
||||
<span>/</span>
|
||||
<span class="bar-label">{{document.system.armorScore.max}}</span>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue