starrover2-0.0.9: src/SpaceState/Game.hs
module SpaceState.Game
where
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 Graphics.Rendering.FTGL as FTGL
import qualified Data.Edison.Assoc.StandardMap as M
import OpenGLUtils
import Entity
import Camera
import AObject
import Combat
import Space
import Cargo
import Utils
import TextScreen
import Politics
import Universe
import Mission
import SpaceState.Difficulty
startState :: String -> Difficulty -> Font -> Font -> SpaceState
startState plname d f f2 = SpaceState
(newStdShipEntity (50.0, 30.0, 0.0) playerShipColor 0)
aobjs
stdCamera
False
f
f2
M.empty
maxHold
startCash
("", M.empty)
0
3
startPlHealth
d
initialAttitudes
emptyMissionMap
plname
Nothing
data SpaceState = SpaceState {
tri :: Entity
, aobjects :: AObjTree
, camstate :: CameraState
, stopped :: Bool
, gamefont :: Font
, monofont :: Font
, plcargo :: Cargo
, plholdspace :: Int
, plcash :: Int
, lastmarket :: (String, Market)
, points :: Int
, lives :: Int
, plhealth :: Int
, difficulty :: Difficulty
, allegattitudes :: AttitudeMap
, plmissions :: MissionMap
, playername :: String
, availmission :: Maybe Mission
}
-- TODO: generate mod-functions using TH
modTri :: (Entity -> Entity) -> SpaceState -> SpaceState
modTri f t = t{tri = f (tri t)}
modAObjects :: (AObjTree -> AObjTree) -> SpaceState -> SpaceState
modAObjects f t = t{aobjects = f (aobjects t)}
modCameraState :: (CameraState -> CameraState) -> SpaceState -> SpaceState
modCameraState f t = t{camstate = f (camstate t)}
modStopped :: (Bool -> Bool) -> SpaceState -> SpaceState
modStopped f t = t{stopped = f (stopped t)}
modPlCargo :: (Cargo -> Cargo) -> SpaceState -> SpaceState
modPlCargo f t = t{plcargo = f (plcargo t)}
modPlCash :: (Int -> Int) -> SpaceState -> SpaceState
modPlCash f t = t{plcash = f (plcash t)}
modPlHoldspace :: (Int -> Int) -> SpaceState -> SpaceState
modPlHoldspace f t = t{plholdspace = f (plholdspace t)}
modMarket :: ((String, Market) -> (String, Market)) -> SpaceState -> SpaceState
modMarket f t = t{lastmarket = f (lastmarket t)}
modPoints :: (Int -> Int) -> SpaceState -> SpaceState
modPoints f t = t{points = f (points t)}
modLives :: (Int -> Int) -> SpaceState -> SpaceState
modLives f t = t{lives = f (lives t)}
modPlHealth :: (Int -> Int) -> SpaceState -> SpaceState
modPlHealth f t = t{plhealth = f (plhealth t)}
modAllegAttitudes :: (AttitudeMap -> AttitudeMap) -> SpaceState -> SpaceState
modAllegAttitudes f t = t{allegattitudes = f (allegattitudes t)}
modPlMissions :: (MissionMap -> MissionMap) -> SpaceState -> SpaceState
modPlMissions f t = t{plmissions = f (plmissions t)}
modAvailMission :: (Maybe Mission -> Maybe Mission) -> SpaceState -> SpaceState
modAvailMission f t = t{availmission = f (availmission t)}
stdCamera :: CameraState
stdCamera = CameraState
((-0.01 * width, -0.01 * height), (0.02 * width, 0.02 * height))
100
0
zoomChangeFactor :: (Floating a) => a
zoomChangeFactor = 1.0
drawSpace :: StateT SpaceState IO ()
drawSpace = do
state <- State.get
modify $ modCameraState $ modCamZoom $ (+ (camzoomdelta $ camstate state))
modify $ modCameraState $ modCamera $ setZoom $ clamp 30 250 $ (camzoom $ camstate state) + (400 * (length2 $ velocity (tri state)))
modify $ modCameraState $ modCamera $ setCentre $ Entity.position (tri state)
liftIO $ setCamera (camera $ camstate state)
liftIO $ drawGLScreen Nothing [tri state] (aobjects state)
gameoverText :: String
gameoverText =
intercalate "\n"
["After escaping with your emergency capsule and",
"returning to civilization, you realize your",
"adventurous days are over."]
gameOver :: String -> String -> StateT SpaceState IO Bool
gameOver s s2 = do
state <- State.get
pressKeyScreen
(liftIO $ makeTextScreen (100, 500)
[(gamefont state, Color4 1.0 0.2 0.2 1.0, s ++ "\n\n" ++ s2 ++ "\n" ++ "\n"),
(gamefont state, Color4 1.0 1.0 1.0 1.0, "Total points: " ++ show (finalPoints state)),
(gamefont state, Color4 1.0 0.2 0.2 1.0, "Press ENTER to continue")]
(return ())) SDLK_RETURN
return True
maxHold = holdspace intermediate
startPlHealth = maxhealth intermediate
startCash = 10
finalPoints :: SpaceState -> Int
finalPoints s =
max 0 (10 *
(points s +
(diffcoeff (difficulty s)) * attitudesPoints (M.elements $ allegattitudes s) +
plcash s +
(lives s * 50) - 160))
attitudesPoints :: [Int] -> Int
attitudesPoints = floor . sum . map val
where val n | n < 0 = fromIntegral n * 0.2 :: Double
| otherwise = fromIntegral n * 50.0
allegAttitude :: String -> SpaceState -> Int
allegAttitude planetname state =
attitude (planetNameToAllegiance (aobjects state) planetname) $
allegattitudes state
relationshipsOf :: String -> [(String, Int)]
relationshipsOf n = catMaybes $ map f relationsList
where f ((n1, n2), (_, v)) = do
if n1 == n2
then Nothing
else if n1 == n
then Just (n2, v)
else if n2 == n
then Just (n1, v)
else Nothing