From d28e64a800a075154cbad47503f69769c670d6f7 Mon Sep 17 00:00:00 2001 From: Martin Janiczek Date: Tue, 1 Oct 2024 09:04:24 +0200 Subject: [PATCH] Equipped left/right hand --- .vscode/settings.json | 5 +- Makefile | 4 - src/Admin.elm | 45 ++--- src/Backend.elm | 82 ++++++++- src/Calculator/Meta/Individual.elm | 69 +++++++- src/Data/Auth.elm | 11 +- src/Data/Barter.elm | 46 +++-- src/Data/Fight.elm | 119 +------------ src/Data/Fight/View.elm | 1 - src/Data/Item.elm | 32 +++- src/Data/Message.elm | 26 +-- src/Data/Player.elm | 270 ++--------------------------- src/Data/Player/SPlayer.elm | 134 ++++++++------ src/Data/Vendor.elm | 17 +- src/Data/World.elm | 119 +------------ src/DummyMain.elm | 12 -- src/Frontend.elm | 74 +++++--- src/Types.elm | 12 +- 18 files changed, 378 insertions(+), 700 deletions(-) delete mode 100644 src/DummyMain.elm diff --git a/.vscode/settings.json b/.vscode/settings.json index 4474d59b..b8dc2009 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,8 @@ "\\bclassList[\\s\\[\\(]+\"[^\"]*\",\\s[^\\)]+\\)[\\s\\[\\(,]+\"[^\"]*\",\\s[^\\)]+\\)[\\s\\[\\(,]+\"([^\"]*)\"", ], "elmLS.elmPath": "lamdera", - "elmLS.elmReviewDiagnostics": "warning" + "elmLS.elmReviewDiagnostics": "warning", + "files.exclude": { + "src/Evergreen": true + } } \ No newline at end of file diff --git a/Makefile b/Makefile index 88dc56cd..267b1038 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,6 @@ SEED ?= "$$RANDOM" FUZZ ?= "100" -.PHONY: watch -watch: - elmid --watched-folder=src src/DummyMain.elm - .PHONY: start start: lamdera live diff --git a/src/Admin.elm b/src/Admin.elm index 8b7b5795..22bb753d 100644 --- a/src/Admin.elm +++ b/src/Admin.elm @@ -18,7 +18,6 @@ import Dict import Dict.ExtraExtra as Dict import Json.Decode as JD exposing (Decoder) import Json.Encode as JE -import Logic import Queue import Random import Set.ExtraExtra as Set @@ -35,30 +34,12 @@ encodeBackendModel model = backendModelDecoder : Random.Seed -> Decoder BackendModel backendModelDecoder seed = JD.oneOf - [ backendModelDecoderV2 seed - , backendModelDecoderV1 seed + [ backendModelDecoderV1 seed ] backendModelDecoderV1 : Random.Seed -> Decoder BackendModel backendModelDecoderV1 seed = - JD.map - (\world -> - { worlds = Dict.singleton Logic.mainWorldName world - , loggedInPlayers = BiDict.empty - , time = Time.millisToPosix 0 - , adminLoggedIn = Nothing - , lastTenToBackendMsgs = Queue.empty - , randomSeed = seed - , playerDataCache = Dict.empty - } - ) - World.decoder - - -backendModelDecoderV2 : Random.Seed -> Decoder BackendModel -backendModelDecoderV2 seed = - -- adds support for multiple worlds JD.map (\worlds -> { worlds = worlds @@ -118,9 +99,21 @@ encodeToBackendMsg msg = JE.object [ ( "type", JE.string "Wander" ) ] - EquipItem itemId -> + EquipArmor itemId -> JE.object - [ ( "type", JE.string "EquipItem" ) + [ ( "type", JE.string "EquipArmor" ) + , ( "itemId", JE.int itemId ) + ] + + EquipLeftHand itemId -> + JE.object + [ ( "type", JE.string "EquipLeftHand" ) + , ( "itemId", JE.int itemId ) + ] + + EquipRightHand itemId -> + JE.object + [ ( "type", JE.string "EquipRightHand" ) , ( "itemId", JE.int itemId ) ] @@ -128,6 +121,14 @@ encodeToBackendMsg msg = JE.object [ ( "type", JE.string "UnequipArmor" ) ] + UnequipLeftHand -> + JE.object + [ ( "type", JE.string "UnequipLeftHand" ) ] + + UnequipRightHand -> + JE.object + [ ( "type", JE.string "UnequipRightHand" ) ] + SetFightStrategy ( strategy, text ) -> JE.object [ ( "type", JE.string "SetFightStrategy" ) diff --git a/src/Backend.elm b/src/Backend.elm index 02e7a0f0..c236c91f 100644 --- a/src/Backend.elm +++ b/src/Backend.elm @@ -60,7 +60,7 @@ import Queue import Random exposing (Generator) import Random.List import SeqDict exposing (SeqDict) -import SeqSet exposing (SeqSet) +import SeqSet import Set exposing (Set) import Task import Time exposing (Posix) @@ -854,12 +854,24 @@ updateFromFrontend sessionId clientId msg model = Wander -> withLoggedInCreatedPlayer wander - EquipItem itemId -> - withLoggedInCreatedPlayer <| equipItem itemId + EquipArmor itemId -> + withLoggedInCreatedPlayer <| equipArmor itemId + + EquipLeftHand itemId -> + withLoggedInCreatedPlayer <| equipLeftHand itemId + + EquipRightHand itemId -> + withLoggedInCreatedPlayer <| equipRightHand itemId UnequipArmor -> withLoggedInCreatedPlayer unequipArmor + UnequipLeftHand -> + withLoggedInCreatedPlayer unequipLeftHand + + UnequipRightHand -> + withLoggedInCreatedPlayer unequipRightHand + SetFightStrategy ( strategy, text ) -> withLoggedInCreatedPlayer <| setFightStrategy ( strategy, text ) @@ -1404,16 +1416,48 @@ healMe clientId _ worldName player model = |> sendCurrentWorld worldName player.name clientId -equipItem : Item.Id -> ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) -equipItem itemId clientId _ worldName player model = +equipArmor : Item.Id -> ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) +equipArmor itemId clientId _ worldName player model = + case Dict.get itemId player.items of + Nothing -> + ( model, Cmd.none ) + + Just item -> + if Item.isArmor item.kind then + model + |> updatePlayer worldName player.name (SPlayer.equipArmor item) + |> sendCurrentWorld worldName player.name clientId + + else + ( model, Cmd.none ) + + +equipLeftHand : Item.Id -> ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) +equipLeftHand itemId clientId _ worldName player model = + case Dict.get itemId player.items of + Nothing -> + ( model, Cmd.none ) + + Just item -> + if Item.isHandEquippable item.kind then + model + |> updatePlayer worldName player.name (SPlayer.equipLeftHand item) + |> sendCurrentWorld worldName player.name clientId + + else + ( model, Cmd.none ) + + +equipRightHand : Item.Id -> ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) +equipRightHand itemId clientId _ worldName player model = case Dict.get itemId player.items of Nothing -> ( model, Cmd.none ) Just item -> - if Item.isEquippable item.kind then + if Item.isHandEquippable item.kind then model - |> updatePlayer worldName player.name (SPlayer.equipItem item) + |> updatePlayer worldName player.name (SPlayer.equipRightHand item) |> sendCurrentWorld worldName player.name clientId else @@ -1512,6 +1556,30 @@ unequipArmor clientId _ worldName player model = |> sendCurrentWorld worldName player.name clientId +unequipLeftHand : ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) +unequipLeftHand clientId _ worldName player model = + case player.equippedLeftHand of + Nothing -> + ( model, Cmd.none ) + + Just _ -> + model + |> updatePlayer worldName player.name SPlayer.unequipLeftHand + |> sendCurrentWorld worldName player.name clientId + + +unequipRightHand : ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) +unequipRightHand clientId _ worldName player model = + case player.equippedRightHand of + Nothing -> + ( model, Cmd.none ) + + Just _ -> + model + |> updatePlayer worldName player.name SPlayer.unequipRightHand + |> sendCurrentWorld worldName player.name clientId + + wander : ClientId -> World -> World.Name -> SPlayer -> Model -> ( Model, Cmd BackendMsg ) wander clientId world worldName player model = let diff --git a/src/Calculator/Meta/Individual.elm b/src/Calculator/Meta/Individual.elm index 9c6ad894..404a5253 100644 --- a/src/Calculator/Meta/Individual.elm +++ b/src/Calculator/Meta/Individual.elm @@ -71,6 +71,15 @@ healingItemKindGenerator = Random.uniform x xs +itemKindGenerator : Generator Item.Kind +itemKindGenerator = + let + ( x, xs ) = + Item.allNonempty + in + Random.uniform x xs + + shotTypeGenerator : Generator ShotType shotTypeGenerator = Random.uniform ShotType.NormalShot @@ -79,15 +88,54 @@ shotTypeGenerator = conditionGenerator : Generator FightStrategy.Condition conditionGenerator = + let + self = + Random.lazy (\() -> conditionGenerator) + in Random.uniform - (FightStrategy.Operator - { value = FightStrategy.MyHP - , op = FightStrategy.LT_ - , number_ = 50 - } + (Random.map3 + (\lhs op rhs -> + FightStrategy.Operator + { lhs = lhs + , op = op + , rhs = rhs + } + ) + valueGenerator + operatorGenerator + valueGenerator ) - [ FightStrategy.OpponentIsPlayer - , FightStrategy.OpponentIsNPC + [ Random.constant FightStrategy.OpponentIsPlayer + , Random.constant FightStrategy.OpponentIsNPC + , Random.map2 FightStrategy.Or self self + , Random.map2 FightStrategy.And self self + ] + |> Random.andThen identity + + +valueGenerator : Generator FightStrategy.Value +valueGenerator = + Random.uniform + (Random.constant FightStrategy.MyHP) + [ Random.constant FightStrategy.MyMaxHP + , Random.constant FightStrategy.MyAP + , Random.map FightStrategy.MyItemCount itemKindGenerator + , Random.map FightStrategy.ItemsUsed itemKindGenerator + , Random.map FightStrategy.ChanceToHit shotTypeGenerator + , Random.constant FightStrategy.Distance + , Random.map FightStrategy.Number (Random.int -50 300) + ] + |> Random.andThen identity + + +operatorGenerator : Generator FightStrategy.Operator +operatorGenerator = + Random.uniform FightStrategy.LT_ + [ FightStrategy.LTE + , FightStrategy.EQ_ + , FightStrategy.NE + , FightStrategy.GTE + , FightStrategy.GT_ ] @@ -130,9 +178,9 @@ moveForwardIfNeeded strategy = FightStrategy.If { condition = FightStrategy.Operator - { value = FightStrategy.Distance + { lhs = FightStrategy.Distance , op = FightStrategy.GT_ - , number_ = 0 + , rhs = FightStrategy.Number 0 } , then_ = FightStrategy.Command FightStrategy.MoveForward , else_ = strategy @@ -477,6 +525,9 @@ mutateFightStrategy str = FightStrategy.MoveForward -> Random.constant FightStrategy.MoveForward + FightStrategy.SkipTurn -> + Random.constant FightStrategy.SkipTurn + FightStrategy.DoWhatever -> Random.constant FightStrategy.DoWhatever diff --git a/src/Data/Auth.elm b/src/Data/Auth.elm index b76b291c..6e837124 100644 --- a/src/Data/Auth.elm +++ b/src/Data/Auth.elm @@ -72,21 +72,12 @@ encodePassword password = verifiedDecoder : Decoder (Auth Verified) verifiedDecoder = JD.oneOf - [ verifiedDecoderV2 - , verifiedDecoderV1 + [ verifiedDecoderV1 ] verifiedDecoderV1 : Decoder (Auth Verified) verifiedDecoderV1 = - JD.succeed Auth - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - - -verifiedDecoderV2 : Decoder (Auth Verified) -verifiedDecoderV2 = JD.succeed Auth |> JD.andMap (JD.field "name" JD.string) |> JD.andMap (JD.field "password" verifiedPasswordDecoder) diff --git a/src/Data/Barter.elm b/src/Data/Barter.elm index 08f87b78..226d4273 100644 --- a/src/Data/Barter.elm +++ b/src/Data/Barter.elm @@ -114,21 +114,18 @@ removePlayerItem id count state = | playerItems = state.playerItems |> Dict.update id - (\maybeExistingCount -> - case maybeExistingCount of - Nothing -> + (Maybe.andThen + (\existingCount -> + let + newCount = + existingCount - count + in + if newCount <= 0 then Nothing - Just existingCount -> - let - newCount = - existingCount - count - in - if newCount <= 0 then - Nothing - - else - Just newCount + else + Just newCount + ) ) } @@ -139,21 +136,18 @@ removeVendorItem id count state = | vendorItems = state.vendorItems |> Dict.update id - (\maybeExistingCount -> - case maybeExistingCount of - Nothing -> + (Maybe.andThen + (\existingCount -> + let + newCount = + existingCount - count + in + if newCount <= 0 then Nothing - Just existingCount -> - let - newCount = - existingCount - count - in - if newCount <= 0 then - Nothing - - else - Just newCount + else + Just newCount + ) ) } diff --git a/src/Data/Fight.elm b/src/Data/Fight.elm index 996cb17d..9a96a728 100644 --- a/src/Data/Fight.elm +++ b/src/Data/Fight.elm @@ -243,110 +243,12 @@ encodeResult result = resultDecoder : Decoder Result resultDecoder = JD.oneOf - [ resultDecoderV3 - , resultDecoderV2 - , resultDecoderV1 + [ resultDecoderV1 ] -{-| Original --} resultDecoderV1 : Decoder Result resultDecoderV1 = - JD.field "type" JD.string - |> JD.andThen - (\type_ -> - case type_ of - "AttackerWon" -> - JD.map2 - (\xp caps -> - AttackerWon - { xpGained = xp - , capsGained = caps - , itemsGained = [] - } - ) - (JD.field "xpGained" JD.int) - (JD.field "capsGained" JD.int) - - "TargetWon" -> - JD.map2 - (\xp caps -> - TargetWon - { xpGained = xp - , capsGained = caps - , itemsGained = [] - } - ) - (JD.field "xpGained" JD.int) - (JD.field "capsGained" JD.int) - - "TargetAlreadyDead" -> - JD.succeed TargetAlreadyDead - - "BothDead" -> - JD.succeed BothDead - - "NobodyDead" -> - JD.succeed NobodyDead - - _ -> - JD.fail <| "Unknown Fight.Result: '" ++ type_ ++ "'" - ) - - -{-| Adding the `itemsGained` field --} -resultDecoderV2 : Decoder Result -resultDecoderV2 = - JD.field "type" JD.string - |> JD.andThen - (\type_ -> - case type_ of - "AttackerWon" -> - JD.map3 - (\xp caps items -> - AttackerWon - { xpGained = xp - , capsGained = caps - , itemsGained = items - } - ) - (JD.field "xpGained" JD.int) - (JD.field "capsGained" JD.int) - (JD.field "itemsGained" (JD.list Item.decoder)) - - "TargetWon" -> - JD.map3 - (\xp caps items -> - TargetWon - { xpGained = xp - , capsGained = caps - , itemsGained = items - } - ) - (JD.field "xpGained" JD.int) - (JD.field "capsGained" JD.int) - (JD.field "itemsGained" (JD.list Item.decoder)) - - "TargetAlreadyDead" -> - JD.succeed TargetAlreadyDead - - "BothDead" -> - JD.succeed BothDead - - "NobodyDead" -> - JD.succeed NobodyDead - - _ -> - JD.fail <| "Unknown Fight.Result: '" ++ type_ ++ "'" - ) - - -{-| Adding the `NobodyDeadGivenUp` result type --} -resultDecoderV3 : Decoder Result -resultDecoderV3 = JD.field "type" JD.string |> JD.andThen (\type_ -> @@ -576,29 +478,12 @@ commandRejectionReasonDecoder = attackActionDecoder : Decoder Action attackActionDecoder = JD.oneOf - [ attackActionDecoderV2 - , attackActionDecoderV1 + [ attackActionDecoderV1 ] attackActionDecoderV1 : Decoder Action attackActionDecoderV1 = - JD.map3 - (\damage shotType remainingHp -> - Attack - { damage = damage - , shotType = shotType - , remainingHp = remainingHp - , isCritical = False - } - ) - (JD.field "damage" JD.int) - (JD.field "shotType" ShotType.decoder) - (JD.field "remainingHp" JD.int) - - -attackActionDecoderV2 : Decoder Action -attackActionDecoderV2 = JD.map4 (\damage shotType remainingHp isCritical -> Attack diff --git a/src/Data/Fight/View.elm b/src/Data/Fight/View.elm index 0717c5ca..9082eedc 100644 --- a/src/Data/Fight/View.elm +++ b/src/Data/Fight/View.elm @@ -9,7 +9,6 @@ import Data.Special.Perception as Perception exposing (PerceptionLevel) import Html as H exposing (Html) import Html.Attributes as HA import List.Extra -import Markdown import Set exposing (Set) diff --git a/src/Data/Item.elm b/src/Data/Item.elm index 56468fd0..e3d20a4f 100644 --- a/src/Data/Item.elm +++ b/src/Data/Item.elm @@ -8,6 +8,7 @@ module Data.Item exposing , all , allHealing , allHealingNonempty + , allNonempty , armorClass , baseValue , create @@ -20,7 +21,8 @@ module Data.Item exposing , getUniqueKey , healAmountGenerator , healAmountGenerator_ - , isEquippable + , isArmor + , isHandEquippable , isHealing , kindDecoder , name @@ -154,6 +156,17 @@ all = ] +allNonempty : ( Kind, List Kind ) +allNonempty = + case all of + [] -> + -- Just a sentinel, shouldn't happen + ( Fruit, [] ) + + x :: xs -> + ( x, xs ) + + allHealing : List Kind allHealing = List.filter isHealing all @@ -1801,14 +1814,14 @@ type Type | Ammo -isEquippableType : Type -> Bool -isEquippableType type__ = +isHandEquippableType : Type -> Bool +isHandEquippableType type__ = case type__ of Food -> False Armor -> - True + False UnarmedWeapon -> True @@ -2022,9 +2035,14 @@ type_ kind = Misc -isEquippable : Kind -> Bool -isEquippable kind = - isEquippableType (type_ kind) +isHandEquippable : Kind -> Bool +isHandEquippable kind = + isHandEquippableType (type_ kind) + + +isArmor : Kind -> Bool +isArmor kind = + type_ kind == Armor typeName : Type -> String diff --git a/src/Data/Message.elm b/src/Data/Message.elm index ff753b1c..f58b50b9 100644 --- a/src/Data/Message.elm +++ b/src/Data/Message.elm @@ -88,36 +88,12 @@ could change this back into decoder? dictDecoder : Decoder (Dict Id Message) dictDecoder = JD.oneOf - [ dictDecoderV2 - , dictDecoderV1 + [ dictDecoderV1 ] dictDecoderV1 : Decoder (Dict Id Message) dictDecoderV1 = - JD.list - (JD.succeed - (\content_ hasBeenRead date id -> - { id = id - , content = content_ - , hasBeenRead = hasBeenRead - , date = date - } - ) - |> JD.andMap (JD.field "type" contentDecoder) - |> JD.andMap (JD.field "hasBeenRead" JD.bool) - |> JD.andMap (JD.field "date" Iso8601.decoder) - ) - |> JD.map - (List.indexedMap (\id toMessage -> ( id, toMessage id )) - >> Dict.fromList - ) - - -{-| Adds ID, changes type into content --} -dictDecoderV2 : Decoder (Dict Id Message) -dictDecoderV2 = JD.list (JD.succeed Message |> JD.andMap (JD.field "id" JD.int) diff --git a/src/Data/Player.elm b/src/Data/Player.elm index e9f75a79..c5edc4b1 100644 --- a/src/Data/Player.elm +++ b/src/Data/Player.elm @@ -81,6 +81,8 @@ type alias SPlayer = , availableSkillPoints : Int , availablePerks : Int , equippedArmor : Maybe Item + , equippedLeftHand : Maybe Item + , equippedRightHand : Maybe Item , fightStrategy : FightStrategy , fightStrategyText : String , questsActive : SeqSet Quest.Name @@ -108,6 +110,8 @@ type alias CPlayer = , availableSkillPoints : Int , availablePerks : Int , equippedArmor : Maybe Item + , equippedLeftHand : Maybe Item + , equippedRightHand : Maybe Item , fightStrategy : FightStrategy , fightStrategyText : String , questsActive : SeqSet Quest.Name @@ -191,270 +195,12 @@ decoder innerDecoder = sPlayerDecoder : Decoder SPlayer sPlayerDecoder = JD.oneOf - [ sPlayerDecoderV8 - , sPlayerDecoderV7 - , sPlayerDecoderV6 - , sPlayerDecoderV5 - , sPlayerDecoderV4 - , sPlayerDecoderV3 - , sPlayerDecoderV2 - , sPlayerDecoderV1 + [ sPlayerDecoderV1 ] -{-| with skills we are getting a reset! --} sPlayerDecoderV1 : Decoder SPlayer sPlayerDecoderV1 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "baseSpecial" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.succeed 0) - |> JD.andMap (JD.succeed Nothing) - |> JD.andMap (JD.succeed (Tuple.second FightStrategy.default)) - |> JD.andMap (JD.succeed "") - |> JD.andMap (JD.succeed SeqSet.empty) - |> JD.map - (\player -> - let - finalSpecial = - Logic.newCharSpecial - { baseSpecial = player.special - , hasBruiserTrait = Trait.isSelected Trait.Bruiser player.traits - , hasGiftedTrait = Trait.isSelected Trait.Gifted player.traits - , hasSmallFrameTrait = Trait.isSelected Trait.SmallFrame player.traits - } - in - { player | special = finalSpecial } - ) - - -{-| adding `availablePerks` --} -sPlayerDecoderV2 : Decoder SPlayer -sPlayerDecoderV2 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "baseSpecial" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.succeed Nothing) - |> JD.andMap (JD.succeed (Tuple.second FightStrategy.default)) - |> JD.andMap (JD.succeed "") - |> JD.andMap (JD.succeed SeqSet.empty) - |> JD.map - (\player -> - let - finalSpecial = - Logic.newCharSpecial - { baseSpecial = player.special - , hasBruiserTrait = Trait.isSelected Trait.Bruiser player.traits - , hasGiftedTrait = Trait.isSelected Trait.Gifted player.traits - , hasSmallFrameTrait = Trait.isSelected Trait.SmallFrame player.traits - } - in - { player | special = finalSpecial } - ) - - -{-| Renamed `baseSpecial` to `special`, it now has the final values, not the -base ones before traits. --} -sPlayerDecoderV3 : Decoder SPlayer -sPlayerDecoderV3 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "special" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.succeed Nothing) - |> JD.andMap (JD.succeed (Tuple.second FightStrategy.default)) - |> JD.andMap (JD.succeed "") - |> JD.andMap (JD.succeed SeqSet.empty) - - -{-| Adding equippedArmor --} -sPlayerDecoderV4 : Decoder SPlayer -sPlayerDecoderV4 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "special" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.field "equippedArmor" (JD.maybe Item.decoder)) - |> JD.andMap (JD.succeed (Tuple.second FightStrategy.default)) - |> JD.andMap (JD.succeed "") - |> JD.andMap (JD.succeed SeqSet.empty) - - -{-| Adding fightStrategy --} -sPlayerDecoderV5 : Decoder SPlayer -sPlayerDecoderV5 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "special" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.field "equippedArmor" (JD.maybe Item.decoder)) - |> JD.andMap (JD.field "fightStrategy" FightStrategy.decoder) - |> JD.andMap - (JD.field "fightStrategy" - (FightStrategy.decoder - |> JD.map FightStrategy.toString - ) - ) - |> JD.andMap (JD.succeed SeqSet.empty) - - -{-| Adding fightStrategyText --} -sPlayerDecoderV6 : Decoder SPlayer -sPlayerDecoderV6 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.succeed Logic.mainWorldName) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "special" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.field "equippedArmor" (JD.maybe Item.decoder)) - |> JD.andMap (JD.field "fightStrategy" FightStrategy.decoder) - |> JD.andMap (JD.field "fightStrategyText" JD.string) - |> JD.andMap (JD.succeed SeqSet.empty) - - -{-| Adding worldName --} -sPlayerDecoderV7 : Decoder SPlayer -sPlayerDecoderV7 = - JD.succeed SPlayer - |> JD.andMap (JD.field "name" JD.string) - |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) - |> JD.andMap (JD.field "worldName" JD.string) - |> JD.andMap (JD.field "hp" JD.int) - |> JD.andMap (JD.field "maxHp" JD.int) - |> JD.andMap (JD.field "xp" JD.int) - |> JD.andMap (JD.field "special" Special.decoder) - |> JD.andMap (JD.field "caps" JD.int) - |> JD.andMap (JD.field "ticks" JD.int) - |> JD.andMap (JD.field "wins" JD.int) - |> JD.andMap (JD.field "losses" JD.int) - |> JD.andMap (JD.field "location" JD.int) - |> JD.andMap (JD.field "perks" (SeqDict.decoder Perk.decoder JD.int)) - |> JD.andMap (JD.field "messages" Message.dictDecoder) - |> JD.andMap (JD.field "items" (Dict.decoder JD.int Item.decoder)) - |> JD.andMap (JD.field "traits" (SeqSet.decoder Trait.decoder)) - |> JD.andMap (JD.field "addedSkillPercentages" (SeqDict.decoder Skill.decoder JD.int)) - |> JD.andMap (JD.field "taggedSkills" (SeqSet.decoder Skill.decoder)) - |> JD.andMap (JD.field "availableSkillPoints" JD.int) - |> JD.andMap (JD.field "availablePerks" JD.int) - |> JD.andMap (JD.field "equippedArmor" (JD.maybe Item.decoder)) - |> JD.andMap (JD.field "fightStrategy" FightStrategy.decoder) - |> JD.andMap (JD.field "fightStrategyText" JD.string) - |> JD.andMap (JD.succeed SeqSet.empty) - - -{-| Adding questsActive --} -sPlayerDecoderV8 : Decoder SPlayer -sPlayerDecoderV8 = JD.succeed SPlayer |> JD.andMap (JD.field "name" JD.string) |> JD.andMap (JD.field "password" Auth.verifiedPasswordDecoder) @@ -477,6 +223,8 @@ sPlayerDecoderV8 = |> JD.andMap (JD.field "availableSkillPoints" JD.int) |> JD.andMap (JD.field "availablePerks" JD.int) |> JD.andMap (JD.field "equippedArmor" (JD.maybe Item.decoder)) + |> JD.andMap (JD.field "equippedLeftHand" (JD.maybe Item.decoder)) + |> JD.andMap (JD.field "equippedRightHand" (JD.maybe Item.decoder)) |> JD.andMap (JD.field "fightStrategy" FightStrategy.decoder) |> JD.andMap (JD.field "fightStrategyText" JD.string) |> JD.andMap (JD.field "questsActive" (SeqSet.decoder Quest.decoder)) @@ -503,6 +251,8 @@ serverToClient p = , availableSkillPoints = p.availableSkillPoints , availablePerks = p.availablePerks , equippedArmor = p.equippedArmor + , equippedLeftHand = p.equippedLeftHand + , equippedRightHand = p.equippedRightHand , fightStrategy = p.fightStrategy , fightStrategyText = p.fightStrategyText , questsActive = p.questsActive @@ -638,6 +388,8 @@ fromNewChar currentTime auth newChar = , availableSkillPoints = 0 , availablePerks = 0 , equippedArmor = Nothing + , equippedLeftHand = Nothing + , equippedRightHand = Nothing , fightStrategy = Tuple.second FightStrategy.default , fightStrategyText = Tuple.second FightStrategy.default diff --git a/src/Data/Player/SPlayer.elm b/src/Data/Player/SPlayer.elm index 31b60cce..fdd87b9d 100644 --- a/src/Data/Player/SPlayer.elm +++ b/src/Data/Player/SPlayer.elm @@ -8,7 +8,9 @@ module Data.Player.SPlayer exposing , addXp , canStartProgressing , decAvailablePerks - , equipItem + , equipArmor + , equipLeftHand + , equipRightHand , healManuallyUsingTick , incLosses , incPerkRank @@ -33,6 +35,8 @@ module Data.Player.SPlayer exposing , tagSkill , tick , unequipArmor + , unequipLeftHand + , unequipRightHand , updateStrengthForAdrenalineRush , useSkillPoints ) @@ -436,17 +440,14 @@ removeItem id removedCount player = | items = player.items |> Dict.update id - (\maybeItem -> - case maybeItem of - Nothing -> - Nothing + (Maybe.andThen + (\oldItem -> + if oldItem.count > removedCount then + Just { oldItem | count = oldItem.count - removedCount } - Just oldItem -> - if oldItem.count > removedCount then - Just { oldItem | count = oldItem.count - removedCount } - - else - Nothing + else + Nothing + ) ) } @@ -601,61 +602,95 @@ unequipArmor player = |> addItem armor -equipItem : Item -> SPlayer -> SPlayer -equipItem { id } player = +unequipLeftHand : SPlayer -> SPlayer +unequipLeftHand player = + case player.equippedLeftHand of + Nothing -> + player + + Just leftHand -> + { player | equippedLeftHand = Nothing } + |> addItem leftHand + + +unequipRightHand : SPlayer -> SPlayer +unequipRightHand player = + case player.equippedRightHand of + Nothing -> + player + + Just rightHand -> + { player | equippedRightHand = Nothing } + |> addItem rightHand + + +equipArmor : Item -> SPlayer -> SPlayer +equipArmor { id } player = -- just to be sure... case Dict.get id player.items of Nothing -> player Just item -> - case Item.type_ item.kind of - Item.Food -> - player + if Item.isArmor item.kind then + player + |> (if player.equippedArmor /= Nothing then + unequipArmor - Item.Book -> - player + else + identity + ) + |> removeItem item.id 1 + |> (\p -> { p | equippedArmor = Just { item | count = 1 } }) - Item.Armor -> - player - |> (if player.equippedArmor /= Nothing then - unequipArmor + else + player - else - identity - ) - |> removeItem item.id 1 - |> (\p -> { p | equippedArmor = Just { item | count = 1 } }) - Item.Ammo -> - player +equipLeftHand : Item -> SPlayer -> SPlayer +equipLeftHand { id } player = + -- just to be sure... + case Dict.get id player.items of + Nothing -> + player - Item.Misc -> - player + Just item -> + if Item.isHandEquippable item.kind then + player + |> (if player.equippedLeftHand /= Nothing then + unequipLeftHand - Item.UnarmedWeapon -> - -- TODO equip weapons - player + else + identity + ) + |> removeItem item.id 1 + |> (\p -> { p | equippedLeftHand = Just { item | count = 1 } }) + + else + player - Item.MeleeWeapon -> - -- TODO equip weapons - player - Item.ThrownWeapon -> - -- TODO equip weapons - player +equipRightHand : Item -> SPlayer -> SPlayer +equipRightHand { id } player = + -- just to be sure... + case Dict.get id player.items of + Nothing -> + player - Item.SmallGun -> - -- TODO equip weapons - player + Just item -> + if Item.isHandEquippable item.kind then + player + |> (if player.equippedRightHand /= Nothing then + unequipRightHand - Item.BigGun -> - -- TODO equip weapons - player + else + identity + ) + |> removeItem item.id 1 + |> (\p -> { p | equippedRightHand = Just { item | count = 1 } }) - Item.EnergyWeapon -> - -- TODO equip weapons - player + else + player setFightStrategy : ( FightStrategy, String ) -> SPlayer -> SPlayer @@ -734,6 +769,7 @@ stopProgressing quest player = canStartProgressing : Quest.Name -> TickPerIntervalCurve -> SPlayer -> Bool canStartProgressing quest worldTickCurve player = + -- TODO is it expected that `quest` is not used? ticksPerHourAvailableAfterQuests worldTickCurve player >= Logic.minTicksPerHourNeededForQuest diff --git a/src/Data/Vendor.elm b/src/Data/Vendor.elm index a4b4449c..30704632 100644 --- a/src/Data/Vendor.elm +++ b/src/Data/Vendor.elm @@ -352,17 +352,14 @@ removeItem id removedCount vendor = | items = vendor.items |> Dict.update id - (\maybeItem -> - case maybeItem of - Nothing -> - Nothing - - Just oldItem -> - if oldItem.count > removedCount then - Just { oldItem | count = oldItem.count - removedCount } + (Maybe.andThen + (\oldItem -> + if oldItem.count > removedCount then + Just { oldItem | count = oldItem.count - removedCount } - else - Nothing + else + Nothing + ) ) } diff --git a/src/Data/World.elm b/src/Data/World.elm index 1ae285c9..e23d3fbb 100644 --- a/src/Data/World.elm +++ b/src/Data/World.elm @@ -130,129 +130,12 @@ lastItemId players vendors = decoder : Decoder World decoder = JD.oneOf - [ decoderV4 - , decoderV3 - , decoderV2 - , decoderV1 + [ decoderV1 ] -{-| init version --} decoderV1 : Decoder World decoderV1 = - JD.map2 - (\players nextWantedTick -> - let - vendors = - Vendor.emptyVendors - in - { players = players - , nextWantedTick = nextWantedTick - , nextVendorRestockTick = Nothing - , vendors = vendors - , lastItemId = lastItemId players vendors - , description = "" - , startedAt = Time.millisToPosix 0 - , tickFrequency = Time.Hour - , tickPerIntervalCurve = QuarterAndRest { quarter = 4, rest = 2 } - , vendorRestockFrequency = Time.Hour - , questsProgress = - Quest.all - |> List.map (\q -> ( q, Dict.empty )) - |> SeqDict.fromList - } - ) - (JD.field "players" - (JD.list - (Player.decoder Player.sPlayerDecoder - |> JD.map (\player -> ( Player.getAuth player |> .name, player )) - ) - |> JD.map Dict.fromList - ) - ) - (JD.field "nextWantedTick" (JD.maybe Iso8601.decoder)) - - -{-| adds "vendors" field --} -decoderV2 : Decoder World -decoderV2 = - JD.map3 - (\players nextWantedTick vendors -> - { players = players - , nextWantedTick = nextWantedTick - , nextVendorRestockTick = Nothing - , vendors = vendors - , lastItemId = lastItemId players vendors - , description = "" - , startedAt = Time.millisToPosix 0 - , tickFrequency = Time.Hour - , tickPerIntervalCurve = QuarterAndRest { quarter = 4, rest = 2 } - , vendorRestockFrequency = Time.Hour - , questsProgress = - Quest.all - |> List.map (\q -> ( q, Dict.empty )) - |> SeqDict.fromList - } - ) - (JD.field "players" - (JD.list - (Player.decoder Player.sPlayerDecoder - |> JD.map (\player -> ( Player.getAuth player |> .name, player )) - ) - |> JD.map Dict.fromList - ) - ) - (JD.field "nextWantedTick" (JD.maybe Iso8601.decoder)) - (JD.field "vendors" Vendor.vendorsDecoder) - - -{-| adds "description", "startedAt", "tickFrequency", "tickPerIntervalCurve", "vendorRestockFrequency", "nextVendorRestockTick" fields --} -decoderV3 : Decoder World -decoderV3 = - JD.succeed - (\players nextWantedTick nextVendorRestockTick vendors description startedAt tickFrequency tickPerIntervalCurve vendorRestockFrequency -> - { players = players - , nextWantedTick = nextWantedTick - , nextVendorRestockTick = nextVendorRestockTick - , vendors = vendors - , lastItemId = lastItemId players vendors - , description = description - , startedAt = startedAt - , tickFrequency = tickFrequency - , tickPerIntervalCurve = tickPerIntervalCurve - , vendorRestockFrequency = vendorRestockFrequency - , questsProgress = - Quest.all - |> List.map (\q -> ( q, Dict.empty )) - |> SeqDict.fromList - } - ) - |> JD.andMap - (JD.field "players" - (JD.list - (Player.decoder Player.sPlayerDecoder - |> JD.map (\player -> ( Player.getAuth player |> .name, player )) - ) - |> JD.map Dict.fromList - ) - ) - |> JD.andMap (JD.field "nextWantedTick" (JD.maybe Iso8601.decoder)) - |> JD.andMap (JD.field "nextVendorRestockTick" (JD.maybe Iso8601.decoder)) - |> JD.andMap (JD.field "vendors" Vendor.vendorsDecoder) - |> JD.andMap (JD.field "description" JD.string) - |> JD.andMap (JD.field "startedAt" Iso8601.decoder) - |> JD.andMap (JD.field "tickFrequency" Time.intervalDecoder) - |> JD.andMap (JD.field "tickPerIntervalCurve" Tick.curveDecoder) - |> JD.andMap (JD.field "vendorRestockFrequency" Time.intervalDecoder) - - -{-| adds "questsProgress" field --} -decoderV4 : Decoder World -decoderV4 = JD.succeed (\players nextWantedTick nextVendorRestockTick vendors description startedAt tickFrequency tickPerIntervalCurve vendorRestockFrequency questsProgress -> { players = players diff --git a/src/DummyMain.elm b/src/DummyMain.elm deleted file mode 100644 index 419ddd15..00000000 --- a/src/DummyMain.elm +++ /dev/null @@ -1,12 +0,0 @@ -module DummyMain exposing (main) - -import Backend -import Frontend -import Html - - -main = - Html.div [] - (Html.text (Debug.toString Backend.app) - :: Frontend.aboutView - ) diff --git a/src/Frontend.elm b/src/Frontend.elm index 0fadbf95..154ed453 100644 --- a/src/Frontend.elm +++ b/src/Frontend.elm @@ -309,9 +309,19 @@ update msg ({ loginForm } as model) = , Lamdera.sendToBackend HealMe ) - AskToEquipItem itemId -> + AskToEquipArmor itemId -> ( model - , Lamdera.sendToBackend <| EquipItem itemId + , Lamdera.sendToBackend <| EquipArmor itemId + ) + + AskToEquipLeftHand itemId -> + ( model + , Lamdera.sendToBackend <| EquipLeftHand itemId + ) + + AskToEquipRightHand itemId -> + ( model + , Lamdera.sendToBackend <| EquipRightHand itemId ) AskToUnequipArmor -> @@ -319,6 +329,16 @@ update msg ({ loginForm } as model) = , Lamdera.sendToBackend UnequipArmor ) + AskToUnequipLeftHand -> + ( model + , Lamdera.sendToBackend UnequipLeftHand + ) + + AskToUnequipRightHand -> + ( model + , Lamdera.sendToBackend UnequipRightHand + ) + AskToUseItem itemId -> ( model , Lamdera.sendToBackend <| UseItem itemId @@ -3320,17 +3340,31 @@ inventoryView _ player = [ UI.liBullet , H.span [ HA.class "flex flex-row gap-[2ch]" ] - [ UI.button + (UI.button [ HE.onClick <| AskToUseItem item.id , HA.disabled <| disabledTooltip /= Nothing , HA.attributeMaybe HA.title disabledTooltip ] [ H.text "[Use]" ] - , H.viewIf (Item.isEquippable item.kind) <| - UI.button - [ HE.onClick <| AskToEquipItem item.id ] - [ H.text "[Equip]" ] - ] + :: (if Item.isArmor item.kind then + [ UI.button + [ HE.onClick <| AskToEquipArmor item.id ] + [ H.text "[Equip]" ] + ] + + else if Item.isHandEquippable item.kind then + [ UI.button + [ HE.onClick <| AskToEquipLeftHand item.id ] + [ H.text "[Equip left]" ] + , UI.button + [ HE.onClick <| AskToEquipRightHand item.id ] + [ H.text "[Equip right]" ] + ] + + else + [] + ) + ) , H.span [ HA.class "inventory-item-label" ] [ H.text <| String.fromInt item.count ++ "x " ++ Item.name item.kind ] @@ -3417,20 +3451,12 @@ inventoryView _ player = , H.h3 [ HA.class "text-green-300" ] [ H.text "Equipment" ] - , [ ( player.equippedArmor - , "Armor" - , \armor -> - [ H.text <| Item.name armor.kind - , UI.button - [ HE.onClick AskToUnequipArmor - , HA.class "ml-[1ch]" - ] - [ H.text "[Unequip]" ] - ] - ) + , [ ( player.equippedArmor, "Armor", AskToUnequipArmor ) + , ( player.equippedLeftHand, "Left hand", AskToUnequipLeftHand ) + , ( player.equippedRightHand, "Right hand", AskToUnequipRightHand ) ] |> List.map - (\( maybeItem, label, viewItem ) -> + (\( maybeItem, label, unequipMsg ) -> H.div [] [ UI.liBullet , H.text <| label ++ ": " @@ -3440,7 +3466,13 @@ inventoryView _ player = [ H.text "None" ] Just item -> - viewItem item + [ H.text <| Item.name item.kind + , UI.button + [ HE.onClick unequipMsg + , HA.class "ml-[1ch]" + ] + [ H.text "[Unequip]" ] + ] ] ) |> H.ul [] diff --git a/src/Types.elm b/src/Types.elm index d1c76dfa..4a48acdd 100644 --- a/src/Types.elm +++ b/src/Types.elm @@ -98,8 +98,12 @@ type FrontendMsg | AskToUseItem Item.Id | AskToWander | AskToChoosePerk Perk - | AskToEquipItem Item.Id + | AskToEquipArmor Item.Id + | AskToEquipLeftHand Item.Id + | AskToEquipRightHand Item.Id | AskToUnequipArmor + | AskToUnequipLeftHand + | AskToUnequipRightHand | AskToSetFightStrategy ( FightStrategy, String ) | AskForExport | ImportButtonClicked @@ -161,9 +165,13 @@ type ToBackend | HealMe | UseItem Item.Id | Wander - | EquipItem Item.Id + | EquipArmor Item.Id + | EquipLeftHand Item.Id + | EquipRightHand Item.Id | SetFightStrategy ( FightStrategy, String ) | UnequipArmor + | UnequipLeftHand + | UnequipRightHand | RefreshPlease | TagSkill Skill | UseSkillPoints Skill