{
min="1"
max="20"
:label="'Player ' + (index + 1)"
- v-model.number="tmpParty[index]"
+ v-model.number="tmpParty.members[index]"
@update:model-value="validateLevel(index)"
dense
/>
@@ -109,7 +268,7 @@ const saveChanges = () => {
+
+
diff --git a/src/pages/EncounterPage.vue b/src/pages/EncounterPage.vue
index 90c0b37..05fe533 100644
--- a/src/pages/EncounterPage.vue
+++ b/src/pages/EncounterPage.vue
@@ -2,6 +2,7 @@
import { shallowRef } from 'vue';
import { requestCreatures, requestFilters } from 'src/utils/api-calls';
import { partyStore, filtersStore, creaturesStore, encounterStore } from 'stores/store';
+import { party } from 'src/types/party';
import { creature } from 'src/types/creature';
import CreatureList from 'src/components/Encounter/CreatureList.vue';
@@ -11,19 +12,41 @@ const creatures = creaturesStore();
const encounter = encounterStore();
const currentComponent = shallowRef();
-const localParty = localStorage.getItem('party');
+const localParty = localStorage.getItem('parties');
if (localParty) {
try {
- const parsedParty: number[] = JSON.parse(localParty);
- if (parsedParty && parsedParty.every((player) => player >= 1 && player <= 20)) {
- party.updateParty(parsedParty);
+ const parsedParties = JSON.parse(localParty);
+ if (Array.isArray(parsedParties)) {
+ const isCompatible = parsedParties.every((p) => {
+ return (
+ typeof p.name === 'string' &&
+ Array.isArray(p.members) &&
+ p.members.every((member: any) => typeof member === 'number')
+ );
+ });
+ if (isCompatible) {
+ const parties: party[] = parsedParties;
+ parties.forEach((p) => {
+ if (!p || !p.members.every((player) => player >= 1 && player <= 20)) {
+ throw 'Invalid saved party levels';
+ }
+ });
+ const partyNames = parties.map((p) => p.name);
+ if (new Set(partyNames).size !== partyNames.length) {
+ throw 'Duplicate saved party names';
+ }
+ party.updateParties(parties);
+ } else {
+ throw 'Invalid saved party format';
+ }
} else {
- throw 'Invalid saved party';
+ throw 'Invalid saved party format';
}
- } catch (_) {
- console.error('Invalid saved party');
- localStorage.setItem('party', JSON.stringify([1, 1, 1, 1]));
- party.updateParty([1, 1, 1, 1]);
+ } catch (error) {
+ console.error(error);
+ const defaultParty = { name: 'Default', members: [1, 1, 1, 1] };
+ localStorage.setItem('parties', JSON.stringify([defaultParty]));
+ party.updateParties([defaultParty]);
}
}
@@ -119,7 +142,8 @@ const steps = [
},
{
target: '#v-step-1',
- content: 'You can change your party size and the level of the individual players here.',
+ content:
+ 'Here you can change your party size and the level of the individual players. You can also add multiple parties and select the active one.',
params: {
placement: 'bottom'
}
@@ -135,14 +159,14 @@ const steps = [
{
target: '#v-step-3',
content:
- 'Clicking this button will generate a new random encounter, using the settings previously described.',
+ 'Clicking this button will generate a new random encounter, based on the generator settings previously described and the currently active party.',
params: {
placement: 'bottom'
}
},
{
target: '#v-step-4',
- content: 'From this dropdown you can select which colums to show and hide.',
+ content: 'From this dropdown you can select which columns of the table to show and hide.',
params: {
placement: 'bottom'
}
@@ -157,7 +181,7 @@ const steps = [
{
target: '#v-step-6',
content:
- 'This is the encounter list, where the creatures you added will be displayed. You can increase or decrease the number of creatures and change them to their Weak/Elite variant.',
+ 'This is the encounter list, where the creatures you added will be displayed. You can increase or decrease the number of each creature and change them to their Weak/Elite variant.',
params: {
placement: 'auto'
}
diff --git a/src/stores/store.ts b/src/stores/store.ts
index 303aa73..a0148c0 100644
--- a/src/stores/store.ts
+++ b/src/stores/store.ts
@@ -1,21 +1,48 @@
+import { party } from 'src/types/party';
import { creature } from 'src/types/creature';
import { encounter } from 'src/types/encounter';
import { defineStore } from 'pinia';
export const partyStore = defineStore('party', {
- state: () => ({ party: [1, 1, 1, 1] }),
+ state: () => ({
+ parties: [{ name: 'Default', members: [1, 1, 1, 1] }] as party[],
+ activeParty: 0
+ }),
getters: {
- getParty: (state) => state.party
+ getParties: (state) => state.parties,
+ getActive: (state) => state.activeParty,
+ getActiveParty: (state) => state.parties[state.activeParty]
},
actions: {
- updateParty(newParty: number[]) {
- this.party = newParty;
+ getPartyIndex(partyName: string): number {
+ return this.parties.map((party) => party.name).indexOf(partyName);
},
- addPlayer() {
- this.party.push(1);
+ updateParty(partyName: string, newMembers: number[]) {
+ const partyIndex = this.getPartyIndex(partyName);
+ if (partyIndex >= 0) {
+ this.parties[partyIndex].members = newMembers;
+ }
},
- removePlayer(index: number) {
- this.party.splice(index, 1);
+ updateParties(newParties: party[]) {
+ this.parties = newParties;
+ },
+ changeActiveParty(partyIndex: number) {
+ if (partyIndex >= this.parties.length || partyIndex < 0) {
+ this.activeParty = 0;
+ } else {
+ this.activeParty = partyIndex;
+ }
+ },
+ addParty(partyName: string) {
+ this.parties.push({ name: partyName, members: [1, 1, 1, 1] });
+ this.activeParty = this.parties.length - 1;
+ },
+ removeParty() {
+ this.parties.splice(this.activeParty, 1);
+ this.activeParty = 0;
+ if (this.parties.length <= 0) {
+ this.parties = [{ name: 'Default', members: [1, 1, 1, 1] }];
+ }
}
}
});
diff --git a/src/types/party.ts b/src/types/party.ts
new file mode 100644
index 0000000..46736d1
--- /dev/null
+++ b/src/types/party.ts
@@ -0,0 +1,4 @@
+export type party = {
+ name: string;
+ members: number[];
+};