starrover2-0.0.9: src/SpaceState/Combat.hs
module SpaceState.Combat(startCombat)
where
import System.Random
import Data.List
import Data.Maybe
import Control.Monad
import Control.Monad.State as State
import Prelude hiding (catch)
import Graphics.Rendering.OpenGL as OpenGL
import Graphics.UI.SDL as SDL
import qualified Data.Edison.Assoc.StandardMap as M
import Combat
import Space
import Cargo
import TextScreen
import Politics
import SDLUtils
import Universe
import SpaceState.Common
import SpaceState.Game
import SpaceState.Init
import SpaceState.Difficulty
startCombat :: Maybe (String, Enemy, String) -- ^ If Nothing, use random enemy
-- and standard message. Otherwise
-- use given (msg, enemy, enemy allegiance).
-> StateT SpaceState IO (Bool, Bool) -- ^ (gameOver?, combatWon?)
startCombat n = do
state <- State.get
(s, en, enalleg) <- case n of
Nothing -> do
en' <- liftIO $ randomEnemy $ difficultyAIshift $ difficulty state
enalleg' <- liftIO $ randomAllegiance
s' <- return $
concat ["You spot another ship traveling nearby.\n",
"It seems to be a " ++ (describeEnemy en') ++ ".\n",
"The ship is part of the country of " ++ enalleg' ++ ".\n",
"Press ENTER to start a battle against the foreign ship\n",
"or ESCAPE to escape"]
return (s', en', enalleg')
Just m -> return m
c <- pressOneOfScreen
(liftIO $ makeTextScreen (100, 400)
[(gamefont state, Color4 1.0 1.0 1.0 1.0, s)]
(return ()))
[SDLK_RETURN, SDLK_ESCAPE]
if c == SDLK_RETURN
then do
enemyrot <- liftIO $ fromIntegral `fmap` randomRIO (-180, 180 :: Int)
enpos <- liftIO $ randPos ((0, 0), (50, 100))
plpos <- liftIO $ randPos ((100, 0), (150, 100))
let plrot = angleFromTo plpos enpos - 90
(newhealth, newpoints, mnewcargo) <- liftIO $ evalStateT combatLoop
(newCombat plalleg enalleg intermediate (plhealth state) plpos enpos plrot enemyrot en)
if newhealth == 0
then do
releaseKeys
gameover <- lostLife "You fought bravely, but your ship was blown to pieces." recoveryText
return (gameover, False)
else do
modify $ modPlHealth $ const newhealth
case mnewcargo of
Nothing -> do
liftIO $ makeTextScreen (100, 400) [(gamefont state, Color4 1.0 1.0 1.0 1.0, "The enemy is out of your sight.\n\n"),
(gamefont state, Color4 1.0 1.0 1.0 1.0, "Press ENTER to continue")] (return ())
liftIO $ getSpecificSDLChar SDLK_RETURN
releaseKeys
return (False, False)
Just newcargo -> do
when (not (M.null newcargo)) $ do
modify $ modPoints (+(newpoints * (diffcoeff $ difficulty state)))
(_, cargo', _, hold') <- liftIO $ execStateT
(takeScreen ("Captured cargo")
(gamefont state) (monofont state))
(newcargo, plcargo state, plcash state, plholdspace state)
modify $ modPlCargo (const cargo')
modify $ modPlHoldspace (const hold')
killed enalleg
releaseKeys
return (False, True)
else do
releaseKeys
return (False, False)
internationalAction :: String -> Int -> StateT SpaceState IO ()
internationalAction s f = modify $ modAllegAttitudes $ consequences f s allegiances relations
killed :: String -> StateT SpaceState IO ()
killed enalleg = internationalAction enalleg (-1)