Skip to content

Commit

Permalink
refactor hero selection code; surprisingly small now
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikolaj committed Feb 12, 2011
1 parent 780d118 commit 11f89ad
Showing 1 changed file with 31 additions and 55 deletions.
86 changes: 31 additions & 55 deletions src/Actions.hs
Expand Up @@ -302,71 +302,47 @@ fleeDungeon =
-- | Switches current hero to the next hero on the level, if any, wrapping. -- | Switches current hero to the next hero on the level, if any, wrapping.
cycleHero = cycleHero =
do do
hs <- gets (lheroes . slevel) hs <- gets (lheroes . slevel)
nln <- gets (lname . slevel)
player <- gets splayer player <- gets splayer
look <- gets slook let i = heroNumber player
case look of (lt, gt) = IM.split i hs
Just look@(Look { returnLn = ln }) case IM.keys gt ++ IM.keys lt of
| ln /= nln -> [] -> abortWith "Cannot select another hero on this level."
case IM.assocs hs of ni : _ -> selectHero ni
[] -> abortWith "No heroes on this level."
(ni, np) : _ ->
do
let i = heroNumber player
ins = IM.insert i player
pli = updateHeroes ins
del = IM.delete ni
modify (updateAnyLevel pli ln)
modify (updateLevel (updateHeroes del))
modify (updatePlayer (const np))
modify (updateLook (const (Just $ look { returnLn = nln })))
messageAdd $ "Hero number " ++ show ni ++ " selected."
_ ->
let i = heroNumber player
(lt, gt) = IM.split i hs
in case IM.assocs gt ++ IM.assocs lt of
[] -> abortWith "Only one hero on this level."
(ni, np) : _ -> swapCurrentHero (ni, np)


-- | Selects a hero based on the number. Focuses on the hero if level changed. -- | Selects a hero based on the number. Focuses on the hero if level changed.
-- Even selecting the already selected hero makes sense when in look mode
-- it focuses on the level and location of the hero.
selectHero :: Int -> Action () selectHero :: Int -> Action ()
selectHero ni = selectHero ni =
do do
state <- get state <- get
player <- gets splayer player <- gets splayer
look <- gets slook let i = heroNumber player
case findHeroLevel ni state of unless (ni == i) $ -- already selected
Nothing -> abortWith $ "No hero number " ++ show ni ++ " in the party." case findHeroLevel ni state of
Just (nln, np) -> do Nothing -> abortWith $ "No hero number " ++ show ni ++ " in the party."
let i = heroNumber player Just (nln, np) -> do
ins = IM.insert i player -- put the old player back into his original level
pli = updateHeroes ins stashPlayer
del = IM.delete ni -- switch to the level with the new hero
-- put the old player back into his original level (look mode!) lvlswitch (nln, mloc np)
modify (updateAnyLevel pli (playerLevel state)) -- make the new hero the player controlled hero
-- if in look mode, record the original level of the new hero modify (updateLevel (updateHeroes $ IM.delete ni))
modify (updateLook (fmap (\ lk -> lk { returnLn = nln }))) modify (updatePlayer (const np))
-- switch to the level with the new hero -- if in look mode, record the original level of the new hero
lvlswitch (nln, mloc np) modify (updateLook (fmap (\ lk -> lk { returnLn = nln })))
-- make the new hero the player controlled hero -- announce
modify (updateLevel (updateHeroes del)) messageAdd $ "Hero number " ++ show ni ++ " selected."
modify (updatePlayer (const np))
-- announce -- | Copies player to an ordinary hero slot on his level.
messageAdd $ "Hero number " ++ show ni ++ " selected." stashPlayer :: Action ()

stashPlayer =
swapCurrentHero :: (Int, Hero) -> Action ()
swapCurrentHero (ni, np) =
do do
state <- get
player <- gets splayer player <- gets splayer
let i = heroNumber player let i = heroNumber player
upd hs = IM.insert i player $ IM.delete ni hs ins = updateHeroes $ IM.insert i player
when (ni /= i) (do ln = playerLevel state
modify (updateLevel (updateHeroes upd)) modify (updateAnyLevel ins ln)
modify (updatePlayer (const np))
messageAdd $ "Hero number " ++ show ni ++ " selected.")


-- | Calculate loot's worth. TODO: move to another module, and refine significantly. -- | Calculate loot's worth. TODO: move to another module, and refine significantly.
calculateTotal :: State -> Int calculateTotal :: State -> Int
Expand Down Expand Up @@ -674,7 +650,7 @@ moveOrAttack allowAttacks autoOpen actor dir
-- Focus on the attacked hero, if any. This is also handy for -- Focus on the attacked hero, if any. This is also handy for
-- selecting adjacent hero by bumping into him (without running). -- selecting adjacent hero by bumping into him (without running).
-- TODO: let running switch position of hero and another hero/monster. -- TODO: let running switch position of hero and another hero/monster.
maybe (return ()) swapCurrentHero attHero maybe (return ()) (selectHero . fst) attHero
-- At the moment, we check whether there is a monster before checking -- At the moment, we check whether there is a monster before checking
-- accessibility, i.e., we can attack a monster on a blocked location. -- accessibility, i.e., we can attack a monster on a blocked location.
-- For instance, a monster on an open door can be attacked diagonally, -- For instance, a monster on an open door can be attacked diagonally,
Expand Down

0 comments on commit 11f89ad

Please sign in to comment.