From b1fa78ec8fea115bc66f05f1381b45af6cc39148 Mon Sep 17 00:00:00 2001 From: david-buderus Date: Sat, 1 Jun 2024 19:22:03 +0200 Subject: [PATCH] Added universe settings as own classes --- .teamscale.toml | 2 +- docs/swagger.json | 315 +++++++-- ...fectCalculation.java => ECalculation.java} | 5 +- .../attributes/PrimaryAttribute.java | 4 +- .../attributes/SecondaryAttribute.java | 4 +- .../component/character/Character.java | 11 - .../character/CharacterDescription.java | 51 +- .../character/CharacterEquipment.java | 43 +- .../character/CharacterInventory.java | 23 +- .../component/character/CharacterStats.java | 48 +- .../component/character/CharacterTalents.java | 25 + .../manager/component/character/Nation.java | 52 +- .../component/character/PnPCharacter.java | 182 ++++++ .../pnp/manager/component/character/Race.java | 61 +- .../manager/component/character/Talent.java | 2 +- .../character/stats/PrimaryStat.java | 8 - .../character/stats/SecondaryStat.java | 13 - .../component/character/stats/Stat.java | 34 + .../character/traits/CharacterTrait.java | 8 - .../character/traits/ICharacterTrait.java | 24 + .../character/traits/RollModifyingTrait.java | 5 - .../traits/SimpleCharacterTrait.java | 39 ++ .../character/traits/StatModifyingTrait.java | 5 - .../component/character/traits/StatTrait.java | 94 +++ .../traits/TalentCharacterTrait.java | 45 ++ .../component/inventory/Inventory.java | 61 +- .../component/inventory/ItemStack.java | 10 +- .../inventory/equipment/ArmorEquipment.java | 13 + .../equipment/DamageableEquipment.java | 4 +- .../equipment/DefensiveEquipment.java | 23 +- .../inventory/equipment/Equipment.java | 15 +- .../inventory/equipment/ShieldEquipment.java | 25 + .../item/interfaces/IDefensiveItem.java | 6 + .../item/interfaces/IEquipableItem.java | 3 + .../item/interfaces/IHandheldItem.java | 6 + .../item/interfaces/IOffensiveItem.java | 6 + .../component/universe/CharacterSettings.java | 80 +++ ...Calculation.java => CurrencySettings.java} | 11 +- .../component/universe/ItemSettings.java | 43 ++ .../component/universe/SettingsBase.java | 15 + .../manager/component/universe/Universe.java | 25 +- .../component/universe/UniverseSettings.java | 57 -- .../effect/EquipmentUpgradeEffect.java | 7 +- .../server/contoller/ItemStackController.java | 7 +- .../backup/BackupExportController.java | 2 +- .../backup/BackupImportController.java | 2 +- .../server/database/RepositoryBase.java | 1 + .../{ => universe}/UniverseRepository.java | 17 +- .../universe/UniverseSettingsRepository.java | 65 ++ .../{ => universe}/UniverseService.java | 4 +- .../universe/UniverseSettingsService.java | 77 +++ .../equipment/DefensiveEquipmentTest.java | 24 +- .../inventory/equipment/EquipmentTest.java | 10 +- .../equipment/WeaponEquipmentTest.java | 12 +- .../de/pnp/manager/server/ServerTestBase.java | 2 +- .../pnp/manager/server/UniverseTestBase.java | 14 +- .../SimpleUniverseServerConfiguration.java | 2 +- .../contoller/ItemStackControllerTest.java | 12 +- .../backup/BackupControllerTest.java | 2 +- .../UniverseSettingRepositoryTest.java | 24 + .../upgrade/UpgradeRepositoryTest.java | 6 +- .../server/service/UniverseServiceTest.java | 5 +- .../service/upgrade/UpgradeServiceTest.java | 6 +- .../webapp/database/UpgradePageTest.java | 4 +- webapp/src/api/api.ts | 617 ++++++++++++++++-- webapp/src/components/PageBase.tsx | 15 +- webapp/src/components/Utils.tsx | 18 +- .../database/DatabaseObjectDialog.tsx | 4 +- .../src/components/items/ItemManipulation.tsx | 4 +- webapp/src/pages/items/armor.tsx | 4 +- webapp/src/pages/items/items.tsx | 4 +- webapp/src/pages/items/jewellery.tsx | 4 +- webapp/src/pages/items/shields.tsx | 4 +- webapp/src/pages/items/upgrades.tsx | 8 +- webapp/src/pages/items/weapons.tsx | 4 +- 75 files changed, 2080 insertions(+), 417 deletions(-) rename server/src/main/java/de/pnp/manager/component/{upgrade/effect/EUpgradeEffectCalculation.java => ECalculation.java} (61%) delete mode 100644 server/src/main/java/de/pnp/manager/component/character/Character.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/CharacterTalents.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/PnPCharacter.java delete mode 100644 server/src/main/java/de/pnp/manager/component/character/stats/PrimaryStat.java delete mode 100644 server/src/main/java/de/pnp/manager/component/character/stats/SecondaryStat.java delete mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/CharacterTrait.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/ICharacterTrait.java delete mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/RollModifyingTrait.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/SimpleCharacterTrait.java delete mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/StatModifyingTrait.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/StatTrait.java create mode 100644 server/src/main/java/de/pnp/manager/component/character/traits/TalentCharacterTrait.java create mode 100644 server/src/main/java/de/pnp/manager/component/inventory/equipment/ArmorEquipment.java create mode 100644 server/src/main/java/de/pnp/manager/component/inventory/equipment/ShieldEquipment.java create mode 100644 server/src/main/java/de/pnp/manager/component/universe/CharacterSettings.java rename server/src/main/java/de/pnp/manager/component/universe/{CurrencyCalculation.java => CurrencySettings.java} (85%) create mode 100644 server/src/main/java/de/pnp/manager/component/universe/ItemSettings.java create mode 100644 server/src/main/java/de/pnp/manager/component/universe/SettingsBase.java delete mode 100644 server/src/main/java/de/pnp/manager/component/universe/UniverseSettings.java rename server/src/main/java/de/pnp/manager/server/database/{ => universe}/UniverseRepository.java (84%) create mode 100644 server/src/main/java/de/pnp/manager/server/database/universe/UniverseSettingsRepository.java rename server/src/main/java/de/pnp/manager/server/service/{ => universe}/UniverseService.java (98%) create mode 100644 server/src/main/java/de/pnp/manager/server/service/universe/UniverseSettingsService.java create mode 100644 server/src/test/java/de/pnp/manager/server/database/universe/UniverseSettingRepositoryTest.java diff --git a/.teamscale.toml b/.teamscale.toml index 2ef1f382..7e97de28 100644 --- a/.teamscale.toml +++ b/.teamscale.toml @@ -12,7 +12,7 @@ root = true # Optional, default: false # The URL of the Teamscale server. # If set, it must match the URL of a server for which credentials (Username, IDE Access Key) have been configured in the respective IDE. -url = "https://pnp-nexus.de/teamscale" # Optional, but must be set in the merged configuration +url = "https://pnp-nexus.de/teamscale/" # Optional, but must be set in the merged configuration [project] diff --git a/docs/swagger.json b/docs/swagger.json index ba14aac5..8de0cea9 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -115,6 +115,195 @@ ] } }, + "/api/universe-settings/{universe}/character": { + "get": { + "operationId": "getCharacterSettings", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CharacterSettings" + } + } + }, + "description": "OK" + } + }, + "summary": "Get the settings", + "tags": [ + "universe-settings-service" + ] + }, + "put": { + "operationId": "updateCharacterSettings_1", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CharacterSettings" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + } + }, + "summary": "Update the settings", + "tags": [ + "universe-settings-service" + ] + } + }, + "/api/universe-settings/{universe}/currency": { + "get": { + "operationId": "getCurrencySettings", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CurrencySettings" + } + } + }, + "description": "OK" + } + }, + "summary": "Get the settings", + "tags": [ + "universe-settings-service" + ] + }, + "put": { + "operationId": "updateCharacterSettings", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CurrencySettings" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + } + }, + "summary": "Update the settings", + "tags": [ + "universe-settings-service" + ] + } + }, + "/api/universe-settings/{universe}/item": { + "get": { + "operationId": "getItemSettings", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ItemSettings" + } + } + }, + "description": "OK" + } + }, + "summary": "Get the settings", + "tags": [ + "universe-settings-service" + ] + }, + "put": { + "operationId": "updateItemSettings", + "parameters": [ + { + "in": "path", + "name": "universe", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ItemSettings" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + } + }, + "summary": "Update the settings", + "tags": [ + "universe-settings-service" + ] + } + }, "/api/universes": { "get": { "operationId": "getAllUniverses", @@ -3632,6 +3821,21 @@ } ] }, + "ArmorDefinition": { + "required": [ + "name", + "type" + ], + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "$ref": "#/components/schemas/ItemType" + } + } + }, "CharacterResourceUsage": { "required": [ "resource" @@ -3655,6 +3859,31 @@ } ] }, + "CharacterSettings": { + "required": [ + "armorDefinitions", + "jewelleryDefinitions" + ], + "type": "object", + "properties": { + "armorDefinitions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ArmorDefinition" + } + }, + "jewelleryDefinitions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ArmorDefinition" + } + }, + "numberOfHandheld": { + "type": "integer", + "format": "int32" + } + } + }, "CraftingRecipe": { "required": [ "materials", @@ -3701,47 +3930,54 @@ } } }, - "CurrencyCalculation": { + "CurrencyCalculationEntry": { "required": [ - "baseCurrency", - "baseCurrencyShortForm", - "calculationEntries" + "currency", + "currencyShortForm" ], "type": "object", "properties": { - "baseCurrency": { + "currency": { "type": "string" }, - "baseCurrencyShortForm": { + "currencyShortForm": { "type": "string" }, - "calculationEntries": { - "type": "array", - "items": { - "$ref": "#/components/schemas/CurrencyCalculationEntry" - } + "factor": { + "type": "integer", + "format": "int32" } } }, - "CurrencyCalculationEntry": { + "CurrencySettings": { "required": [ - "currency", - "currencyShortForm" + "baseCurrency", + "baseCurrencyShortForm", + "calculationEntries" ], "type": "object", "properties": { - "currency": { + "baseCurrency": { "type": "string" }, - "currencyShortForm": { + "baseCurrencyShortForm": { "type": "string" }, - "factor": { - "type": "integer", - "format": "int32" + "calculationEntries": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CurrencyCalculationEntry" + } } } }, + "ECalculation": { + "type": "string", + "enum": [ + "ADDITIVE", + "MULTIPLICATIVE" + ] + }, "ERarity": { "type": "string", "enum": [ @@ -3753,13 +3989,6 @@ "GODLIKE" ] }, - "EUpgradeEffectCalculation": { - "type": "string", - "enum": [ - "ADDITIVE", - "MULTIPLICATIVE" - ] - }, "EUpgradeEquipmentManipulator": { "type": "string", "enum": [ @@ -3788,7 +4017,7 @@ "type": "object", "properties": { "calculation": { - "$ref": "#/components/schemas/EUpgradeEffectCalculation" + "$ref": "#/components/schemas/ECalculation" }, "upgradeManipulator": { "$ref": "#/components/schemas/EUpgradeEquipmentManipulator" @@ -3930,6 +4159,18 @@ } } }, + "ItemSettings": { + "required": [ + "wearFactor" + ], + "type": "object", + "properties": { + "wearFactor": { + "type": "integer", + "format": "int32" + } + } + }, "ItemType": { "required": [ "name", @@ -4409,7 +4650,6 @@ "description", "displayName", "name", - "settings", "shortDescription" ], "type": "object", @@ -4426,30 +4666,11 @@ "pattern": "[a-z][a-z-]+[a-z]", "type": "string" }, - "settings": { - "$ref": "#/components/schemas/UniverseSettings" - }, "shortDescription": { "type": "string" } } }, - "UniverseSettings": { - "required": [ - "currencyCalculation", - "wearFactor" - ], - "type": "object", - "properties": { - "currencyCalculation": { - "$ref": "#/components/schemas/CurrencyCalculation" - }, - "wearFactor": { - "type": "integer", - "format": "int32" - } - } - }, "Upgrade": { "required": [ "effects", diff --git a/server/src/main/java/de/pnp/manager/component/upgrade/effect/EUpgradeEffectCalculation.java b/server/src/main/java/de/pnp/manager/component/ECalculation.java similarity index 61% rename from server/src/main/java/de/pnp/manager/component/upgrade/effect/EUpgradeEffectCalculation.java rename to server/src/main/java/de/pnp/manager/component/ECalculation.java index 2eff8c85..c96a5658 100644 --- a/server/src/main/java/de/pnp/manager/component/upgrade/effect/EUpgradeEffectCalculation.java +++ b/server/src/main/java/de/pnp/manager/component/ECalculation.java @@ -1,11 +1,12 @@ -package de.pnp.manager.component.upgrade.effect; +package de.pnp.manager.component; +import de.pnp.manager.component.upgrade.effect.UpgradeEffect; import io.swagger.v3.oas.annotations.media.Schema; /** * Determines how the attribute gets manipulated by the {@link UpgradeEffect}. */ @Schema(enumAsRef = true) -public enum EUpgradeEffectCalculation { +public enum ECalculation { ADDITIVE, MULTIPLICATIVE } diff --git a/server/src/main/java/de/pnp/manager/component/attributes/PrimaryAttribute.java b/server/src/main/java/de/pnp/manager/component/attributes/PrimaryAttribute.java index 26acc0c1..73993de1 100644 --- a/server/src/main/java/de/pnp/manager/component/attributes/PrimaryAttribute.java +++ b/server/src/main/java/de/pnp/manager/component/attributes/PrimaryAttribute.java @@ -2,14 +2,14 @@ import de.pnp.manager.component.DatabaseObject; import de.pnp.manager.component.IUniquelyNamedDataObject; -import de.pnp.manager.component.character.Character; +import de.pnp.manager.component.character.PnPCharacter; import jakarta.validation.constraints.NotBlank; import java.util.Objects; import org.bson.types.ObjectId; import org.springframework.data.mongodb.core.index.Indexed; /** - * A primary attribute of a {@link Character}. + * A primary attribute of a {@link PnPCharacter}. */ public class PrimaryAttribute extends DatabaseObject implements IUniquelyNamedDataObject { diff --git a/server/src/main/java/de/pnp/manager/component/attributes/SecondaryAttribute.java b/server/src/main/java/de/pnp/manager/component/attributes/SecondaryAttribute.java index f68682d1..eee3234b 100644 --- a/server/src/main/java/de/pnp/manager/component/attributes/SecondaryAttribute.java +++ b/server/src/main/java/de/pnp/manager/component/attributes/SecondaryAttribute.java @@ -2,7 +2,7 @@ import de.pnp.manager.component.DatabaseObject; import de.pnp.manager.component.IUniquelyNamedDataObject; -import de.pnp.manager.component.character.Character; +import de.pnp.manager.component.character.PnPCharacter; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; @@ -14,7 +14,7 @@ import org.springframework.data.mongodb.core.mapping.DBRef; /** - * A secondary attribute of a {@link Character}. + * A secondary attribute of a {@link PnPCharacter}. */ public class SecondaryAttribute extends DatabaseObject implements IUniquelyNamedDataObject { diff --git a/server/src/main/java/de/pnp/manager/component/character/Character.java b/server/src/main/java/de/pnp/manager/component/character/Character.java deleted file mode 100644 index 4db4d699..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/Character.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.pnp.manager.component.character; - -public class Character { - - private CharacterDescription description; - private CharacterInventory inventory; - - private Race race; - private Nation nation; - -} diff --git a/server/src/main/java/de/pnp/manager/component/character/CharacterDescription.java b/server/src/main/java/de/pnp/manager/component/character/CharacterDescription.java index f53b2484..af71d9ee 100644 --- a/server/src/main/java/de/pnp/manager/component/character/CharacterDescription.java +++ b/server/src/main/java/de/pnp/manager/component/character/CharacterDescription.java @@ -1,11 +1,54 @@ package de.pnp.manager.component.character; -import de.pnp.manager.component.character.traits.CharacterTrait; -import java.util.Set; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +/** + * The description of a {@link PnPCharacter}. + */ public class CharacterDescription { - private String description; + @NotBlank + private final String name; - private Set traits; + @Positive + private final int age; + + @NotNull + private final String profession; + + @NotNull + private final String gender; + + @NotNull + private final String backstory; + + public CharacterDescription(String name, int age, String profession, String gender, String backstory) { + this.name = name; + this.age = age; + this.profession = profession; + this.gender = gender; + this.backstory = backstory; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public String getProfession() { + return profession; + } + + public String getGender() { + return gender; + } + + public String getBackstory() { + return backstory; + } } diff --git a/server/src/main/java/de/pnp/manager/component/character/CharacterEquipment.java b/server/src/main/java/de/pnp/manager/component/character/CharacterEquipment.java index ec512734..d825643f 100644 --- a/server/src/main/java/de/pnp/manager/component/character/CharacterEquipment.java +++ b/server/src/main/java/de/pnp/manager/component/character/CharacterEquipment.java @@ -1,20 +1,45 @@ package de.pnp.manager.component.character; -import de.pnp.manager.component.inventory.equipment.DefensiveEquipment; +import com.google.common.collect.ListMultimap; +import de.pnp.manager.component.inventory.equipment.ArmorEquipment; import de.pnp.manager.component.inventory.equipment.Equipment; import de.pnp.manager.component.inventory.equipment.interfaces.IHandheldEquipment; import de.pnp.manager.component.item.equipable.Jewellery; -import java.util.Set; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import java.util.Map; +import java.util.Optional; +/** + * The {@link Equipment} of a {@link PnPCharacter}. + */ public class CharacterEquipment { - IHandheldEquipment primary; - IHandheldEquipment secondary; + @NotNull + private final List handheldEquipments; - DefensiveEquipment helmet; - DefensiveEquipment bodyArmor; - DefensiveEquipment legs; - DefensiveEquipment boots; + @NotNull + private final Map armor; - Set> jewellerySet; + @NotNull + private final ListMultimap> jewellery; + + public CharacterEquipment(List handheldEquipments, Map armor, + ListMultimap> jewellery) { + this.handheldEquipments = handheldEquipments; + this.armor = armor; + this.jewellery = jewellery; + } + + public List getHandheldEquipments() { + return handheldEquipments; + } + + public Optional getArmor(String slot) { + return Optional.ofNullable(armor.get(slot)); + } + + public List> getJewellery(String slot) { + return jewellery.get(slot); + } } diff --git a/server/src/main/java/de/pnp/manager/component/character/CharacterInventory.java b/server/src/main/java/de/pnp/manager/component/character/CharacterInventory.java index 5afe7e4c..6ccc13a5 100644 --- a/server/src/main/java/de/pnp/manager/component/character/CharacterInventory.java +++ b/server/src/main/java/de/pnp/manager/component/character/CharacterInventory.java @@ -2,12 +2,29 @@ import de.pnp.manager.component.inventory.Inventory; +/** + * The inventory of a {@link PnPCharacter}. + */ public class CharacterInventory { - private Inventory inventory; + private final Inventory inventory; - static class CharacterPurse { + private int coin; - int coin; + public CharacterInventory(Inventory inventory, int coin) { + this.inventory = inventory; + this.coin = coin; + } + + public Inventory getInventory() { + return inventory; + } + + public int getCoin() { + return coin; + } + + public void setCoin(int coin) { + this.coin = coin; } } diff --git a/server/src/main/java/de/pnp/manager/component/character/CharacterStats.java b/server/src/main/java/de/pnp/manager/component/character/CharacterStats.java index 0519868c..1a3d1872 100644 --- a/server/src/main/java/de/pnp/manager/component/character/CharacterStats.java +++ b/server/src/main/java/de/pnp/manager/component/character/CharacterStats.java @@ -1,24 +1,54 @@ package de.pnp.manager.component.character; +import com.fasterxml.jackson.annotation.JsonCreator; import de.pnp.manager.component.attributes.PrimaryAttribute; import de.pnp.manager.component.attributes.SecondaryAttribute; -import de.pnp.manager.component.character.stats.PrimaryStat; -import de.pnp.manager.component.character.stats.SecondaryStat; -import java.util.Collections; +import de.pnp.manager.component.character.stats.Stat; +import jakarta.validation.constraints.NotEmpty; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; +/** + * The stats of a {@link PnPCharacter}. + */ public class CharacterStats { - private Map primaryStats; - private Map secondaryStats; + @NotEmpty + private final Map primaryStats; + @NotEmpty + private final Map secondaryStats; - public int getStat(PrimaryStat primaryAttribute) { - return primaryStats.get(primaryAttribute).getStatValue(); + @JsonCreator + public CharacterStats(Map primaryStats, Map secondaryStats) { + this.primaryStats = new HashMap<>(primaryStats); + this.secondaryStats = new HashMap<>(secondaryStats); } + public int getStat(PrimaryAttribute attribute) { + return primaryStats.get(attribute).getValue(); + } + + + public int getStat(SecondaryAttribute attribute) { + return secondaryStats.get(attribute).getValue(); + } + + public void setFlatModifier(PrimaryAttribute attribute, int flatModifier) { + primaryStats.get(attribute).setFlatModifier(flatModifier); + } + + public void setFlatModifier(SecondaryAttribute attribute, int flatModifier) { + secondaryStats.get(attribute).setFlatModifier(flatModifier); + } - public Map getPrimaryStats() { - return Collections.unmodifiableMap(primaryStats); + public void recalculateSecondaryStats() { + for (Entry entry : secondaryStats.entrySet()) { + SecondaryAttribute attribute = entry.getKey(); + secondaryStats.put(attribute, new Stat((int) Math.round(attribute.getPrimaryAttributeDependencies().stream() + .mapToDouble(dependency -> dependency.factor() * getStat(dependency.primaryAttribute())).sum()), + entry.getValue().getFlatModifier())); + } } } diff --git a/server/src/main/java/de/pnp/manager/component/character/CharacterTalents.java b/server/src/main/java/de/pnp/manager/component/character/CharacterTalents.java new file mode 100644 index 00000000..6dc26bf3 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/CharacterTalents.java @@ -0,0 +1,25 @@ +package de.pnp.manager.component.character; + +import jakarta.validation.constraints.NotEmpty; +import java.util.Map; + +/** + * The talents of a {@link PnPCharacter} + */ +public class CharacterTalents { + + @NotEmpty + private final Map talents; + + public CharacterTalents(Map talents) { + this.talents = talents; + } + + public int getRoll(Talent talent) { + return talents.getOrDefault(talent, 0); + } + + public void setRoll(Talent talent, int roll) { + talents.put(talent, roll); + } +} diff --git a/server/src/main/java/de/pnp/manager/component/character/Nation.java b/server/src/main/java/de/pnp/manager/component/character/Nation.java index 0b89f91c..5bad3349 100644 --- a/server/src/main/java/de/pnp/manager/component/character/Nation.java +++ b/server/src/main/java/de/pnp/manager/component/character/Nation.java @@ -1,11 +1,51 @@ package de.pnp.manager.component.character; -import de.pnp.manager.component.character.traits.CharacterTrait; -import java.util.Set; +import de.pnp.manager.component.DatabaseObject; +import de.pnp.manager.component.IUniquelyNamedDataObject; +import de.pnp.manager.component.character.traits.ICharacterTrait; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import org.bson.types.ObjectId; -public class Nation { +public class Nation extends DatabaseObject implements IUniquelyNamedDataObject { - private String name; - private Set races; - private Set traits; + @NotBlank + private final String name; + + @NotBlank + private final String description; + + @NotNull + private final List<@Valid ICharacterTrait> advantageTraits; + + @NotNull + private final List<@Valid ICharacterTrait> disadvantageTraits; + + public Nation(ObjectId id, String name, String description, List advantageTraits, + List disadvantageTraits) { + super(id); + this.name = name; + this.description = description; + this.advantageTraits = advantageTraits; + this.disadvantageTraits = disadvantageTraits; + } + + @Override + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public List getAdvantageTraits() { + return advantageTraits; + } + + public List getDisadvantageTraits() { + return disadvantageTraits; + } } diff --git a/server/src/main/java/de/pnp/manager/component/character/PnPCharacter.java b/server/src/main/java/de/pnp/manager/component/character/PnPCharacter.java new file mode 100644 index 00000000..055e1cf1 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/PnPCharacter.java @@ -0,0 +1,182 @@ +package de.pnp.manager.component.character; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import de.pnp.manager.component.DatabaseObject; +import de.pnp.manager.component.Spell; +import de.pnp.manager.component.attributes.PrimaryAttribute; +import de.pnp.manager.component.attributes.SecondaryAttribute; +import de.pnp.manager.component.character.traits.ICharacterTrait; +import de.pnp.manager.component.character.traits.StatTrait.PrimaryStatTrait; +import de.pnp.manager.component.character.traits.StatTrait.SecondaryStatTrait; +import de.pnp.manager.component.character.traits.TalentCharacterTrait; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; +import java.util.List; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.mapping.DBRef; + +/** + * A character in the universe. + */ +public class PnPCharacter extends DatabaseObject { + + @Valid + @NotNull + private final CharacterDescription description; + + @DBRef + @NotNull + private final Race race; + + @DBRef + @NotNull + private final Nation nation; + + @NotNull + private final List<@Valid ICharacterTrait> advantageTraits; + + @NotNull + private final List<@Valid ICharacterTrait> disadvantageTraits; + + @Valid + @NotNull + private final CharacterStats stats; + + @Valid + @NotNull + private final CharacterTalents talents; + + @Valid + @NotNull + private final CharacterEquipment equipment; + + @Valid + @NotNull + private final CharacterInventory inventory; + + @DBRef + @NotNull + private final List spells; + + @PositiveOrZero + private int level; + + @PositiveOrZero + private int experience; + + public PnPCharacter(ObjectId id, CharacterDescription description, Race race, Nation nation, + List advantageTraits, List disadvantageTraits, CharacterStats stats, + CharacterTalents talents, CharacterEquipment equipment, CharacterInventory inventory, List spells, + int level, int experience) { + super(id); + this.description = description; + this.race = race; + this.nation = nation; + this.advantageTraits = advantageTraits; + this.disadvantageTraits = disadvantageTraits; + this.stats = stats; + this.talents = talents; + this.equipment = equipment; + this.inventory = inventory; + this.spells = spells; + this.level = level; + this.experience = experience; + } + + public int getTalentRoll(Talent talent) { + int roll = talents.getRoll(talent); + for (TalentCharacterTrait trait : getAllTalentTraits()) { + roll = trait.apply(talent, roll); + } + return roll; + } + + public int getPrimaryStat(PrimaryAttribute attribute) { + float stat = stats.getStat(attribute); + for (PrimaryStatTrait trait : getAllPrimaryStatTraits()) { + stat = trait.apply(attribute, stat); + } + return Math.round(stat); + } + + public int getSecondaryStat(SecondaryAttribute attribute) { + float stat = stats.getStat(attribute); + for (SecondaryStatTrait trait : getAllSecondaryStatTraits()) { + stat = trait.apply(attribute, stat); + } + return Math.round(stat); + } + + public List getAllTraits() { + Builder builder = ImmutableList.builder(); + builder.addAll(advantageTraits).addAll(disadvantageTraits); + builder.addAll(race.getAdvantageTraits()).addAll(race.getDisadvantageTraits()); + builder.addAll(nation.getAdvantageTraits()).addAll(nation.getDisadvantageTraits()); + return builder.build(); + } + + public List getAllTalentTraits() { + return getAllTraits().stream() + .filter(TalentCharacterTrait.class::isInstance).map(TalentCharacterTrait.class::cast).toList(); + } + + public List getAllPrimaryStatTraits() { + return getAllTraits().stream() + .filter(PrimaryStatTrait.class::isInstance).map(PrimaryStatTrait.class::cast).toList(); + } + + public List getAllSecondaryStatTraits() { + return getAllTraits().stream() + .filter(SecondaryStatTrait.class::isInstance).map(SecondaryStatTrait.class::cast).toList(); + } + + public CharacterDescription getDescription() { + return description; + } + + public Race getRace() { + return race; + } + + public Nation getNation() { + return nation; + } + + public List getAdvantageTraits() { + return advantageTraits; + } + + public List getDisadvantageTraits() { + return disadvantageTraits; + } + + public CharacterStats getStats() { + return stats; + } + + public CharacterTalents getTalents() { + return talents; + } + + public CharacterEquipment getEquipment() { + return equipment; + } + + public CharacterInventory getInventory() { + return inventory; + } + + public List getSpells() { + return spells; + } + + public int getLevel() { + return level; + } + + public int getExperience() { + return experience; + } +} diff --git a/server/src/main/java/de/pnp/manager/component/character/Race.java b/server/src/main/java/de/pnp/manager/component/character/Race.java index dbe245a2..0fde2ef3 100644 --- a/server/src/main/java/de/pnp/manager/component/character/Race.java +++ b/server/src/main/java/de/pnp/manager/component/character/Race.java @@ -1,10 +1,61 @@ package de.pnp.manager.component.character; -import de.pnp.manager.component.character.traits.CharacterTrait; -import java.util.Set; +import de.pnp.manager.component.DatabaseObject; +import de.pnp.manager.component.IUniquelyNamedDataObject; +import de.pnp.manager.component.character.traits.ICharacterTrait; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import org.bson.types.ObjectId; +import org.springframework.data.mongodb.core.mapping.DBRef; -public class Race { +public class Race extends DatabaseObject implements IUniquelyNamedDataObject { - private String name; - private Set traits; + @NotBlank + private final String name; + + @NotBlank + private final String description; + + @NotNull + private final List<@Valid ICharacterTrait> advantageTraits; + + @NotNull + private final List<@Valid ICharacterTrait> disadvantageTraits; + + @DBRef + @NotNull + private final List nations; + + public Race(ObjectId id, String name, String description, List advantageTraits, + List disadvantageTraits, List nations) { + super(id); + this.name = name; + this.description = description; + this.advantageTraits = advantageTraits; + this.disadvantageTraits = disadvantageTraits; + this.nations = nations; + } + + @Override + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public List getAdvantageTraits() { + return advantageTraits; + } + + public List getDisadvantageTraits() { + return disadvantageTraits; + } + + public List getNations() { + return nations; + } } diff --git a/server/src/main/java/de/pnp/manager/component/character/Talent.java b/server/src/main/java/de/pnp/manager/component/character/Talent.java index 8308b8ff..71694c0d 100644 --- a/server/src/main/java/de/pnp/manager/component/character/Talent.java +++ b/server/src/main/java/de/pnp/manager/component/character/Talent.java @@ -13,7 +13,7 @@ import org.springframework.data.mongodb.core.mapping.Document; /** - * A talent of a {@link Character}. + * A talent of a {@link PnPCharacter}. */ @Document(TalentRepository.REPOSITORY_NAME) public class Talent extends DatabaseObject { diff --git a/server/src/main/java/de/pnp/manager/component/character/stats/PrimaryStat.java b/server/src/main/java/de/pnp/manager/component/character/stats/PrimaryStat.java deleted file mode 100644 index b4d33bed..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/stats/PrimaryStat.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.pnp.manager.component.character.stats; - -public class PrimaryStat { - - public int getStatValue() { - throw new UnsupportedOperationException("Not yet implemented"); - } -} diff --git a/server/src/main/java/de/pnp/manager/component/character/stats/SecondaryStat.java b/server/src/main/java/de/pnp/manager/component/character/stats/SecondaryStat.java deleted file mode 100644 index d5ef6e60..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/stats/SecondaryStat.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.pnp.manager.component.character.stats; - -import de.pnp.manager.component.attributes.SecondaryAttribute; - -public class SecondaryStat { - - SecondaryAttribute attribute; - - public SecondaryStat(SecondaryAttribute attribute) { - this.attribute = attribute; - } - -} diff --git a/server/src/main/java/de/pnp/manager/component/character/stats/Stat.java b/server/src/main/java/de/pnp/manager/component/character/stats/Stat.java index 994bdadf..a0eb6595 100644 --- a/server/src/main/java/de/pnp/manager/component/character/stats/Stat.java +++ b/server/src/main/java/de/pnp/manager/component/character/stats/Stat.java @@ -1,5 +1,39 @@ package de.pnp.manager.component.character.stats; +import jakarta.validation.constraints.PositiveOrZero; + +/** + * A single stat of a character. + */ public class Stat { + @PositiveOrZero + private final int rawValue; + + private int flatModifier; + + public Stat(int rawValue) { + this(rawValue, 0); + } + + public Stat(int rawValue, int flatModifier) { + this.rawValue = rawValue; + this.flatModifier = flatModifier; + } + + public int getRawValue() { + return rawValue; + } + + public int getFlatModifier() { + return flatModifier; + } + + public int getValue() { + return getRawValue() + getFlatModifier(); + } + + public void setFlatModifier(int flatModifier) { + this.flatModifier = flatModifier; + } } diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/CharacterTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/CharacterTrait.java deleted file mode 100644 index d92fb8ed..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/traits/CharacterTrait.java +++ /dev/null @@ -1,8 +0,0 @@ -package de.pnp.manager.component.character.traits; - -/** - * Can influence a character's stats, rolls and others. - */ -public class CharacterTrait { - -} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/ICharacterTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/ICharacterTrait.java new file mode 100644 index 00000000..1cf6e04f --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/traits/ICharacterTrait.java @@ -0,0 +1,24 @@ +package de.pnp.manager.component.character.traits; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import de.pnp.manager.component.character.traits.StatTrait.PrimaryStatTrait; +import de.pnp.manager.component.character.traits.StatTrait.SecondaryStatTrait; + +/** + * Can influence a character's stats, rolls and others. + */ +@JsonSubTypes({ + @JsonSubTypes.Type(value = SimpleCharacterTrait.class, name = "SimpleCharacterTrait"), + @JsonSubTypes.Type(value = TalentCharacterTrait.class, name = "TalentCharacterTrait"), + @JsonSubTypes.Type(value = PrimaryStatTrait.class, name = "PrimaryStatTrait"), + @JsonSubTypes.Type(value = SecondaryStatTrait.class, name = "SecondaryStatTrait") +}) +@JsonTypeInfo(use = JsonTypeInfo.Id.NAME) +public interface ICharacterTrait { + + /** + * Returns a human-readable description of the trait. + */ + String getDescription(); +} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/RollModifyingTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/RollModifyingTrait.java deleted file mode 100644 index cc2b30d1..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/traits/RollModifyingTrait.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.pnp.manager.component.character.traits; - -public class RollModifyingTrait extends CharacterTrait { - -} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/SimpleCharacterTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/SimpleCharacterTrait.java new file mode 100644 index 00000000..69d3d80d --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/traits/SimpleCharacterTrait.java @@ -0,0 +1,39 @@ +package de.pnp.manager.component.character.traits; + +import jakarta.validation.constraints.NotBlank; +import java.util.Objects; + +/** + * A simple trait. + */ +public class SimpleCharacterTrait implements ICharacterTrait { + + @NotBlank + private final String description; + + public SimpleCharacterTrait(String description) { + this.description = description; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SimpleCharacterTrait that = (SimpleCharacterTrait) o; + return Objects.equals(getDescription(), that.getDescription()); + } + + @Override + public int hashCode() { + return Objects.hash(getDescription()); + } +} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/StatModifyingTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/StatModifyingTrait.java deleted file mode 100644 index 7c2671af..00000000 --- a/server/src/main/java/de/pnp/manager/component/character/traits/StatModifyingTrait.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.pnp.manager.component.character.traits; - -public class StatModifyingTrait extends CharacterTrait { - -} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/StatTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/StatTrait.java new file mode 100644 index 00000000..24b73f41 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/traits/StatTrait.java @@ -0,0 +1,94 @@ +package de.pnp.manager.component.character.traits; + + +import de.pnp.manager.component.ECalculation; +import de.pnp.manager.component.attributes.PrimaryAttribute; +import de.pnp.manager.component.attributes.SecondaryAttribute; +import de.pnp.manager.component.character.stats.Stat; +import jakarta.validation.constraints.NotNull; +import java.util.Objects; +import org.springframework.data.mongodb.core.mapping.DBRef; + +/** + * Influences a {@link Stat}. + */ +public sealed abstract class StatTrait implements ICharacterTrait { + + @NotNull + private final ECalculation calculation; + + private final float value; + + @DBRef + @NotNull + private final Attribute attribute; + + @NotNull + private final String description; + + protected StatTrait(ECalculation calculation, float value, Attribute attribute, String description) { + this.calculation = calculation; + this.value = value; + this.attribute = attribute; + this.description = description; + } + + /** + * Applies the trait if the attribute matches the attribute of the trait. + */ + public float apply(Attribute attribute, float value) { + if (Objects.equals(attribute, this.attribute)) { + return switch (calculation) { + case ADDITIVE -> value + this.value; + case MULTIPLICATIVE -> value * this.value; + }; + } + return value; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + StatTrait statTrait = (StatTrait) o; + return Float.compare(statTrait.value, value) == 0 && calculation == statTrait.calculation + && Objects.equals(attribute, statTrait.attribute) && Objects.equals(getDescription(), + statTrait.getDescription()); + } + + @Override + public int hashCode() { + return Objects.hash(calculation, value, attribute, getDescription()); + } + + /** + * Influences {@link PrimaryAttribute} + */ + public static final class PrimaryStatTrait extends StatTrait { + + public PrimaryStatTrait(ECalculation calculation, float value, PrimaryAttribute primaryAttribute, + String description) { + super(calculation, value, primaryAttribute, description); + } + } + + /** + * Influences {@link SecondaryAttribute} + */ + public static final class SecondaryStatTrait extends StatTrait { + + public SecondaryStatTrait(ECalculation calculation, float value, SecondaryAttribute secondaryAttribute, + String description) { + super(calculation, value, secondaryAttribute, description); + } + } +} diff --git a/server/src/main/java/de/pnp/manager/component/character/traits/TalentCharacterTrait.java b/server/src/main/java/de/pnp/manager/component/character/traits/TalentCharacterTrait.java new file mode 100644 index 00000000..71331ce5 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/character/traits/TalentCharacterTrait.java @@ -0,0 +1,45 @@ +package de.pnp.manager.component.character.traits; + +import de.pnp.manager.component.character.Talent; +import jakarta.validation.constraints.NotNull; +import java.util.Objects; +import org.springframework.data.mongodb.core.mapping.DBRef; + +/** + * Influences the talent. + */ +public class TalentCharacterTrait implements ICharacterTrait { + + @NotNull + @DBRef + private final Talent talent; + + private final int rollModifier; + + @NotNull + private final String description; + + public TalentCharacterTrait(Talent talent, int rollModifier, String description) { + this.talent = talent; + this.rollModifier = rollModifier; + this.description = description; + } + + /** + * Applies the trait on the talent. + */ + public int apply(Talent talent, int value) { + if (Objects.equals(talent, this.talent)) { + return value + rollModifier; + } + return value; + } + + @Override + public String getDescription() { + if (description.isBlank()) { + return rollModifier + " " + talent.getName(); + } + return description; + } +} diff --git a/server/src/main/java/de/pnp/manager/component/inventory/Inventory.java b/server/src/main/java/de/pnp/manager/component/inventory/Inventory.java index da003594..28f53c57 100644 --- a/server/src/main/java/de/pnp/manager/component/inventory/Inventory.java +++ b/server/src/main/java/de/pnp/manager/component/inventory/Inventory.java @@ -1,10 +1,67 @@ package de.pnp.manager.component.inventory; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; +/** + * An inventory. + */ public class Inventory { - private int maxSize; + private final int maxSize; - private List items; + private final List> items; + + public Inventory(int maxSize, List> items) { + this.maxSize = maxSize; + this.items = items; + } + + /** + * Checks if the inventory has enough space left for the given stack. + */ + public boolean hasSpaceFor(ItemStack itemStack) { + if (items.size() < maxSize - 1) { + return true; + } + float maxStackSize = itemStack.getItem().getMaximumStackSize(); + float remaining = itemStack.getStackSize(); + + for (ItemStack stack : items) { + if (Objects.equals(stack.getItem(), itemStack.getItem())) { + remaining -= maxStackSize - stack.getStackSize(); + } + } + + return remaining <= 0; + } + + /** + * Adds an item to inventory. + */ + public boolean addItem(ItemStack itemStack) { + if (!hasSpaceFor(itemStack)) { + return false; + } + float remaining = itemStack.getStackSize(); + + for (ItemStack stack : items) { + if (Objects.equals(stack.getItem(), itemStack.getItem())) { + remaining -= stack.addAmount(remaining); + } + } + return true; + } + + public int getMaxSize() { + return maxSize; + } + + /** + * Returns a copy of the underlying item list. + */ + public List> getItems() { + return new ArrayList<>(items); + } } diff --git a/server/src/main/java/de/pnp/manager/component/inventory/ItemStack.java b/server/src/main/java/de/pnp/manager/component/inventory/ItemStack.java index c98a4304..61b057e5 100644 --- a/server/src/main/java/de/pnp/manager/component/inventory/ItemStack.java +++ b/server/src/main/java/de/pnp/manager/component/inventory/ItemStack.java @@ -4,18 +4,22 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.google.common.base.Preconditions; import com.google.common.primitives.Floats; -import de.pnp.manager.component.inventory.equipment.DefensiveEquipment; +import de.pnp.manager.component.inventory.equipment.ArmorEquipment; import de.pnp.manager.component.inventory.equipment.Equipment; +import de.pnp.manager.component.inventory.equipment.ShieldEquipment; import de.pnp.manager.component.inventory.equipment.WeaponEquipment; import de.pnp.manager.component.item.Item; import de.pnp.manager.component.item.interfaces.IItem; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; /** * Represents an {@link Item} that can be held and used. */ @JsonSubTypes({ @JsonSubTypes.Type(value = Equipment.class, name = "Equipment"), - @JsonSubTypes.Type(value = DefensiveEquipment.class, name = "DefensiveEquipment"), + @JsonSubTypes.Type(value = ShieldEquipment.class, name = "ShieldEquipment"), + @JsonSubTypes.Type(value = ArmorEquipment.class, name = "ArmorEquipment"), @JsonSubTypes.Type(value = WeaponEquipment.class, name = "WeaponEquipment"), }) @JsonTypeInfo(use = JsonTypeInfo.Id.NAME) @@ -24,11 +28,13 @@ public class ItemStack { /** * The amount of the {@link #item} this {@link ItemStack} holds. */ + @PositiveOrZero private float stackSize; /** * The {@link Item} this {@link ItemStack} represents. */ + @NotNull private final I item; public ItemStack(float stackSize, I item) { diff --git a/server/src/main/java/de/pnp/manager/component/inventory/equipment/ArmorEquipment.java b/server/src/main/java/de/pnp/manager/component/inventory/equipment/ArmorEquipment.java new file mode 100644 index 00000000..9cbf438d --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/inventory/equipment/ArmorEquipment.java @@ -0,0 +1,13 @@ +package de.pnp.manager.component.inventory.equipment; + +import de.pnp.manager.component.item.equipable.Armor; + +/** + * Represents an {@link Armor} that can be held and used. + */ +public class ArmorEquipment extends DefensiveEquipment { + + public ArmorEquipment(float stackSize, Armor item, int wear) { + super(stackSize, item, wear); + } +} diff --git a/server/src/main/java/de/pnp/manager/component/inventory/equipment/DamageableEquipment.java b/server/src/main/java/de/pnp/manager/component/inventory/equipment/DamageableEquipment.java index 19472cfb..30b953da 100644 --- a/server/src/main/java/de/pnp/manager/component/inventory/equipment/DamageableEquipment.java +++ b/server/src/main/java/de/pnp/manager/component/inventory/equipment/DamageableEquipment.java @@ -3,6 +3,7 @@ import de.pnp.manager.component.inventory.equipment.interfaces.IDamageableEquipment; import de.pnp.manager.component.item.interfaces.IDamageableItem; import de.pnp.manager.component.item.interfaces.IEquipableItem; +import jakarta.validation.constraints.PositiveOrZero; /** * Represents an {@link IDamageableItem} that can be held and used. @@ -13,9 +14,10 @@ public abstract class DamageableEquipment implements - IHandheldEquipment { +public abstract class DefensiveEquipment extends DamageableEquipment { - public DefensiveEquipment(float stackSize, IDefensiveItem item, int wear) { + protected DefensiveEquipment(float stackSize, I item, int wear) { super(stackSize, item, wear); } @@ -42,22 +39,6 @@ public int getWeight() { applyUpgradeEffects(EUpgradeEquipmentManipulator.WEIGHT, getItem().getWeight()) * getRelativeDurability()); } - @Override - public int getHit() { - if (getItem() instanceof IHandheldItem handHoldItem) { - return applyUpgradeEffects(EUpgradeEquipmentManipulator.HIT, handHoldItem.getHit()); - } - throw new AssertionError("Only HandholdItems have hit."); - } - - @Override - public float getInitiative() { - if (getItem() instanceof IHandheldItem handHoldItem) { - return applyUpgradeEffects(EUpgradeEquipmentManipulator.INITIATIVE, handHoldItem.getInitiative()); - } - throw new AssertionError("Only HandholdItems have initiative."); - } - @Override public int getMaxDurability() { return getMaxArmor(); diff --git a/server/src/main/java/de/pnp/manager/component/inventory/equipment/Equipment.java b/server/src/main/java/de/pnp/manager/component/inventory/equipment/Equipment.java index 67365a5c..0d8a615f 100644 --- a/server/src/main/java/de/pnp/manager/component/inventory/equipment/Equipment.java +++ b/server/src/main/java/de/pnp/manager/component/inventory/equipment/Equipment.java @@ -1,14 +1,16 @@ package de.pnp.manager.component.inventory.equipment; +import com.fasterxml.jackson.annotation.JsonCreator; import com.google.common.base.Preconditions; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.inventory.ItemStack; import de.pnp.manager.component.inventory.equipment.interfaces.IEquipment; import de.pnp.manager.component.item.equipable.EquipableItem; import de.pnp.manager.component.item.interfaces.IEquipableItem; import de.pnp.manager.component.upgrade.Upgrade; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; +import jakarta.validation.constraints.NotNull; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -22,6 +24,7 @@ public class Equipment extends ItemStack implements /** * The {@link Upgrade upgrades} of the {@link EquipableItem}. */ + @NotNull private Collection upgrades; public Equipment(float amount, E item) { @@ -29,6 +32,12 @@ public Equipment(float amount, E item) { upgrades = new ArrayList<>(); } + @JsonCreator + public Equipment(float stackSize, E item, Collection upgrades) { + super(stackSize, item); + this.upgrades = upgrades; + } + /** * Returns {@link EquipableItem#getUpgradeSlots()} in regard to the {@link #upgrades}. */ @@ -87,10 +96,10 @@ protected float applyUpgradeEffects(EUpgradeEquipmentManipulator manipulator, fl .filter(EquipmentUpgradeEffect.class::isInstance).map(EquipmentUpgradeEffect.class::cast) .toList(); List additiveEffects = upgradeEffects.stream() - .filter(effect -> effect.getCalculation() == EUpgradeEffectCalculation.ADDITIVE) + .filter(effect -> effect.getCalculation() == ECalculation.ADDITIVE) .toList(); List multiplicativeEffects = upgradeEffects.stream() - .filter(effect -> effect.getCalculation() == EUpgradeEffectCalculation.MULTIPLICATIVE) + .filter(effect -> effect.getCalculation() == ECalculation.MULTIPLICATIVE) .toList(); for (EquipmentUpgradeEffect effect : additiveEffects) { diff --git a/server/src/main/java/de/pnp/manager/component/inventory/equipment/ShieldEquipment.java b/server/src/main/java/de/pnp/manager/component/inventory/equipment/ShieldEquipment.java new file mode 100644 index 00000000..ea05bba3 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/inventory/equipment/ShieldEquipment.java @@ -0,0 +1,25 @@ +package de.pnp.manager.component.inventory.equipment; + +import de.pnp.manager.component.inventory.equipment.interfaces.IHandheldEquipment; +import de.pnp.manager.component.item.equipable.Shield; +import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; + +/** + * Represents an {@link Shield} that can be held and used. + */ +public class ShieldEquipment extends DefensiveEquipment implements IHandheldEquipment { + + public ShieldEquipment(float stackSize, Shield item, int wear) { + super(stackSize, item, wear); + } + + @Override + public int getHit() { + return applyUpgradeEffects(EUpgradeEquipmentManipulator.HIT, getItem().getHit()); + } + + @Override + public float getInitiative() { + return applyUpgradeEffects(EUpgradeEquipmentManipulator.INITIATIVE, getItem().getInitiative()); + } +} diff --git a/server/src/main/java/de/pnp/manager/component/item/interfaces/IDefensiveItem.java b/server/src/main/java/de/pnp/manager/component/item/interfaces/IDefensiveItem.java index 795c753e..e5c9339f 100644 --- a/server/src/main/java/de/pnp/manager/component/item/interfaces/IDefensiveItem.java +++ b/server/src/main/java/de/pnp/manager/component/item/interfaces/IDefensiveItem.java @@ -5,7 +5,13 @@ */ public interface IDefensiveItem extends IDamageableItem, IEquipableItem { + /** + * The weight of the item. + */ float getWeight(); + /** + * The armor of the item. + */ int getArmor(); } diff --git a/server/src/main/java/de/pnp/manager/component/item/interfaces/IEquipableItem.java b/server/src/main/java/de/pnp/manager/component/item/interfaces/IEquipableItem.java index 5445dc14..dc960137 100644 --- a/server/src/main/java/de/pnp/manager/component/item/interfaces/IEquipableItem.java +++ b/server/src/main/java/de/pnp/manager/component/item/interfaces/IEquipableItem.java @@ -5,5 +5,8 @@ */ public interface IEquipableItem extends IItem { + /** + * The number of upgrade slots of the underlying item. + */ int getUpgradeSlots(); } diff --git a/server/src/main/java/de/pnp/manager/component/item/interfaces/IHandheldItem.java b/server/src/main/java/de/pnp/manager/component/item/interfaces/IHandheldItem.java index 52cc0246..7bd5d758 100644 --- a/server/src/main/java/de/pnp/manager/component/item/interfaces/IHandheldItem.java +++ b/server/src/main/java/de/pnp/manager/component/item/interfaces/IHandheldItem.java @@ -5,7 +5,13 @@ */ public interface IHandheldItem extends IEquipableItem { + /** + * The hit of the underlying item. + */ int getHit(); + /** + * The init of the underlying item. + */ float getInitiative(); } diff --git a/server/src/main/java/de/pnp/manager/component/item/interfaces/IOffensiveItem.java b/server/src/main/java/de/pnp/manager/component/item/interfaces/IOffensiveItem.java index cbe3736b..7fbb88e0 100644 --- a/server/src/main/java/de/pnp/manager/component/item/interfaces/IOffensiveItem.java +++ b/server/src/main/java/de/pnp/manager/component/item/interfaces/IOffensiveItem.java @@ -5,7 +5,13 @@ */ public interface IOffensiveItem extends IDamageableItem, IHandheldItem { + /** + * The dice used while attacking with this item. + */ String getDice(); + /** + * The flat damage of the item. + */ int getDamage(); } diff --git a/server/src/main/java/de/pnp/manager/component/universe/CharacterSettings.java b/server/src/main/java/de/pnp/manager/component/universe/CharacterSettings.java new file mode 100644 index 00000000..912e0ff9 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/universe/CharacterSettings.java @@ -0,0 +1,80 @@ +package de.pnp.manager.component.universe; + +import de.pnp.manager.component.character.PnPCharacter; +import de.pnp.manager.component.item.ItemType; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.PositiveOrZero; +import java.util.List; +import java.util.Objects; +import org.springframework.data.mongodb.core.mapping.DBRef; + +/** + * The settings related to {@link PnPCharacter} + */ +public final class CharacterSettings extends SettingsBase { + + /** + * The default settings + */ + public static final CharacterSettings DEFAULT = new CharacterSettings(2, List.of(), List.of()); + private final @PositiveOrZero int numberOfHandheld; + private final @NotNull List armorDefinitions; + private final @NotNull List jewelleryDefinitions; + + public CharacterSettings( + @PositiveOrZero int numberOfHandheld, + @NotNull List armorDefinitions, + @NotNull List jewelleryDefinitions + ) { + this.numberOfHandheld = numberOfHandheld; + this.armorDefinitions = armorDefinitions; + this.jewelleryDefinitions = jewelleryDefinitions; + } + + public int getNumberOfHandheld() { + return numberOfHandheld; + } + + public List getArmorDefinitions() { + return armorDefinitions; + } + + public List getJewelleryDefinitions() { + return jewelleryDefinitions; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } + var that = (CharacterSettings) obj; + return this.numberOfHandheld == that.numberOfHandheld && + Objects.equals(this.armorDefinitions, that.armorDefinitions) && + Objects.equals(this.jewelleryDefinitions, that.jewelleryDefinitions); + } + + @Override + public int hashCode() { + return Objects.hash(numberOfHandheld, armorDefinitions, jewelleryDefinitions); + } + + /** + * In which armor slot what kind of armor is allowed. + */ + public record ArmorDefinition(@NotBlank String name, @DBRef @NotNull ItemType type) { + + } + + /** + * In which jewellery slot what kind of jewellery is allowed and how many. + */ + public record JewelleryDefinition(@NotBlank String name, @DBRef @NotNull ItemType type, @Positive int amount) { + + } +} diff --git a/server/src/main/java/de/pnp/manager/component/universe/CurrencyCalculation.java b/server/src/main/java/de/pnp/manager/component/universe/CurrencySettings.java similarity index 85% rename from server/src/main/java/de/pnp/manager/component/universe/CurrencyCalculation.java rename to server/src/main/java/de/pnp/manager/component/universe/CurrencySettings.java index a779d2df..7993ff83 100644 --- a/server/src/main/java/de/pnp/manager/component/universe/CurrencyCalculation.java +++ b/server/src/main/java/de/pnp/manager/component/universe/CurrencySettings.java @@ -10,7 +10,12 @@ /** * Defines how the vendor prices are displayed to the user. */ -public class CurrencyCalculation { +public class CurrencySettings extends SettingsBase { + + /** + * The default settings + */ + public static final CurrencySettings DEFAULT = new CurrencySettings("Currency", "C", List.of()); @NotBlank private final String baseCurrency; @@ -21,7 +26,7 @@ public class CurrencyCalculation { @NotNull private final List<@Valid CurrencyCalculationEntry> calculationEntries; - public CurrencyCalculation(String baseCurrency, String baseCurrencyShortForm, + public CurrencySettings(String baseCurrency, String baseCurrencyShortForm, List calculationEntries) { this.baseCurrency = baseCurrency; this.baseCurrencyShortForm = baseCurrencyShortForm; @@ -48,7 +53,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } - CurrencyCalculation that = (CurrencyCalculation) o; + CurrencySettings that = (CurrencySettings) o; return getBaseCurrency().equals(that.getBaseCurrency()) && getBaseCurrencyShortForm().equals( that.getBaseCurrencyShortForm()) && getCalculationEntries().equals(that.getCalculationEntries()); } diff --git a/server/src/main/java/de/pnp/manager/component/universe/ItemSettings.java b/server/src/main/java/de/pnp/manager/component/universe/ItemSettings.java new file mode 100644 index 00000000..4d995d9b --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/universe/ItemSettings.java @@ -0,0 +1,43 @@ +package de.pnp.manager.component.universe; + +import jakarta.validation.constraints.NotNull; +import java.util.Objects; + +/** + * Settings for items + */ +public class ItemSettings extends SettingsBase { + + /** + * The default settings + */ + public static final ItemSettings DEFAULT = new ItemSettings(-1); + + @NotNull + private final int wearFactor; + + public ItemSettings(int wearFactor) { + this.wearFactor = wearFactor; + } + + public int getWearFactor() { + return wearFactor; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ItemSettings that = (ItemSettings) o; + return getWearFactor() == that.getWearFactor(); + } + + @Override + public int hashCode() { + return Objects.hash(getWearFactor()); + } +} diff --git a/server/src/main/java/de/pnp/manager/component/universe/SettingsBase.java b/server/src/main/java/de/pnp/manager/component/universe/SettingsBase.java new file mode 100644 index 00000000..b78e7946 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/component/universe/SettingsBase.java @@ -0,0 +1,15 @@ +package de.pnp.manager.component.universe; + +import org.springframework.data.annotation.Id; + +/** + * Base for universe settings. + *

+ * Automatically sets the id to the name of the class. + */ +public abstract class SettingsBase { + + @Id + @SuppressWarnings({"unused", "FieldMayBeFinal"}) // Used for identification in the database + private String id = getClass().getName(); +} diff --git a/server/src/main/java/de/pnp/manager/component/universe/Universe.java b/server/src/main/java/de/pnp/manager/component/universe/Universe.java index 819686db..e1d51765 100644 --- a/server/src/main/java/de/pnp/manager/component/universe/Universe.java +++ b/server/src/main/java/de/pnp/manager/component/universe/Universe.java @@ -1,8 +1,7 @@ package de.pnp.manager.component.universe; import com.fasterxml.jackson.annotation.JsonCreator; -import de.pnp.manager.server.database.UniverseRepository; -import jakarta.validation.Valid; +import de.pnp.manager.server.database.universe.UniverseRepository; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; @@ -41,26 +40,17 @@ public class Universe { @NotNull private final String description; - /** - * The settings of the {@link Universe} - */ - @Valid - @NotNull - private final UniverseSettings settings; - public Universe(String name, String displayName) { - this(name, displayName, "", "", UniverseSettings.DEFAULT); + this(name, displayName, "", ""); } @PersistenceCreator @JsonCreator - public Universe(String name, String displayName, String shortDescription, String description, - UniverseSettings settings) { + public Universe(String name, String displayName, String shortDescription, String description) { this.name = name; this.displayName = displayName; this.shortDescription = shortDescription; this.description = description; - this.settings = settings; } public String getName() { @@ -79,10 +69,6 @@ public String getDescription() { return description; } - public UniverseSettings getSettings() { - return settings; - } - @Override public boolean equals(Object o) { if (this == o) { @@ -94,12 +80,11 @@ public boolean equals(Object o) { Universe universe = (Universe) o; return getName().equals(universe.getName()) && getDisplayName().equals(universe.getDisplayName()) && getShortDescription().equals(universe.getShortDescription()) && getDescription().equals( - universe.getDescription()) - && getSettings().equals(universe.getSettings()); + universe.getDescription()); } @Override public int hashCode() { - return Objects.hash(getName(), getDisplayName(), getShortDescription(), getDescription(), getSettings()); + return Objects.hash(getName(), getDisplayName(), getShortDescription(), getDescription()); } } diff --git a/server/src/main/java/de/pnp/manager/component/universe/UniverseSettings.java b/server/src/main/java/de/pnp/manager/component/universe/UniverseSettings.java deleted file mode 100644 index 81be6c81..00000000 --- a/server/src/main/java/de/pnp/manager/component/universe/UniverseSettings.java +++ /dev/null @@ -1,57 +0,0 @@ -package de.pnp.manager.component.universe; - -import de.pnp.manager.component.universe.CurrencyCalculation.CurrencyCalculationEntry; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotNull; -import java.util.List; -import java.util.Objects; - -/** - * The settings of the {@link Universe}. - */ -public final class UniverseSettings { - - /** - * The default settings - */ - public static final UniverseSettings DEFAULT = new UniverseSettings(10, new CurrencyCalculation("Copper", "C", - List.of(new CurrencyCalculationEntry(100, "Silver", "S"), new CurrencyCalculationEntry(100, "Gold", "G")))); - - @NotNull - private final int wearFactor; - - @Valid - @NotNull - private final CurrencyCalculation currencyCalculation; - - public UniverseSettings(int wearFactor, CurrencyCalculation currencyCalculation) { - this.wearFactor = wearFactor; - this.currencyCalculation = currencyCalculation; - } - - public int getWearFactor() { - return wearFactor; - } - - public CurrencyCalculation getCurrencyCalculation() { - return currencyCalculation; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - UniverseSettings that = (UniverseSettings) o; - return getWearFactor() == that.getWearFactor() && Objects.equals(getCurrencyCalculation(), - that.getCurrencyCalculation()); - } - - @Override - public int hashCode() { - return Objects.hash(getWearFactor(), getCurrencyCalculation()); - } -} diff --git a/server/src/main/java/de/pnp/manager/component/upgrade/effect/EquipmentUpgradeEffect.java b/server/src/main/java/de/pnp/manager/component/upgrade/effect/EquipmentUpgradeEffect.java index b29aa652..0236d840 100644 --- a/server/src/main/java/de/pnp/manager/component/upgrade/effect/EquipmentUpgradeEffect.java +++ b/server/src/main/java/de/pnp/manager/component/upgrade/effect/EquipmentUpgradeEffect.java @@ -2,6 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.base.MoreObjects; +import de.pnp.manager.component.ECalculation; import jakarta.validation.constraints.NotNull; import java.util.Objects; @@ -29,10 +30,10 @@ public class EquipmentUpgradeEffect extends UpgradeEffect { */ @NotNull @JsonProperty - private final EUpgradeEffectCalculation calculation; + private final ECalculation calculation; public EquipmentUpgradeEffect(String description, float value, EUpgradeEquipmentManipulator upgradeManipulator, - EUpgradeEffectCalculation calculation) { + ECalculation calculation) { super(description); this.value = value; this.upgradeManipulator = upgradeManipulator; @@ -53,7 +54,7 @@ public float apply(EUpgradeEquipmentManipulator manipulator, float value) { }; } - public EUpgradeEffectCalculation getCalculation() { + public ECalculation getCalculation() { return calculation; } diff --git a/server/src/main/java/de/pnp/manager/server/contoller/ItemStackController.java b/server/src/main/java/de/pnp/manager/server/contoller/ItemStackController.java index 1082fa57..59b60939 100644 --- a/server/src/main/java/de/pnp/manager/server/contoller/ItemStackController.java +++ b/server/src/main/java/de/pnp/manager/server/contoller/ItemStackController.java @@ -2,7 +2,8 @@ import de.pnp.manager.component.inventory.ItemStack; import de.pnp.manager.component.inventory.equipment.interfaces.IDamageableEquipment; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.component.universe.ItemSettings; +import de.pnp.manager.server.database.universe.UniverseSettingsRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -13,7 +14,7 @@ public class ItemStackController { @Autowired - private UniverseRepository universeRepository; + private UniverseSettingsRepository settingsRepository; /** * Wears down the given {@link IDamageableEquipment equipment} by the amount of usages of the equipment. @@ -21,7 +22,7 @@ public class ItemStackController { * @return whether the {@link IDamageableEquipment equipment} is not broken and can be used. */ public boolean applyWearByUsage(String universe, IDamageableEquipment equipment, int usages) { - int wearFactor = universeRepository.getSetting(universe).getWearFactor(); + int wearFactor = settingsRepository.getSettings(universe, ItemSettings.class).getWearFactor(); if (wearFactor < 1) { return true; } diff --git a/server/src/main/java/de/pnp/manager/server/controller/backup/BackupExportController.java b/server/src/main/java/de/pnp/manager/server/controller/backup/BackupExportController.java index ded7d80b..c3eaa033 100644 --- a/server/src/main/java/de/pnp/manager/server/controller/backup/BackupExportController.java +++ b/server/src/main/java/de/pnp/manager/server/controller/backup/BackupExportController.java @@ -7,7 +7,7 @@ import de.pnp.manager.component.universe.Universe; import de.pnp.manager.server.database.DatabaseConstants; import de.pnp.manager.server.database.MongoConfig; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import java.io.IOException; import java.io.OutputStream; import java.util.Collection; diff --git a/server/src/main/java/de/pnp/manager/server/controller/backup/BackupImportController.java b/server/src/main/java/de/pnp/manager/server/controller/backup/BackupImportController.java index e2969f46..971d5889 100644 --- a/server/src/main/java/de/pnp/manager/server/controller/backup/BackupImportController.java +++ b/server/src/main/java/de/pnp/manager/server/controller/backup/BackupImportController.java @@ -9,7 +9,7 @@ import com.mongodb.client.MongoClient; import de.pnp.manager.server.database.DatabaseConstants; import de.pnp.manager.server.database.MongoConfig; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; diff --git a/server/src/main/java/de/pnp/manager/server/database/RepositoryBase.java b/server/src/main/java/de/pnp/manager/server/database/RepositoryBase.java index 2f94164e..8eb913e0 100644 --- a/server/src/main/java/de/pnp/manager/server/database/RepositoryBase.java +++ b/server/src/main/java/de/pnp/manager/server/database/RepositoryBase.java @@ -7,6 +7,7 @@ import de.pnp.manager.component.DatabaseObject; import de.pnp.manager.exception.AlreadyPersistedException; import de.pnp.manager.exception.UniverseNotFoundException; +import de.pnp.manager.server.database.universe.UniverseRepository; import jakarta.validation.ConstraintViolation; import jakarta.validation.ConstraintViolationException; import jakarta.validation.Validation; diff --git a/server/src/main/java/de/pnp/manager/server/database/UniverseRepository.java b/server/src/main/java/de/pnp/manager/server/database/universe/UniverseRepository.java similarity index 84% rename from server/src/main/java/de/pnp/manager/server/database/UniverseRepository.java rename to server/src/main/java/de/pnp/manager/server/database/universe/UniverseRepository.java index ff4629e6..4b576a2f 100644 --- a/server/src/main/java/de/pnp/manager/server/database/UniverseRepository.java +++ b/server/src/main/java/de/pnp/manager/server/database/universe/UniverseRepository.java @@ -1,11 +1,11 @@ -package de.pnp.manager.server.database; +package de.pnp.manager.server.database.universe; import com.google.common.base.Preconditions; import com.mongodb.client.MongoClient; import com.mongodb.client.result.DeleteResult; import de.pnp.manager.component.universe.Universe; -import de.pnp.manager.component.universe.UniverseSettings; -import de.pnp.manager.exception.UniverseNotFoundException; +import de.pnp.manager.server.database.DatabaseConstants; +import de.pnp.manager.server.database.MongoConfig; import java.util.Collection; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; @@ -85,15 +85,4 @@ public boolean remove(String universe) { mongoClient.getDatabase(DatabaseConstants.UNIVERSE_PREFIX + universe).drop(); return true; } - - /** - * Returns the {@link UniverseSettings} of the given universe. - */ - public UniverseSettings getSetting(String universe) { - Optional optUniverse = get(universe); - if (optUniverse.isEmpty()) { - throw new UniverseNotFoundException(universe); - } - return optUniverse.get().getSettings(); - } } diff --git a/server/src/main/java/de/pnp/manager/server/database/universe/UniverseSettingsRepository.java b/server/src/main/java/de/pnp/manager/server/database/universe/UniverseSettingsRepository.java new file mode 100644 index 00000000..a78cdf24 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/server/database/universe/UniverseSettingsRepository.java @@ -0,0 +1,65 @@ +package de.pnp.manager.server.database.universe; + +import de.pnp.manager.component.universe.CharacterSettings; +import de.pnp.manager.component.universe.CurrencySettings; +import de.pnp.manager.component.universe.ItemSettings; +import de.pnp.manager.component.universe.SettingsBase; +import de.pnp.manager.component.universe.Universe; +import de.pnp.manager.exception.UniverseNotFoundException; +import de.pnp.manager.server.database.MongoConfig; +import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.stereotype.Component; + +/** + * Stores the settings of a {@link Universe} + */ +@Component +public class UniverseSettingsRepository { + + /** + * Name of the repository. + */ + public static final String REPOSITORY_NAME = "universe-settings"; + + private static final Map, SettingsBase> DEFAULT_SETTINGS = Map.of( + CharacterSettings.class, CharacterSettings.DEFAULT, + CurrencySettings.class, CurrencySettings.DEFAULT, + ItemSettings.class, ItemSettings.DEFAULT + ); + + @Autowired + private MongoConfig config; + + @Autowired + private UniverseRepository universeRepository; + + /** + * Returns the settings or the default value of the settings. + */ + public S getSettings(String universe, Class clazz) { + S settings = getTemplate(universe).findById(clazz.getName(), clazz, REPOSITORY_NAME); + if (settings == null) { + return clazz.cast(DEFAULT_SETTINGS.get(clazz)); + } + return settings; + } + + /** + * Sets the settings. + */ + public void setSettings(String universe, S settings) { + getTemplate(universe).save(settings, REPOSITORY_NAME); + } + + /** + * Returns the {@link MongoTemplate} to manipulate the database of the given universe. + */ + protected MongoTemplate getTemplate(String universe) { + if (!universeRepository.exists(universe)) { + throw new UniverseNotFoundException(universe); + } + return config.universeMongoTemplate(universe); + } +} \ No newline at end of file diff --git a/server/src/main/java/de/pnp/manager/server/service/UniverseService.java b/server/src/main/java/de/pnp/manager/server/service/universe/UniverseService.java similarity index 98% rename from server/src/main/java/de/pnp/manager/server/service/UniverseService.java rename to server/src/main/java/de/pnp/manager/server/service/universe/UniverseService.java index 962bbb5d..aed1b7ed 100644 --- a/server/src/main/java/de/pnp/manager/server/service/UniverseService.java +++ b/server/src/main/java/de/pnp/manager/server/service/universe/UniverseService.java @@ -1,4 +1,4 @@ -package de.pnp.manager.server.service; +package de.pnp.manager.server.service.universe; import static org.springframework.http.HttpStatus.BAD_REQUEST; import static org.springframework.http.HttpStatus.NOT_FOUND; @@ -10,8 +10,8 @@ import de.pnp.manager.security.UniverseOwner; import de.pnp.manager.security.UniverseRead; import de.pnp.manager.server.contoller.UserController; -import de.pnp.manager.server.database.UniverseRepository; import de.pnp.manager.server.database.UserDetailsRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import io.swagger.v3.oas.annotations.Operation; import jakarta.validation.Valid; import java.util.Collection; diff --git a/server/src/main/java/de/pnp/manager/server/service/universe/UniverseSettingsService.java b/server/src/main/java/de/pnp/manager/server/service/universe/UniverseSettingsService.java new file mode 100644 index 00000000..23c76115 --- /dev/null +++ b/server/src/main/java/de/pnp/manager/server/service/universe/UniverseSettingsService.java @@ -0,0 +1,77 @@ +package de.pnp.manager.server.service.universe; + +import de.pnp.manager.component.universe.CharacterSettings; +import de.pnp.manager.component.universe.CurrencySettings; +import de.pnp.manager.component.universe.ItemSettings; +import de.pnp.manager.security.UniverseOwner; +import de.pnp.manager.security.UniverseRead; +import de.pnp.manager.server.database.universe.UniverseSettingsRepository; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +/** + * Service to access {@link UniverseSettingsRepository}. + */ +@RestController +@Validated +@RequestMapping("/api/universe-settings") +public class UniverseSettingsService { + + @Autowired + private UniverseSettingsRepository settingsRepository; + + @GetMapping("{universe}/character") + @UniverseRead + @Operation(summary = "Get the settings", operationId = "getCharacterSettings") + public CharacterSettings getCharacterSettings(@PathVariable String universe) { + return settingsRepository.getSettings(universe, CharacterSettings.class); + } + + @PutMapping("{universe}/character") + @UniverseOwner + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @Operation(summary = "Update the settings", operationId = "updateCharacterSettings") + public void updateCharacterSettings(@PathVariable String universe, @Valid @RequestBody CharacterSettings settings) { + settingsRepository.setSettings(universe, settings); + } + + @GetMapping("{universe}/currency") + @UniverseRead + @Operation(summary = "Get the settings", operationId = "getCurrencySettings") + public CurrencySettings getCurrencySettings(@PathVariable String universe) { + return settingsRepository.getSettings(universe, CurrencySettings.class); + } + + @PutMapping("{universe}/currency") + @UniverseOwner + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @Operation(summary = "Update the settings", operationId = "updateCharacterSettings") + public void updateCurrencySettings(@PathVariable String universe, @Valid @RequestBody CurrencySettings settings) { + settingsRepository.setSettings(universe, settings); + } + + @GetMapping("{universe}/item") + @UniverseRead + @Operation(summary = "Get the settings", operationId = "getItemSettings") + public ItemSettings getItemSettings(@PathVariable String universe) { + return settingsRepository.getSettings(universe, ItemSettings.class); + } + + @PutMapping("{universe}/item") + @UniverseOwner + @ResponseStatus(value = HttpStatus.NO_CONTENT) + @Operation(summary = "Update the settings", operationId = "updateItemSettings") + public void updateCurrencySettings(@PathVariable String universe, @Valid @RequestBody ItemSettings settings) { + settingsRepository.setSettings(universe, settings); + } +} diff --git a/server/src/test/java/de/pnp/manager/component/inventory/equipment/DefensiveEquipmentTest.java b/server/src/test/java/de/pnp/manager/component/inventory/equipment/DefensiveEquipmentTest.java index f319b542..39de50da 100644 --- a/server/src/test/java/de/pnp/manager/component/inventory/equipment/DefensiveEquipmentTest.java +++ b/server/src/test/java/de/pnp/manager/component/inventory/equipment/DefensiveEquipmentTest.java @@ -4,8 +4,8 @@ import static de.pnp.manager.utils.TestUpgradeBuilder.createUpgrade; import static org.assertj.core.api.Assertions.assertThat; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.item.equipable.Shield; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import org.junit.jupiter.api.Test; @@ -20,13 +20,13 @@ class DefensiveEquipmentTest { @Test void testGetArmor() { - DefensiveEquipment defensiveEquipment = new DefensiveEquipment(1, TEST_SHIELD, 0); + ShieldEquipment defensiveEquipment = new ShieldEquipment(1, TEST_SHIELD, 0); assertThat(defensiveEquipment.getArmor()).isEqualTo(5); assertThat(defensiveEquipment.getMaxArmor()).isEqualTo(5); defensiveEquipment.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.ARMOR, - EUpgradeEffectCalculation.MULTIPLICATIVE)) + ECalculation.MULTIPLICATIVE)) .build()); assertThat(defensiveEquipment.getArmor()).isEqualTo(10); assertThat(defensiveEquipment.getMaxArmor()).isEqualTo(10); @@ -51,12 +51,12 @@ void testGetArmor() { @Test void testGetHit() { - DefensiveEquipment defensiveEquipment = new DefensiveEquipment(1, TEST_SHIELD, 0); + ShieldEquipment defensiveEquipment = new ShieldEquipment(1, TEST_SHIELD, 0); assertThat(defensiveEquipment.getHit()).isEqualTo(2); defensiveEquipment.addUpgrade( createUpgrade().addEffect( - new EquipmentUpgradeEffect("", 1, EUpgradeEquipmentManipulator.HIT, EUpgradeEffectCalculation.ADDITIVE)) + new EquipmentUpgradeEffect("", 1, EUpgradeEquipmentManipulator.HIT, ECalculation.ADDITIVE)) .build()); assertThat(defensiveEquipment.getHit()).isEqualTo(3); @@ -68,12 +68,12 @@ void testGetHit() { @Test void testGetInitiative() { - DefensiveEquipment defensiveEquipment = new DefensiveEquipment(1, TEST_SHIELD, 0); + ShieldEquipment defensiveEquipment = new ShieldEquipment(1, TEST_SHIELD, 0); assertThat(defensiveEquipment.getInitiative()).isEqualTo(1); defensiveEquipment.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", 0.5F, EUpgradeEquipmentManipulator.INITIATIVE, - EUpgradeEffectCalculation.ADDITIVE)) + ECalculation.ADDITIVE)) .build()); assertThat(defensiveEquipment.getInitiative()).isEqualTo(1.5F); @@ -85,12 +85,12 @@ void testGetInitiative() { @Test void testGetWeight() { - DefensiveEquipment defensiveEquipment = new DefensiveEquipment(1, TEST_SHIELD, 0); + ShieldEquipment defensiveEquipment = new ShieldEquipment(1, TEST_SHIELD, 0); assertThat(defensiveEquipment.getWeight()).isEqualTo(3); defensiveEquipment.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.WEIGHT, - EUpgradeEffectCalculation.ADDITIVE)).build()); + ECalculation.ADDITIVE)).build()); assertThat(defensiveEquipment.getWeight()).isEqualTo(5); // Check no other stat got changed due to the upgrade @@ -101,17 +101,17 @@ void testGetWeight() { @Test void testCurseUpgrades() { - DefensiveEquipment defensiveEquipment = new DefensiveEquipment(1, TEST_SHIELD, 0); + ShieldEquipment defensiveEquipment = new ShieldEquipment(1, TEST_SHIELD, 0); assertThat(defensiveEquipment.getArmor()).isEqualTo(5); defensiveEquipment.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", -3, EUpgradeEquipmentManipulator.ARMOR, - EUpgradeEffectCalculation.ADDITIVE)).build()); + ECalculation.ADDITIVE)).build()); assertThat(defensiveEquipment.getArmor()).isEqualTo(2); defensiveEquipment.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", -3, EUpgradeEquipmentManipulator.ARMOR, - EUpgradeEffectCalculation.ADDITIVE)).build()); + ECalculation.ADDITIVE)).build()); assertThat(defensiveEquipment.getArmor()).isEqualTo(0); } } \ No newline at end of file diff --git a/server/src/test/java/de/pnp/manager/component/inventory/equipment/EquipmentTest.java b/server/src/test/java/de/pnp/manager/component/inventory/equipment/EquipmentTest.java index 9ab87e3d..aa5eb5f8 100644 --- a/server/src/test/java/de/pnp/manager/component/inventory/equipment/EquipmentTest.java +++ b/server/src/test/java/de/pnp/manager/component/inventory/equipment/EquipmentTest.java @@ -5,9 +5,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.item.equipable.EquipableItem; import de.pnp.manager.component.upgrade.Upgrade; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import de.pnp.manager.component.upgrade.effect.SimpleUpgradeEffect; @@ -52,7 +52,7 @@ void testUpgradeSlots() { equipment.addUpgrade( createUpgrade().withSlots(1).addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.SLOTS, - EUpgradeEffectCalculation.ADDITIVE)) + ECalculation.ADDITIVE)) .build()); assertThat(equipment.getUpgradeSlots()).isEqualTo(4); assertThat(equipment.getRemainingUpgradeSlots()).isEqualTo(3); @@ -64,16 +64,16 @@ void testUpgradeEffectOrder() { equipment.addUpgrade( createUpgrade().withSlots(0).addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.SLOTS, - EUpgradeEffectCalculation.ADDITIVE)) + ECalculation.ADDITIVE)) .build()); equipment.addUpgrade( createUpgrade().withSlots(0) .addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.SLOTS, - EUpgradeEffectCalculation.MULTIPLICATIVE)) + ECalculation.MULTIPLICATIVE)) .build()); equipment.addUpgrade( createUpgrade().withSlots(0).addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.SLOTS, - EUpgradeEffectCalculation.ADDITIVE)) + ECalculation.ADDITIVE)) .build()); assertThat(equipment.getUpgradeSlots()).isEqualTo(12); diff --git a/server/src/test/java/de/pnp/manager/component/inventory/equipment/WeaponEquipmentTest.java b/server/src/test/java/de/pnp/manager/component/inventory/equipment/WeaponEquipmentTest.java index c76a830e..8bde571e 100644 --- a/server/src/test/java/de/pnp/manager/component/inventory/equipment/WeaponEquipmentTest.java +++ b/server/src/test/java/de/pnp/manager/component/inventory/equipment/WeaponEquipmentTest.java @@ -4,8 +4,8 @@ import static de.pnp.manager.utils.TestUpgradeBuilder.createUpgrade; import static org.assertj.core.api.Assertions.assertThat; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.item.equipable.Weapon; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import org.junit.jupiter.api.Test; @@ -26,7 +26,7 @@ void testGetDamage() { weapon.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", 2, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.MULTIPLICATIVE)) + ECalculation.MULTIPLICATIVE)) .build()); assertThat(weapon.getDamage()).isEqualTo(10); assertThat(weapon.getMaxDamage()).isEqualTo(10); @@ -55,7 +55,7 @@ void testGetHit() { weapon.addUpgrade( createUpgrade().addEffect( - new EquipmentUpgradeEffect("", 1, EUpgradeEquipmentManipulator.HIT, EUpgradeEffectCalculation.ADDITIVE)) + new EquipmentUpgradeEffect("", 1, EUpgradeEquipmentManipulator.HIT, ECalculation.ADDITIVE)) .build()); assertThat(weapon.getHit()).isEqualTo(3); @@ -71,7 +71,7 @@ void testGetInitiative() { weapon.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", 0.5F, EUpgradeEquipmentManipulator.INITIATIVE, - EUpgradeEffectCalculation.ADDITIVE)) + ECalculation.ADDITIVE)) .build()); assertThat(weapon.getInitiative()).isEqualTo(1.5F); @@ -87,12 +87,12 @@ void testCurseUpgrades() { weapon.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", -3, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.ADDITIVE)).build()); + ECalculation.ADDITIVE)).build()); assertThat(weapon.getDamage()).isEqualTo(2); weapon.addUpgrade( createUpgrade().addEffect(new EquipmentUpgradeEffect("", -3, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.ADDITIVE)).build()); + ECalculation.ADDITIVE)).build()); assertThat(weapon.getDamage()).isEqualTo(0); } } \ No newline at end of file diff --git a/server/src/test/java/de/pnp/manager/server/ServerTestBase.java b/server/src/test/java/de/pnp/manager/server/ServerTestBase.java index 9fe886e8..5373e785 100644 --- a/server/src/test/java/de/pnp/manager/server/ServerTestBase.java +++ b/server/src/test/java/de/pnp/manager/server/ServerTestBase.java @@ -15,7 +15,7 @@ import de.pnp.manager.security.SecurityConstants; import de.pnp.manager.server.configurator.EServerTestConfiguration; import de.pnp.manager.server.contoller.UserController; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import de.pnp.manager.utils.TestUtils; import de.pnp.manager.webapp.WebDriver; import java.lang.annotation.Annotation; diff --git a/server/src/test/java/de/pnp/manager/server/UniverseTestBase.java b/server/src/test/java/de/pnp/manager/server/UniverseTestBase.java index c8fbafb9..65317169 100644 --- a/server/src/test/java/de/pnp/manager/server/UniverseTestBase.java +++ b/server/src/test/java/de/pnp/manager/server/UniverseTestBase.java @@ -1,9 +1,9 @@ package de.pnp.manager.server; +import de.pnp.manager.component.universe.SettingsBase; import de.pnp.manager.component.universe.Universe; -import de.pnp.manager.component.universe.UniverseSettings; import de.pnp.manager.server.configurator.EServerTestConfiguration; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.server.database.universe.UniverseSettingsRepository; import org.springframework.beans.factory.annotation.Autowired; /** @@ -13,14 +13,12 @@ public abstract class UniverseTestBase extends ServerTestBase { @Autowired - private UniverseRepository universeRepository; + private UniverseSettingsRepository settingsRepository; /** - * Updates the {@link UniverseSettings} of the {@link Universe test universe}. + * Updates the {@link SettingsBase} of the {@link Universe test universe}. */ - protected void updateUniverseSettings(UniverseSettings settings) { - Universe universe = universeRepository.get(getUniverseName()).orElseThrow(); - universeRepository.update( - new Universe(getUniverseName(), universe.getDisplayName(), "", "", settings)); + protected void updateUniverseSettings(SettingsBase settings) { + settingsRepository.setSettings(getUniverseName(), settings); } } diff --git a/server/src/test/java/de/pnp/manager/server/configurator/SimpleUniverseServerConfiguration.java b/server/src/test/java/de/pnp/manager/server/configurator/SimpleUniverseServerConfiguration.java index 00d90be6..fc7a939e 100644 --- a/server/src/test/java/de/pnp/manager/server/configurator/SimpleUniverseServerConfiguration.java +++ b/server/src/test/java/de/pnp/manager/server/configurator/SimpleUniverseServerConfiguration.java @@ -1,7 +1,7 @@ package de.pnp.manager.server.configurator; import de.pnp.manager.component.universe.Universe; -import de.pnp.manager.server.database.UniverseRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import java.io.File; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; diff --git a/server/src/test/java/de/pnp/manager/server/contoller/ItemStackControllerTest.java b/server/src/test/java/de/pnp/manager/server/contoller/ItemStackControllerTest.java index f475de36..1521764c 100644 --- a/server/src/test/java/de/pnp/manager/server/contoller/ItemStackControllerTest.java +++ b/server/src/test/java/de/pnp/manager/server/contoller/ItemStackControllerTest.java @@ -2,13 +2,11 @@ import static org.assertj.core.api.Assertions.assertThat; -import de.pnp.manager.component.inventory.equipment.DefensiveEquipment; +import de.pnp.manager.component.inventory.equipment.ArmorEquipment; import de.pnp.manager.component.inventory.equipment.WeaponEquipment; -import de.pnp.manager.component.universe.CurrencyCalculation; -import de.pnp.manager.component.universe.UniverseSettings; +import de.pnp.manager.component.universe.ItemSettings; import de.pnp.manager.server.UniverseTestBase; import de.pnp.manager.utils.TestItemBuilder.TestItemBuilderFactory; -import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -25,7 +23,7 @@ class ItemStackControllerTest extends UniverseTestBase { @Test void testApplyWearByUsage() { - updateUniverseSettings(new UniverseSettings(10, new CurrencyCalculation("Copper", "C", List.of()))); + updateUniverseSettings(new ItemSettings(10)); WeaponEquipment equipment = new WeaponEquipment(1, itemBuilder.createItemBuilder(getUniverseName()).withDamage(3).buildWeapon(), 0); @@ -42,9 +40,9 @@ void testApplyWearByUsage() { @Test void testUniverseWithoutWear() { - updateUniverseSettings(new UniverseSettings(-1, new CurrencyCalculation("Copper", "C", List.of()))); + updateUniverseSettings(new ItemSettings(-1)); - DefensiveEquipment equipment = new DefensiveEquipment(1, + ArmorEquipment equipment = new ArmorEquipment(1, itemBuilder.createItemBuilder(getUniverseName()).withArmor(3).buildArmor(), 0); assertThat(controller.applyWearByUsage(getUniverseName(), equipment, 40)).isTrue(); diff --git a/server/src/test/java/de/pnp/manager/server/controller/backup/BackupControllerTest.java b/server/src/test/java/de/pnp/manager/server/controller/backup/BackupControllerTest.java index 12e03223..1e4762a1 100644 --- a/server/src/test/java/de/pnp/manager/server/controller/backup/BackupControllerTest.java +++ b/server/src/test/java/de/pnp/manager/server/controller/backup/BackupControllerTest.java @@ -14,9 +14,9 @@ import de.pnp.manager.server.database.MaterialRepository; import de.pnp.manager.server.database.SpellRepository; import de.pnp.manager.server.database.TalentRepository; -import de.pnp.manager.server.database.UniverseRepository; import de.pnp.manager.server.database.attributes.PrimaryAttributeRepository; import de.pnp.manager.server.database.item.ItemRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; import de.pnp.manager.utils.TestItemBuilder.TestItemBuilderFactory; import java.io.File; import java.io.FileInputStream; diff --git a/server/src/test/java/de/pnp/manager/server/database/universe/UniverseSettingRepositoryTest.java b/server/src/test/java/de/pnp/manager/server/database/universe/UniverseSettingRepositoryTest.java new file mode 100644 index 00000000..1f2bab64 --- /dev/null +++ b/server/src/test/java/de/pnp/manager/server/database/universe/UniverseSettingRepositoryTest.java @@ -0,0 +1,24 @@ +package de.pnp.manager.server.database.universe; + +import static org.assertj.core.api.Assertions.assertThat; + +import de.pnp.manager.component.universe.CharacterSettings; +import de.pnp.manager.server.UniverseTestBase; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +class UniverseSettingRepositoryTest extends UniverseTestBase { + + @Autowired + private UniverseSettingsRepository settingsRepository; + + @Test + void testInsert() { + CharacterSettings settings = new CharacterSettings(7, List.of(), List.of()); + + settingsRepository.setSettings(getUniverseName(), settings); + + assertThat(settingsRepository.getSettings(getUniverseName(), CharacterSettings.class)).isEqualTo(settings); + } +} \ No newline at end of file diff --git a/server/src/test/java/de/pnp/manager/server/database/upgrade/UpgradeRepositoryTest.java b/server/src/test/java/de/pnp/manager/server/database/upgrade/UpgradeRepositoryTest.java index 04b7564b..1859c593 100644 --- a/server/src/test/java/de/pnp/manager/server/database/upgrade/UpgradeRepositoryTest.java +++ b/server/src/test/java/de/pnp/manager/server/database/upgrade/UpgradeRepositoryTest.java @@ -1,9 +1,9 @@ package de.pnp.manager.server.database.upgrade; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.item.ItemType; import de.pnp.manager.component.item.ItemType.ETypeRestriction; import de.pnp.manager.component.upgrade.Upgrade; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import de.pnp.manager.component.upgrade.effect.SimpleUpgradeEffect; @@ -57,9 +57,9 @@ protected List createMultipleObjects() { new Upgrade(null, "Shine", type, 1, 10, List.of( new EquipmentUpgradeEffect("The weapon emits light", 2, EUpgradeEquipmentManipulator.HIT, - EUpgradeEffectCalculation.MULTIPLICATIVE))), + ECalculation.MULTIPLICATIVE))), new Upgrade(null, "Fire", type, 2, 70, List.of(new EquipmentUpgradeEffect("The item is on fire", 1, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.ADDITIVE)))); + ECalculation.ADDITIVE)))); } } \ No newline at end of file diff --git a/server/src/test/java/de/pnp/manager/server/service/UniverseServiceTest.java b/server/src/test/java/de/pnp/manager/server/service/UniverseServiceTest.java index 65deb3f7..e6d1bcd2 100644 --- a/server/src/test/java/de/pnp/manager/server/service/UniverseServiceTest.java +++ b/server/src/test/java/de/pnp/manager/server/service/UniverseServiceTest.java @@ -19,8 +19,9 @@ import de.pnp.manager.server.ServerTestBase; import de.pnp.manager.server.TestServer; import de.pnp.manager.server.configurator.EServerTestConfiguration; -import de.pnp.manager.server.database.UniverseRepository; import de.pnp.manager.server.database.UserDetailsRepository; +import de.pnp.manager.server.database.universe.UniverseRepository; +import de.pnp.manager.server.service.universe.UniverseService; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -311,7 +312,7 @@ private void runUpdateTest() throws Exception { assertThat(getOne(exampleUniverse.getName())).isEqualTo(exampleUniverse); Universe changedUniverse = new Universe(exampleUniverse.getName(), "Other Title", - "", "", exampleUniverse.getSettings()); + "", ""); Universe oldUniverse = update(changedUniverse); assertThat(oldUniverse).isEqualTo(exampleUniverse); assertThat(getOne(exampleUniverse.getName())).isEqualTo(changedUniverse); diff --git a/server/src/test/java/de/pnp/manager/server/service/upgrade/UpgradeServiceTest.java b/server/src/test/java/de/pnp/manager/server/service/upgrade/UpgradeServiceTest.java index 846cfcc5..ad40e0ed 100644 --- a/server/src/test/java/de/pnp/manager/server/service/upgrade/UpgradeServiceTest.java +++ b/server/src/test/java/de/pnp/manager/server/service/upgrade/UpgradeServiceTest.java @@ -1,7 +1,7 @@ package de.pnp.manager.server.service.upgrade; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.upgrade.Upgrade; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import de.pnp.manager.component.upgrade.effect.SimpleUpgradeEffect; @@ -23,11 +23,11 @@ public UpgradeServiceTest(@Autowired UpgradeService upgradeService, @Autowired U protected List createObjects() { return List.of(createUpgrade().withName("A") .addEffect(new EquipmentUpgradeEffect("More Damage", 2, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.ADDITIVE)).build(), + ECalculation.ADDITIVE)).build(), createUpgrade().withName("B") .addEffect(new SimpleUpgradeEffect("Nothing")).build(), createUpgrade().withName("C") .addEffect(new EquipmentUpgradeEffect("Wall", 10, EUpgradeEquipmentManipulator.ARMOR, - EUpgradeEffectCalculation.MULTIPLICATIVE)).build()); + ECalculation.MULTIPLICATIVE)).build()); } } diff --git a/server/src/test/java/de/pnp/manager/webapp/database/UpgradePageTest.java b/server/src/test/java/de/pnp/manager/webapp/database/UpgradePageTest.java index a64d6bc5..2a9f156e 100644 --- a/server/src/test/java/de/pnp/manager/webapp/database/UpgradePageTest.java +++ b/server/src/test/java/de/pnp/manager/webapp/database/UpgradePageTest.java @@ -1,8 +1,8 @@ package de.pnp.manager.webapp.database; +import de.pnp.manager.component.ECalculation; import de.pnp.manager.component.item.ItemType; import de.pnp.manager.component.upgrade.Upgrade; -import de.pnp.manager.component.upgrade.effect.EUpgradeEffectCalculation; import de.pnp.manager.component.upgrade.effect.EUpgradeEquipmentManipulator; import de.pnp.manager.component.upgrade.effect.EquipmentUpgradeEffect; import de.pnp.manager.component.upgrade.effect.SimpleUpgradeEffect; @@ -61,7 +61,7 @@ protected List getExpectedErrorFields() { protected Upgrade getCorrectObject() { return new Upgrade(null, "Shine 100", getItemType("Weapon"), 1, 10, List.of(new EquipmentUpgradeEffect("+100 Damage", 1, EUpgradeEquipmentManipulator.DAMAGE, - EUpgradeEffectCalculation.ADDITIVE), + ECalculation.ADDITIVE), new SimpleUpgradeEffect("It shines"))); } diff --git a/webapp/src/api/api.ts b/webapp/src/api/api.ts index 53ded00d..fa396d3c 100644 --- a/webapp/src/api/api.ts +++ b/webapp/src/api/api.ts @@ -165,6 +165,25 @@ export interface ArmorAllOf { */ 'weight'?: number; } +/** + * + * @export + * @interface ArmorDefinition + */ +export interface ArmorDefinition { + /** + * + * @type {string} + * @memberof ArmorDefinition + */ + 'name': string; + /** + * + * @type {ItemType} + * @memberof ArmorDefinition + */ + 'type': ItemType; +} /** * * @export @@ -203,6 +222,31 @@ export interface CharacterResourceUsageAllOf { */ 'resource'?: SecondaryAttribute; } +/** + * + * @export + * @interface CharacterSettings + */ +export interface CharacterSettings { + /** + * + * @type {Array} + * @memberof CharacterSettings + */ + 'armorDefinitions': Array; + /** + * + * @type {Array} + * @memberof CharacterSettings + */ + 'jewelleryDefinitions': Array; + /** + * + * @type {number} + * @memberof CharacterSettings + */ + 'numberOfHandheld'?: number; +} /** * * @export @@ -261,52 +305,52 @@ export type CraftingRecipeMaterialsInner = CharacterResourceUsage | ItemUsage | /** * * @export - * @interface CurrencyCalculation + * @interface CurrencyCalculationEntry */ -export interface CurrencyCalculation { +export interface CurrencyCalculationEntry { /** * * @type {string} - * @memberof CurrencyCalculation + * @memberof CurrencyCalculationEntry */ - 'baseCurrency': string; + 'currency': string; /** * * @type {string} - * @memberof CurrencyCalculation + * @memberof CurrencyCalculationEntry */ - 'baseCurrencyShortForm': string; + 'currencyShortForm': string; /** * - * @type {Array} - * @memberof CurrencyCalculation + * @type {number} + * @memberof CurrencyCalculationEntry */ - 'calculationEntries': Array; + 'factor'?: number; } /** * * @export - * @interface CurrencyCalculationEntry + * @interface CurrencySettings */ -export interface CurrencyCalculationEntry { +export interface CurrencySettings { /** * * @type {string} - * @memberof CurrencyCalculationEntry + * @memberof CurrencySettings */ - 'currency': string; + 'baseCurrency': string; /** * * @type {string} - * @memberof CurrencyCalculationEntry + * @memberof CurrencySettings */ - 'currencyShortForm': string; + 'baseCurrencyShortForm': string; /** * - * @type {number} - * @memberof CurrencyCalculationEntry + * @type {Array} + * @memberof CurrencySettings */ - 'factor'?: number; + 'calculationEntries': Array; } /** * @@ -314,16 +358,12 @@ export interface CurrencyCalculationEntry { * @enum {string} */ -export const ERarity = { - Common: 'COMMON', - Uncommon: 'UNCOMMON', - Rare: 'RARE', - Epic: 'EPIC', - Legendary: 'LEGENDARY', - Godlike: 'GODLIKE' +export const ECalculation = { + Additive: 'ADDITIVE', + Multiplicative: 'MULTIPLICATIVE' } as const; -export type ERarity = typeof ERarity[keyof typeof ERarity]; +export type ECalculation = typeof ECalculation[keyof typeof ECalculation]; /** @@ -332,12 +372,16 @@ export type ERarity = typeof ERarity[keyof typeof ERarity]; * @enum {string} */ -export const EUpgradeEffectCalculation = { - Additive: 'ADDITIVE', - Multiplicative: 'MULTIPLICATIVE' +export const ERarity = { + Common: 'COMMON', + Uncommon: 'UNCOMMON', + Rare: 'RARE', + Epic: 'EPIC', + Legendary: 'LEGENDARY', + Godlike: 'GODLIKE' } as const; -export type EUpgradeEffectCalculation = typeof EUpgradeEffectCalculation[keyof typeof EUpgradeEffectCalculation]; +export type ERarity = typeof ERarity[keyof typeof ERarity]; /** @@ -373,10 +417,10 @@ export interface EquipmentUpgradeEffect { 'description': string; /** * - * @type {EUpgradeEffectCalculation} + * @type {ECalculation} * @memberof EquipmentUpgradeEffect */ - 'calculation': EUpgradeEffectCalculation; + 'calculation': ECalculation; /** * * @type {EUpgradeEquipmentManipulator} @@ -400,10 +444,10 @@ export interface EquipmentUpgradeEffect { export interface EquipmentUpgradeEffectAllOf { /** * - * @type {EUpgradeEffectCalculation} + * @type {ECalculation} * @memberof EquipmentUpgradeEffectAllOf */ - 'calculation'?: EUpgradeEffectCalculation; + 'calculation'?: ECalculation; /** * * @type {EUpgradeEquipmentManipulator} @@ -607,6 +651,19 @@ export interface Item { } +/** + * + * @export + * @interface ItemSettings + */ +export interface ItemSettings { + /** + * + * @type {number} + * @memberof ItemSettings + */ + 'wearFactor': number; +} /** * * @export @@ -1417,12 +1474,6 @@ export interface Universe { * @memberof Universe */ 'name': string; - /** - * - * @type {UniverseSettings} - * @memberof Universe - */ - 'settings': UniverseSettings; /** * * @type {string} @@ -1430,25 +1481,6 @@ export interface Universe { */ 'shortDescription': string; } -/** - * - * @export - * @interface UniverseSettings - */ -export interface UniverseSettings { - /** - * - * @type {CurrencyCalculation} - * @memberof UniverseSettings - */ - 'currencyCalculation': CurrencyCalculation; - /** - * - * @type {number} - * @memberof UniverseSettings - */ - 'wearFactor': number; -} /** * * @export @@ -7529,6 +7561,473 @@ export class UniverseServiceApi extends BaseAPI { } +/** + * UniverseSettingsServiceApi - axios parameter creator + * @export + */ +export const UniverseSettingsServiceApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCharacterSettings: async (universe: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('getCharacterSettings', 'universe', universe) + const localVarPath = `/api/universe-settings/{universe}/character` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCurrencySettings: async (universe: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('getCurrencySettings', 'universe', universe) + const localVarPath = `/api/universe-settings/{universe}/currency` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getItemSettings: async (universe: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('getItemSettings', 'universe', universe) + const localVarPath = `/api/universe-settings/{universe}/item` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CurrencySettings} currencySettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCharacterSettings: async (universe: string, currencySettings: CurrencySettings, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('updateCharacterSettings', 'universe', universe) + // verify required parameter 'currencySettings' is not null or undefined + assertParamExists('updateCharacterSettings', 'currencySettings', currencySettings) + const localVarPath = `/api/universe-settings/{universe}/currency` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(currencySettings, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CharacterSettings} characterSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCharacterSettings1: async (universe: string, characterSettings: CharacterSettings, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('updateCharacterSettings1', 'universe', universe) + // verify required parameter 'characterSettings' is not null or undefined + assertParamExists('updateCharacterSettings1', 'characterSettings', characterSettings) + const localVarPath = `/api/universe-settings/{universe}/character` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(characterSettings, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {ItemSettings} itemSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateItemSettings: async (universe: string, itemSettings: ItemSettings, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'universe' is not null or undefined + assertParamExists('updateItemSettings', 'universe', universe) + // verify required parameter 'itemSettings' is not null or undefined + assertParamExists('updateItemSettings', 'itemSettings', itemSettings) + const localVarPath = `/api/universe-settings/{universe}/item` + .replace(`{${"universe"}}`, encodeURIComponent(String(universe))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'PUT', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(itemSettings, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * UniverseSettingsServiceApi - functional programming interface + * @export + */ +export const UniverseSettingsServiceApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = UniverseSettingsServiceApiAxiosParamCreator(configuration) + return { + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCharacterSettings(universe: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCharacterSettings(universe, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getCurrencySettings(universe: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getCurrencySettings(universe, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getItemSettings(universe: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getItemSettings(universe, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CurrencySettings} currencySettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateCharacterSettings(universe: string, currencySettings: CurrencySettings, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateCharacterSettings(universe, currencySettings, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CharacterSettings} characterSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateCharacterSettings1(universe: string, characterSettings: CharacterSettings, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateCharacterSettings1(universe, characterSettings, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {ItemSettings} itemSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async updateItemSettings(universe: string, itemSettings: ItemSettings, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.updateItemSettings(universe, itemSettings, options); + return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); + }, + } +}; + +/** + * UniverseSettingsServiceApi - factory interface + * @export + */ +export const UniverseSettingsServiceApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = UniverseSettingsServiceApiFp(configuration) + return { + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCharacterSettings(universe: string, options?: any): AxiosPromise { + return localVarFp.getCharacterSettings(universe, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getCurrencySettings(universe: string, options?: any): AxiosPromise { + return localVarFp.getCurrencySettings(universe, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getItemSettings(universe: string, options?: any): AxiosPromise { + return localVarFp.getItemSettings(universe, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CurrencySettings} currencySettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCharacterSettings(universe: string, currencySettings: CurrencySettings, options?: any): AxiosPromise { + return localVarFp.updateCharacterSettings(universe, currencySettings, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CharacterSettings} characterSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateCharacterSettings1(universe: string, characterSettings: CharacterSettings, options?: any): AxiosPromise { + return localVarFp.updateCharacterSettings1(universe, characterSettings, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary Update the settings + * @param {string} universe + * @param {ItemSettings} itemSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + updateItemSettings(universe: string, itemSettings: ItemSettings, options?: any): AxiosPromise { + return localVarFp.updateItemSettings(universe, itemSettings, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * UniverseSettingsServiceApi - object-oriented interface + * @export + * @class UniverseSettingsServiceApi + * @extends {BaseAPI} + */ +export class UniverseSettingsServiceApi extends BaseAPI { + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public getCharacterSettings(universe: string, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).getCharacterSettings(universe, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public getCurrencySettings(universe: string, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).getCurrencySettings(universe, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Get the settings + * @param {string} universe + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public getItemSettings(universe: string, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).getItemSettings(universe, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CurrencySettings} currencySettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public updateCharacterSettings(universe: string, currencySettings: CurrencySettings, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).updateCharacterSettings(universe, currencySettings, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update the settings + * @param {string} universe + * @param {CharacterSettings} characterSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public updateCharacterSettings1(universe: string, characterSettings: CharacterSettings, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).updateCharacterSettings1(universe, characterSettings, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * + * @summary Update the settings + * @param {string} universe + * @param {ItemSettings} itemSettings + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof UniverseSettingsServiceApi + */ + public updateItemSettings(universe: string, itemSettings: ItemSettings, options?: AxiosRequestConfig) { + return UniverseSettingsServiceApiFp(this.configuration).updateItemSettings(universe, itemSettings, options).then((request) => request(this.axios, this.basePath)); + } +} + + /** * UpgradeRecipeServiceApi - axios parameter creator * @export diff --git a/webapp/src/components/PageBase.tsx b/webapp/src/components/PageBase.tsx index bd5dc6bb..709997ed 100644 --- a/webapp/src/components/PageBase.tsx +++ b/webapp/src/components/PageBase.tsx @@ -1,4 +1,4 @@ -import { AuthenticationServiceApi, PnPUser, PnPUserPreference, Universe, UniverseServiceApi, UserServiceApi } from '../api'; +import { AuthenticationServiceApi, CurrencySettings, PnPUser, PnPUserPreference, Universe, UniverseServiceApi, UniverseSettingsServiceApi, UserServiceApi } from '../api'; import { Outlet, useOutletContext, useSearchParams } from 'react-router-dom'; import { useEffect, useState } from 'react'; import { Box, CssBaseline, ThemeProvider, Toolbar } from '@mui/material'; @@ -14,10 +14,11 @@ import i18n from '../i18n'; import { IoSettingsSharp } from 'react-icons/io5'; import { HiUserCircle } from 'react-icons/hi2'; -type UniverseContext = { universes: Universe[], activeUniverse: Universe, setActiveUniverse: (activeUniverse: Universe) => void, fetchUniverses: () => void; }; +type UniverseContext = { universes: Universe[], activeUniverse: Universe, setActiveUniverse: (activeUniverse: Universe) => void, fetchUniverses: () => void, currencySettings: CurrencySettings; }; type UserContext = { userPermissions: UserPermissions, userPreferences: PnPUserPreference, user: PnPUser, refreshUser: () => void; }; const UNIVERSE_API = new UniverseServiceApi(API_CONFIGURATION); +const SETTINGS_API = new UniverseSettingsServiceApi(API_CONFIGURATION); const AUTHENTICATION_API = new AuthenticationServiceApi(API_CONFIGURATION); const USER_API = new UserServiceApi(API_CONFIGURATION); @@ -25,6 +26,7 @@ function PageBase() { const [universes, setUniverses] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); const [activeUniverse, setActiveUniverse] = useState(null); + const [currencySettings, setCurrencySettings] = useState(null); const [username, setUsername] = useState(null); const [user, setUser] = useState(null); const [userPreferences, setUserPreferences] = useState(null); @@ -79,10 +81,12 @@ function PageBase() { }, []); useEffect(() => { - if (activeUniverse) { - searchParams.set("universe", activeUniverse.name); - setSearchParams(searchParams); + if (!activeUniverse) { + return; } + searchParams.set("universe", activeUniverse.name); + setSearchParams(searchParams); + SETTINGS_API.getCurrencySettings(activeUniverse.name).then(response => setCurrencySettings(response.data)); }, [activeUniverse]); useEffect(() => { @@ -127,6 +131,7 @@ function PageBase() { activeUniverse: activeUniverse, setActiveUniverse: setActiveUniverse, fetchUniverses: fetchUniverses, + currencySettings: currencySettings, userPermissions: userPermissions, userPreferences: userPreferences, user: user, diff --git a/webapp/src/components/Utils.tsx b/webapp/src/components/Utils.tsx index 0bdb8285..5ea92979 100644 --- a/webapp/src/components/Utils.tsx +++ b/webapp/src/components/Utils.tsx @@ -1,4 +1,4 @@ -import { Universe } from "../api"; +import { CurrencySettings, Universe } from "../api"; /** Helper class to calculate human readable currency */ interface CurrencyCalculationStep { @@ -13,26 +13,24 @@ interface CurrencyCalculationStep { * * For example as 2G 11S 9K */ -export function currencyToHumanReadable(universe: Universe, amount: number): string { +export function currencyToHumanReadable(currencySettings: CurrencySettings, amount: number): string { if (Number.isNaN(amount)) { return ""; } - if (universe === null) { + if (currencySettings === null) { return amount.toString(); } - const currencyCalculation = universe.settings.currencyCalculation; - if (amount <= 0) { - return "0" + currencyCalculation.baseCurrencyShortForm; + return "0" + currencySettings.baseCurrencyShortForm; } - if (currencyCalculation.calculationEntries.length === 0) { - return amount + currencyCalculation.baseCurrencyShortForm; + if (currencySettings.calculationEntries.length === 0) { + return amount + currencySettings.baseCurrencyShortForm; } - const calcuationSteps: CurrencyCalculationStep[] = [{ shortForm: currencyCalculation.baseCurrencyShortForm, factor: 1 }]; + const calcuationSteps: CurrencyCalculationStep[] = [{ shortForm: currencySettings.baseCurrencyShortForm, factor: 1 }]; - for (const entry of currencyCalculation.calculationEntries) { + for (const entry of currencySettings.calculationEntries) { calcuationSteps.unshift({ shortForm: entry.currencyShortForm, factor: calcuationSteps[0].factor * (entry.factor ?? 1) diff --git a/webapp/src/components/database/DatabaseObjectDialog.tsx b/webapp/src/components/database/DatabaseObjectDialog.tsx index a4a0464a..e4e389e5 100644 --- a/webapp/src/components/database/DatabaseObjectDialog.tsx +++ b/webapp/src/components/database/DatabaseObjectDialog.tsx @@ -135,7 +135,7 @@ function Field({ setDatabaseObject }: FieldProps): React.JSX.Element { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); const fullId = (field.fullId ?? field.fieldId) as string; @@ -212,7 +212,7 @@ function Field({ label={t("resultingPrice")} data-testid="resultingPrice" variant="outlined" - value={currencyToHumanReadable(activeUniverse, Number(databaseObject?.[field.fieldId]))} + value={currencyToHumanReadable(currencySettings, Number(databaseObject?.[field.fieldId]))} InputProps={{ readOnly: true }} fullWidth /> diff --git a/webapp/src/components/items/ItemManipulation.tsx b/webapp/src/components/items/ItemManipulation.tsx index 60a78a65..74afe5f5 100644 --- a/webapp/src/components/items/ItemManipulation.tsx +++ b/webapp/src/components/items/ItemManipulation.tsx @@ -133,7 +133,7 @@ interface ItemManipulationProps { export function ItemManipulation(props: ItemManipulationProps) { const { itemTypes, materials, itemClass, errors, item, setItem } = props; const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); const [name, setName] = useState(item?.name ?? ""); const [type, setType] = useState(item?.type ?? null); @@ -249,7 +249,7 @@ export function ItemManipulation(props: ItemManipulationProps) { - + {itemClass === "Item" && diff --git a/webapp/src/pages/items/armor.tsx b/webapp/src/pages/items/armor.tsx index f9c1343f..ac10b856 100644 --- a/webapp/src/pages/items/armor.tsx +++ b/webapp/src/pages/items/armor.tsx @@ -6,7 +6,7 @@ import { ItemBasePage } from '../../components/items/ItemBasePage'; const ArmorPage = () => { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); return item.name }, @@ -21,7 +21,7 @@ const ArmorPage = () => { { label: t("description"), id: "description", getter: item => item.description }, { label: t("upgradeSlots"), id: "upgradeSlots", getter: item => item.upgradeSlots, numeric: true }, { label: t("requirement"), id: "requirement", getter: item => item.requirement }, - { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(activeUniverse, item.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(currencySettings, item.vendorPrice) }, { label: t("item:minStackSize"), id: "minimumStackSize", getter: item => item.minimumStackSize, numeric: true, defaultVisible: false }, { label: t("item:maxStackSize"), id: "maximumStackSize", getter: item => item.maximumStackSize, numeric: true, defaultVisible: false }, { label: t("note"), id: "note", getter: item => item.note, defaultVisible: false } diff --git a/webapp/src/pages/items/items.tsx b/webapp/src/pages/items/items.tsx index 7eafcb77..5d1aee8b 100644 --- a/webapp/src/pages/items/items.tsx +++ b/webapp/src/pages/items/items.tsx @@ -6,7 +6,7 @@ import { ItemBasePage } from '../../components/items/ItemBasePage'; const ItemPage = () => { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); return item.name }, @@ -17,7 +17,7 @@ const ItemPage = () => { { label: t("effect"), id: "effect", getter: item => item.effect }, { label: t("description"), id: "description", getter: item => item.description }, { label: t("requirement"), id: "requirement", getter: item => item.requirement }, - { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(activeUniverse, item.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(currencySettings, item.vendorPrice) }, { label: t("item:minStackSize"), id: "minimumStackSize", getter: item => item.minimumStackSize, numeric: true, defaultVisible: false }, { label: t("item:maxStackSize"), id: "maximumStackSize", getter: item => item.maximumStackSize, numeric: true, defaultVisible: false }, { label: t("note"), id: "note", getter: item => item.note, defaultVisible: false } diff --git a/webapp/src/pages/items/jewellery.tsx b/webapp/src/pages/items/jewellery.tsx index 7b4987be..3265c264 100644 --- a/webapp/src/pages/items/jewellery.tsx +++ b/webapp/src/pages/items/jewellery.tsx @@ -6,7 +6,7 @@ import { ItemBasePage } from '../../components/items/ItemBasePage'; const JewelleryPage = () => { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); return item.name }, @@ -19,7 +19,7 @@ const JewelleryPage = () => { { label: t("description"), id: "description", getter: item => item.description }, { label: t("upgradeSlots"), id: "upgradeSlots", getter: item => item.upgradeSlots, numeric: true }, { label: t("requirement"), id: "requirement", getter: item => item.requirement }, - { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(activeUniverse, item.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(currencySettings, item.vendorPrice) }, { label: t("item:minStackSize"), id: "minimumStackSize", getter: item => item.minimumStackSize, numeric: true, defaultVisible: false }, { label: t("item:maxStackSize"), id: "maximumStackSize", getter: item => item.maximumStackSize, numeric: true, defaultVisible: false }, { label: t("note"), id: "note", getter: item => item.note, defaultVisible: false } diff --git a/webapp/src/pages/items/shields.tsx b/webapp/src/pages/items/shields.tsx index f260635b..b738ada7 100644 --- a/webapp/src/pages/items/shields.tsx +++ b/webapp/src/pages/items/shields.tsx @@ -6,7 +6,7 @@ import { ItemBasePage } from '../../components/items/ItemBasePage'; const ShieldPage = () => { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); return item.name }, @@ -23,7 +23,7 @@ const ShieldPage = () => { { label: t("description"), id: "description", getter: item => item.description }, { label: t("upgradeSlots"), id: "upgradeSlots", getter: item => item.upgradeSlots, numeric: true }, { label: t("requirement"), id: "requirement", getter: item => item.requirement }, - { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(activeUniverse, item.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(currencySettings, item.vendorPrice) }, { label: t("item:minStackSize"), id: "minimumStackSize", getter: item => item.minimumStackSize, numeric: true, defaultVisible: false }, { label: t("item:maxStackSize"), id: "maximumStackSize", getter: item => item.maximumStackSize, numeric: true, defaultVisible: false }, { label: t("note"), id: "note", getter: item => item.note, defaultVisible: false } diff --git a/webapp/src/pages/items/upgrades.tsx b/webapp/src/pages/items/upgrades.tsx index af9a7f3d..a62339ba 100644 --- a/webapp/src/pages/items/upgrades.tsx +++ b/webapp/src/pages/items/upgrades.tsx @@ -1,6 +1,6 @@ import { useTranslation } from "react-i18next"; -import { EUpgradeEffectCalculation, EUpgradeEquipmentManipulator, ItemType, ItemTypeServiceApi, Upgrade, UpgradeServiceApi } from "../../api"; +import { ECalculation, EUpgradeEquipmentManipulator, ItemType, ItemTypeServiceApi, Upgrade, UpgradeServiceApi } from "../../api"; import { API_CONFIGURATION } from "../../components/Constants"; import { OverviewBasePage } from "../../components/database/OverviewBasePage"; import { useEffect, useState } from "react"; @@ -13,7 +13,7 @@ const UPGRADE_API = new UpgradeServiceApi(API_CONFIGURATION); /** Page to give an overview over all upgrades */ export function UpgradePage() { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { activeUniverse, currencySettings } = getUniverseContext(); const [itemTypes, setItemTypes] = useState([]); @@ -29,7 +29,7 @@ export function UpgradePage() { { label: t("upgrade:effects"), id: "effects", getter: upgrade => upgrade.effects.map(effect => effect.description).join(", ") }, { label: t("upgrade:target"), id: "target", getter: upgrade => upgrade.target.name }, { label: t("upgrade:necessary-slots"), id: "slots", getter: upgrade => upgrade.slots, numeric: true }, - { label: t("price"), id: "vendorPrice", getter: upgrade => currencyToHumanReadable(activeUniverse, upgrade.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: upgrade => currencyToHumanReadable(currencySettings, upgrade.vendorPrice) }, ]} fields={[ { fieldId: "name", label: t("name"), fieldType: "STRING" }, @@ -58,7 +58,7 @@ export function UpgradePage() { fieldId: "effect-row", label: "", fieldType: "STACK", subFields: [ { fieldId: "calculation", label: t("upgrade:calculation"), fieldType: "ENUM", - dependency: Object.values(EUpgradeEffectCalculation).map(manipulator => { + dependency: Object.values(ECalculation).map(manipulator => { return { key: manipulator, content: manipulator, label: t("upgrade:" + manipulator.toLowerCase()) }; }) }, diff --git a/webapp/src/pages/items/weapons.tsx b/webapp/src/pages/items/weapons.tsx index e1969abf..6bb06143 100644 --- a/webapp/src/pages/items/weapons.tsx +++ b/webapp/src/pages/items/weapons.tsx @@ -6,7 +6,7 @@ import { ItemBasePage } from '../../components/items/ItemBasePage'; const WeaponPage = () => { const { t } = useTranslation(); - const { activeUniverse } = getUniverseContext(); + const { currencySettings } = getUniverseContext(); return item.name }, @@ -23,7 +23,7 @@ const WeaponPage = () => { { label: t("description"), id: "description", getter: item => item.description }, { label: t("upgradeSlots"), id: "upgradeSlots", getter: item => item.upgradeSlots, numeric: true }, { label: t("requirement"), id: "requirement", getter: item => item.requirement }, - { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(activeUniverse, item.vendorPrice) }, + { label: t("price"), id: "vendorPrice", getter: item => currencyToHumanReadable(currencySettings, item.vendorPrice) }, { label: t("item:minStackSize"), id: "minimumStackSize", getter: item => item.minimumStackSize, numeric: true, defaultVisible: false }, { label: t("item:maxStackSize"), id: "maximumStackSize", getter: item => item.maximumStackSize, numeric: true, defaultVisible: false }, { label: t("note"), id: "note", getter: item => item.note, defaultVisible: false }