packages feed

MazesOfMonad 1.0.1 → 1.0.2

raw patch · 8 files changed

+97/−11 lines, 8 files

Files

MazesOfMonad.cabal view
@@ -1,5 +1,5 @@ Name:                MazesOfMonad
-Version:             1.0.1
+Version:             1.0.2
 Description:         MazesOfMonad is a console-based Role Playing Game. You create characters
 	with their strong and weak points, and try to complete mazes that are randomly generated. You can pick up gold and items on the way,
 	meet monsters, and deal with them as you want. You can fight, use magic, bribe, trade, steal... This is only a simple game that I did to see what building a 
@@ -16,7 +16,7 @@ 	regex-posix, containers, filepath, directory, pretty, haskell98, 
 	array, mtl, old-locale, time
 tested-with:         GHC==6.10.1
-data-files:          README.txt, WHATSNEW.txt
+data-files:          README.txt, WHATSNEW.txt, TODO.txt
 
 Executable:          mazesofmonad
 Main-is:             Main.hs
+ TODO.txt view
@@ -0,0 +1,8 @@+- traps in maze (can be detected)
+- npcs can choose to bribe/pray/escape
+- npcs can use magic?
+- difficulty level
+	- npc attitude down (except peddlers?)
+	- traps up
+	- items up
+- message displayed when characteristic goes up
WHATSNEW.txt view
@@ -1,5 +1,9 @@+1.0.2:
+	Fix: when a monster yielding a two-handed weapon was killed, two instances of the weapon were dropped
+		Thanks to Christopher Skrzętnicki
 1.0.1:
 	Fix issue on Y/N question (crash on hitting enter directly, now uses default value correctly)
+		Thanks to Justin Bailey
 	
 1.0:
 	Initial release
src/MoresmauJP/Rpg/Arena.hs view
@@ -334,7 +334,7 @@ 			put (gs{gsData=ar2{es=Just Finished},screen=Nothing})
 			return (WText (printf "Your arguments failed to convince the %s!" (name c2b)))
 		rr->do
-			gained<-getItemsFromNPC rr listCarriedItemsU
+			gained<-getItemsFromNPC rr listCarriedItemsUniqueObject
 			let msg=(printf "The %s finds your religion attractive " (name c2b)) ++
 				(case gained of
 					(0,0)->"but has nothing to give you"
@@ -367,7 +367,7 @@ 			put (gs{gsData=ar{es=Just Finished,arenaOpponent=npc3},screen=Nothing})
 			return (WText (printf "You fail to steal anything from the the %s!" (name c2b)))
 		rr->do
-			gained<-getItemsFromNPC rr ((filter (\(p,_)->not $ isActive p)) . listCarriedItemsU)
+			gained<-getItemsFromNPC rr ((filter (\(p,_)->not $ isActive p)) . listCarriedItemsUniqueObject)
 			let msg=
 				(case gained of
 					(0,0)->"You find nothing valuable to steal"
src/MoresmauJP/Rpg/Inventory.hs view
@@ -3,7 +3,7 @@ module MoresmauJP.Rpg.Inventory (
 	Inventory(), Position(..), ItemType(..), InventoryError(..),PotionType(..),
 	makeEmptyInventory, makeFullInventory, takeItem, dropItem, listItems, 
-	listAllowedPositions,listActiveItems,listCarriedItems,listCarriedItemsU,
+	listAllowedPositions,listActiveItems,listCarriedItems,listCarriedItemsUniqueObject,
 	getCarriedItem,	positionAllowed, addGold, getGold,
 	Gold, isActive
 	) where
@@ -176,9 +176,15 @@ listCarriedItems :: Inventory -> [(Position,ItemType)]	
 listCarriedItems i = map (\(x,y)->(x,fromJust y)) (filter (isJust . snd) (listItems i))
 	
-listCarriedItemsU :: Inventory -> [(Position,ItemType)]	
-listCarriedItemsU i = nubBy (\x y -> (snd x)==(snd y)) (map (\(x,y)->(x,fromJust y)) (filter (isJust . snd) (listItems i)))
+listCarriedItemsUniqueType :: Inventory -> [(Position,ItemType)]	
+listCarriedItemsUniqueType = nubBy (\x y -> (snd x)==(snd y)) . listCarriedItems
 
+listCarriedItemsUniqueObject :: Inventory -> [(Position,ItemType)]	
+listCarriedItemsUniqueObject = (filter f) . listCarriedItems
+	where 
+		f (LeftHand,Weapon{hands=2})=False
+		f _=True
+	
 	
 getCarriedItem :: Inventory -> Position ->  Either InventoryError (Maybe ItemType)
 getCarriedItem (Inventory {invItems=m,invBagCapacity=sz}) pos=do
src/MoresmauJP/Rpg/MazeObjects.hs view
@@ -104,7 +104,7 @@ killNPC :: GameWorld -> MazeObjects -> Character -> (MazeObjects,Character,Gold)
 killNPC gw mo c@(Character {inventory=inv})= let
 	killed=fromJust $ M.lookup (position gw) (npcs mo)
-	killedItems=map snd (listCarriedItems $ inventory $ npcCharacter killed)
+	killedItems=map snd (listCarriedItemsUniqueObject $ inventory $ npcCharacter killed)
 	mo2=foldl (\mazeobj item->dropItem gw mazeobj item) mo killedItems
 	extraGold=getGold $ inventory $ npcCharacter killed
 	c2=c{inventory=addGold inv extraGold}
src/MoresmauJP/Rpg/MazeObjectsTests.hs view
@@ -2,17 +2,85 @@ -- (c) JP Moresmau 2009
 module MoresmauJP.Rpg.MazeObjectsTests where
 
+import qualified Data.Map as M
+
+import MoresmauJP.Maze1.Maze
+import MoresmauJP.Rpg.Character
+import MoresmauJP.Rpg.CharacterTests
 import MoresmauJP.Rpg.Inventory
 import MoresmauJP.Rpg.MazeObjects
+import MoresmauJP.Rpg.NPC
+import MoresmauJP.Rpg.NPCTests
 
 import MoresmauJP.Util.Random
 
+import System.Random
+
 import Test.HUnit
 
-mazeObjectsTests=TestList [testScrollFill]
+mazeObjectsTests=TestList [testScrollFill,testKillNPC,testKillNPC2HandBag,testKillNPC2HandHand]
 
 testScrollFill= TestLabel "Test filling scroll" (TestCase (do
 	let sc=Scroll "" "" 5
 	sc2<-evalRandT (generateScroll sc) (mkTestWrapper [2])
 	assertEqual "not proper scroll" (Scroll "Scroll of Feel Better" "Feel Better" 5) sc2
-	))+	))
+	
+testKillNPC=TestLabel "Test kill NPC" (TestCase (do
+	std<-getStdGen
+	gw0<-(evalRandT (generateGameWorld (2,2)) (ProductionRandom std)) 
+	
+	let 
+		gw=gw0{position=(0,0)}
+		jp=createTestChar "JP"
+		item=Weapon "Sword" 2 6 1 10
+		v1=(createTestNPC "Victim")
+		vc1=(npcCharacter v1){inventory=makeFullInventory [(Bag 1,item)] 10 100}
+		victim=v1{npcCharacter=vc1}
+		mz=MazeObjects M.empty (M.fromList [((0,0),victim)])
+		(mz2,jp2,g)=killNPC gw mz jp
+		dropped=M.lookup (0,0) (items mz2)
+	assertEqual "Gold in JP's pocket is not 100" 100 (getGold $ inventory jp2)
+	assertEqual "Gold message is not 100" 100 g
+	assertEqual "item not dropped" (Just [item]) dropped
+	))
+	
+testKillNPC2HandBag=TestLabel "Test kill NPC 2 Handed weapon in Bag" (TestCase (do
+	std<-getStdGen
+	gw0<-(evalRandT (generateGameWorld (2,2)) (ProductionRandom std)) 
+	
+	let 
+		gw=gw0{position=(0,0)}
+		jp=createTestChar "JP"
+		item=Weapon "2 Handed Sword" 4 12 2 20
+		v1=(createTestNPC "Victim")
+		vc1=(npcCharacter v1){inventory=makeFullInventory [(Bag 1,item)] 10 100}
+		victim=v1{npcCharacter=vc1}
+		mz=MazeObjects M.empty (M.fromList [((0,0),victim)])
+		(mz2,jp2,g)=killNPC gw mz jp
+		dropped=M.lookup (0,0) (items mz2)
+	assertEqual "Gold in JP's pocket is not 100" 100 (getGold $ inventory jp2)
+	assertEqual "Gold message is not 100" 100 g
+	assertEqual "item not dropped" (Just [item]) dropped
+	))	
+	
+testKillNPC2HandHand=TestLabel "Test kill NPC 2 Handed weapon in Hand" (TestCase (do
+	std<-getStdGen
+	gw0<-(evalRandT (generateGameWorld (2,2)) (ProductionRandom std)) 
+	
+	let 
+		gw=gw0{position=(0,0)}
+		jp=createTestChar "JP"
+		item=Weapon "2 Handed Sword" 4 12 2 20
+		v1=(createTestNPC "Victim")
+		inv1=makeFullInventory [] 10 100
+		Right (inv2,_)=MoresmauJP.Rpg.Inventory.takeItem inv1 item RightHand
+		vc1=(npcCharacter v1){inventory=inv2}
+		victim=v1{npcCharacter=vc1}
+		mz=MazeObjects M.empty (M.fromList [((0,0),victim)])
+		(mz2,jp2,g)=killNPC gw mz jp
+		dropped=M.lookup (0,0) (items mz2)
+	assertEqual "Gold in JP's pocket is not 100" 100 (getGold $ inventory jp2)
+	assertEqual "Gold message is not 100" 100 g
+	assertEqual "item not dropped" (Just [item]) dropped
+	))	
src/MoresmauJP/Rpg/Trade.hs view
@@ -49,7 +49,7 @@ listTradeItems' inv1 inv2 rr f=
 	let 
 		maxGold=getGold inv1
-		forSale=map (\a-> (a,valueOfItem rr a f)) (listCarriedItemsU inv2)
+		forSale=map (\a-> (a,valueOfItem rr a f)) (listCarriedItemsUniqueObject inv2)
 	in filter (\a->(snd a) <=maxGold) forSale
 	
 valueOfItem::RollResult -> (Position,ItemType) -> (Int -> RollResult -> Int)-> Gold