dev #25
					 6 changed files with 59 additions and 21 deletions
				
			
		|  | @ -91,4 +91,10 @@ isInventoryFull p = inventorySize <= length (inventory p) | |||
| 
 | ||||
| -- Check if the inventory of the player contains an item. | ||||
| inventoryContains :: ItemId -> Player -> Bool | ||||
| inventoryContains id p = any ((== id) . itemId) $ inventory p | ||||
| inventoryContains id p = any ((== id) . itemId) $ inventory p | ||||
| 
 | ||||
| -- Retrieve an item from inventory | ||||
| itemFromInventory :: ItemId -> [Item] -> (Maybe Item, [Item]) | ||||
| itemFromInventory iid list = (match, filteredList) | ||||
|     where match = find ((== iid) . itemId) list | ||||
|           filteredList = filter ((/= iid) . itemId) list | ||||
|  | @ -4,11 +4,11 @@ module RPGEngine.Input.ActionSelection | |||
| 
 | ||||
| import RPGEngine.Input.Core (InputHandler, handleKey, composeInputHandlers, ListSelector (selection)) | ||||
| 
 | ||||
| import RPGEngine.Data (Game (..), State (..), Direction (..), Action (..), ItemId, EntityId, Level (..), Player (inventory, playerHp, Player), Item (..), HP) | ||||
| import RPGEngine.Data (Game (..), State (..), Direction (..), Action (..), ItemId, EntityId, Level (..), Player (inventory, playerHp, Player), Item (..), HP, Entity (..)) | ||||
| import Graphics.Gloss.Interface.IO.Game (Key(SpecialKey), SpecialKey (KeyUp, KeyDown)) | ||||
| import Graphics.Gloss.Interface.IO.Interact | ||||
|     ( SpecialKey(..), KeyState(..) ) | ||||
| import RPGEngine.Data.Level (getWithId) | ||||
| import RPGEngine.Data.Level (getWithId, itemFromInventory) | ||||
| import Data.Foldable (find) | ||||
| 
 | ||||
| ------------------------------ Exported ------------------------------ | ||||
|  | @ -72,13 +72,30 @@ useItem :: ItemId -> State -> State -- TODO | |||
| useItem _ s = s -- TODO | ||||
| 
 | ||||
| -- Attack an entity using an item | ||||
| -- Should receive a Playing state | ||||
| decreaseHp :: EntityId -> ItemId -> State -> State | ||||
| decreaseHp _ _ s = s | ||||
| -- TODO DecreaseHp of monster | ||||
| -- TODO Check if monster is dead | ||||
| -- TODO Entity attack player | ||||
| -- TODO Decrease durability of item | ||||
| -- TODO Break item if durability below zero | ||||
| decreaseHp eid iid s@Playing{ level = level, player = player } = newState | ||||
|     where newState = s{ level = newLevel, player = newPlayer } | ||||
|           -- Change player | ||||
|           (Just usingItem) = find ((== iid) . itemId) (inventory player) | ||||
|           usedItem         = decreaseDurability usingItem | ||||
|           newInventory     = filter (/= usingItem) $ inventory player | ||||
|           newPlayer = player{ inventory = putItemBack usedItem newInventory, playerHp = newHp } | ||||
|           putItemBack Nothing inv     = inv | ||||
|           putItemBack (Just item) inv = item:inv | ||||
|           newHp                       = changeHealth (playerHp player) damageGetAmount -- Damage dealt by entity | ||||
|           damageDealAmount = itemValue usingItem | ||||
|           -- Change entity | ||||
|           (Just (Right attackedEntity)) = getWithId eid level | ||||
|           newLevel = level{ entities = putEntityBack dealtWithEntity newEntities } | ||||
|           newEntities = filter ((/= eid) . entityId) $ entities level | ||||
|           dealtWithEntity = decreaseHealth attackedEntity damageDealAmount  | ||||
|           putEntityBack Nothing    list = list | ||||
|           putEntityBack (Just ent) list = ent:list | ||||
|           damageGetAmount = inverse (entityValue attackedEntity) | ||||
|           inverse (Just val) = Just (-val) | ||||
|           inverse Nothing    = Nothing | ||||
| decreaseHp _ _ _ = Error "something went wrong while attacking" | ||||
| 
 | ||||
| -- Heal a bit | ||||
| -- Should receive a Player | ||||
|  | @ -97,6 +114,12 @@ decreaseDurability item@Item{ useTimes = Nothing  } = Just item -- Infinite uses | |||
| decreaseDurability item@Item{ useTimes = Just val } | 0 < val - 1 = Just item{ useTimes = Just (val - 1) } | ||||
|                                                     | otherwise = Nothing -- Broken | ||||
| 
 | ||||
| decreaseHealth :: Entity -> Maybe Int -> Maybe Entity | ||||
| decreaseHealth entity@Entity{ entityHp = Nothing  } _ = Just entity | ||||
| decreaseHealth entity@Entity{ entityHp = Just val } (Just i) | 0 < val - i = Just entity{ entityHp = Just (val - i) } | ||||
|                                                              | otherwise   = Nothing | ||||
| decreaseHealth entity _ = Just entity | ||||
| 
 | ||||
| -- Change given health by a given amount | ||||
| changeHealth :: HP -> HP -> HP | ||||
| changeHealth (Just health) (Just difference) = Just (health + difference) | ||||
|  |  | |||
|  | @ -139,7 +139,7 @@ action = try $ do | |||
|     let answer | script == "leave"            = Leave | ||||
|                | script == "retrieveItem"     = RetrieveItem arg | ||||
|                | script == "useItem"          = UseItem arg | ||||
|                | script == "decreaseHp"       = DecreaseHp first second | ||||
|                | script == "decreaseHp"       = DecreaseHp first (filter (/= ' ') second) -- TODO Work this hack away | ||||
|                | script == "increasePlayerHp" = IncreasePlayerHp arg | ||||
|                | otherwise                    = DoNothing | ||||
|         (first, ',':second) = break (== ',') arg | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import RPGEngine | ||||
| import RPGEngine ( playRPGEngine ) | ||||
| 
 | ||||
| ----------------------------- Constants ------------------------------ | ||||
| 
 | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ import RPGEngine.Data | |||
| import RPGEngine.Parse.Core | ||||
| import RPGEngine.Parse.TextToStructure | ||||
| import RPGEngine.Parse.StructureToGame | ||||
| import RPGEngine.Parse.TextToStructure (gameFile) | ||||
| 
 | ||||
| spec :: Spec | ||||
| spec = do | ||||
|  | @ -40,7 +39,7 @@ spec = do | |||
|             pendingWith "Still need to write this" | ||||
|         it "Game with multiple levels" $ do | ||||
|             pendingWith "Still need to write this" | ||||
|      | ||||
| 
 | ||||
|     describe "Player" $ do | ||||
|         it "cannot die" $ do | ||||
|             let input   = "player: { hp: infinite, inventory: [] }" | ||||
|  | @ -65,7 +64,7 @@ spec = do | |||
|                 } | ||||
|                 Right (Entry (Tag "player") struct) = parseWith structure input | ||||
|             structureToPlayer struct `shouldBe` correct | ||||
|          | ||||
| 
 | ||||
|         it "with inventory" $ do | ||||
|             let input   = "player: { hp: 50, inventory: [ { id: \"dagger\", x: 0, y: 0, name: \"Dolk\", description: \"Basis schade tegen monsters\", useTimes: infinite, value: 10, actions: {} } ] }" | ||||
|                 correct = Player { | ||||
|  | @ -95,7 +94,7 @@ spec = do | |||
|                 correct = Item { | ||||
|                     itemId          = "dagger", | ||||
|                     itemX           = 0, | ||||
|                     itemY           = 0,  | ||||
|                     itemY           = 0, | ||||
|                     itemName        = "Dagger", | ||||
|                     itemDescription = "Basic dagger you found somewhere", | ||||
|                     itemValue       = Just 10, | ||||
|  | @ -104,7 +103,7 @@ spec = do | |||
|                 } | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToItem struct `shouldBe` correct | ||||
|          | ||||
| 
 | ||||
|         it "with actions" $ do | ||||
|             let input   = "{ id: \"key\", x: 3, y: 1, name: \"Doorkey\", description: \"Unlocks a secret door\", useTimes: 1, value: 0, actions: { [not(inventoryFull())] retrieveItem(key), [] leave() } }" | ||||
|                 correct = Item { | ||||
|  | @ -122,30 +121,36 @@ spec = do | |||
|                 } | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToItem struct `shouldBe` correct | ||||
|      | ||||
| 
 | ||||
|     describe "Actions" $ do | ||||
|         it "no conditions" $ do | ||||
|             let input   = "{[] leave()}" | ||||
|                 correct = [([], Leave)] | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToActions struct `shouldBe` correct | ||||
|          | ||||
| 
 | ||||
|         it "single condition" $ do | ||||
|             let input   = "{ [inventoryFull()] useItem(itemId)}" | ||||
|                 correct = [([InventoryFull], UseItem "itemId")] | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToActions struct `shouldBe` correct | ||||
|          | ||||
| 
 | ||||
|         it "multiple conditions" $ do | ||||
|             let input   = "{ [not(inventoryFull()), inventoryContains(itemId)] increasePlayerHp(itemId)}" | ||||
|                 correct = [([Not InventoryFull, InventoryContains "itemId"], IncreasePlayerHp "itemId")] | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToActions struct `shouldBe` correct | ||||
|          | ||||
|         it "DecreaseHp(entityid, itemid)" $ do | ||||
|             let input   = "{ [] decreaseHp(devil, sword) }" | ||||
|                 correct = [([], DecreaseHp "devil" "sword")] | ||||
|                 Right struct = parseWith structure input | ||||
|             structureToActions struct `shouldBe` correct | ||||
| 
 | ||||
|     describe "Entities" $ do | ||||
|         it "Simple entity" $ do | ||||
|             pendingWith "still need to write this" | ||||
|      | ||||
| 
 | ||||
|     describe "Level" $ do | ||||
|         it "Simple layout" $ do | ||||
|             let input   = "{ layout: { | * * * * * *\n| * s . . e *\n| * * * * * *\n }, items: [], entities: [] }" | ||||
|  |  | |||
|  | @ -146,10 +146,14 @@ spec = do | |||
|                 correct = Right $ Regular $ Action $ UseItem "secondId" | ||||
|             parseWith regular input `shouldBe` correct | ||||
| 
 | ||||
|             let input   = "decreaseHp(entityId,objectId)" | ||||
|             let input   = "decreaseHp(entityId, objectId)" | ||||
|                 correct = Right $ Regular $ Action $ DecreaseHp "entityId" "objectId" | ||||
|             parseWith regular input `shouldBe` correct | ||||
| 
 | ||||
|             let input   = "decreaseHp(entityId,objectId)" | ||||
|                 correct = Right $ Regular $ Action $ DecreaseHp "entityId" "objectId" | ||||
|             parseWith regular input `shouldBe` correct | ||||
|              | ||||
|             let input   = "increasePlayerHp(objectId)" | ||||
|                 correct = Right $ Regular $ Action $ IncreasePlayerHp "objectId" | ||||
|             parseWith regular input `shouldBe` correct | ||||
|  |  | |||
		Reference in a new issue