freekick2-0.1.0: src/Match/State/MatchState.hs
{-# LANGUAGE TemplateHaskell #-}
module Match.State.MatchState
where
import Control.Monad.State as State
import qualified Data.IntMap as M
import System.Random
import Graphics.Rendering.OpenGL as OpenGL
import Graphics.UI.SDL as SDL
import Graphics.Rendering.FTGL as FTGL
import Drawing
import DeriveMod
import FVector
import Gen
import Match.Ball
import Match.Player
type Formation = M.IntMap Gen.Tactic
data Restart = ThrowIn FRange
| GoalKick FRange
| CornerKick FRange
getRestartPoint :: Restart -> FRange
getRestartPoint (ThrowIn r) = r
getRestartPoint (GoalKick r) = r
getRestartPoint (CornerKick r) = r
data BallPlay = BeforeKickoff
| WaitForKickoff Int
| DoKickoff
| InPlay
| OutOfPlayWaiting Int Restart -- ai does nothing
| OutOfPlay Int Restart -- ai moves to positions
| RestartPlay Restart -- ai restarts play
| Finished Int
data MatchEvent = BallKicked
type PlayerMap = M.IntMap Player
data Team = Team {
players :: PlayerMap
, formation :: Formation
, goals :: Int
, teamname :: String
, teamowner :: TeamOwner
}
$(deriveMods ''Team)
data MatchParams = MatchParams {
matchtimedelta :: Float -- time increase in seconds/frame
, kickofftimer :: Int -- time to spend in WaitForKickoff (ms)
, kickoffballtimer :: Int -- time after ball is centered in WaitForKickoff (ms)
, oopthrowintimer :: Int -- time to spend in OutOfPlayWaiting (throwin) (ms)
, oopgoalkicktimer :: Int -- time to spend in OutOfPlayWaiting (goal kick) (ms)
, oopcornerkicktimer :: Int -- time to spend in OutOfPlayWaiting (corner kick) (ms)
, ooptimer :: Int -- time to spend in OutOfPlay (ms)
, oopmoveballtimer :: Int -- time after ball is moved in OutOfPlay (ms)
, ballbounciness :: Float -- 1: no bounce; 2: 100% elastic bounce
, ballgravitypull :: Float -- m/s^2 (approximate)
, ballairviscosity :: Float -- 0: none; 1/frametime(=50): complete
, ballrollfriction :: Float -- as in air viscosity
, plcontrolmin :: Float -- control coeff with control skill = 0
, plcontrolmax :: Float -- control coeff with control skill = 1
, maxkickveclen :: Float -- maximum length of kick vector
, stillpassveclen :: Float -- max. length of kick vector to still count as pass
, stillpassvecheight :: Float -- max. height of kick vector to still count as pass
, maxkickvar :: Float -- percentage [0..1] of kick target variation in x, y
, maxkickvarz :: Float -- percentage [0..1] of kick target variation in z
, setkicktimer :: Int -- kick timer in ms (max. time between kicks by a player)
, aimaxlowpasslen :: Float -- max. distance where to pass low
, ailowpasspower :: Float -- pass power coeff
, aihighpasspower :: Float -- pass power coeff
, aihighpasszpower :: Float -- pass power coeff (z)
, plspeedcoeff :: Float -- player speed coeff
, plspeedmin :: Float -- speed coeff with speed skill = 0
, kickdistance :: Float -- max kick distance
, dribbledistance :: Float -- max dribble distance
, catchdistance :: Float -- max catch distance
, maxkickheight :: Float -- max ball height for kick
, maxdribbleheight :: Float -- max ball height for dribble
, maxcatchheight :: Float -- max ball height for catch
, maxballdspeed :: Float -- max ball speed for dribbling
, ctrlquitkey :: SDLKey -- key to quit
, ctrlshootkey :: SDLKey -- key to shoot
, ctrlleftkey :: SDLKey
, ctrlrightkey :: SDLKey
, ctrlupkey :: SDLKey
, ctrldownkey :: SDLKey
, ctrlpausekey :: SDLKey
}
defaultParams = MatchParams
30 2000 1000 -- general
1000 1000 1000 1000 1000 -- oop
1.5 (-10) 0.5 1.2 -- ball
0.6 0.8 -- control
50 -- kick
20 2 -- pass
0.5 0.5 -- kick variation
1000 -- kick timer
30 4 1.5 0.5 -- ai pass
20 0.7 -- speed
1.2 0.6 2.0 -- max distances
0.8 0.5 2.4 -- max heights
40 -- max ball dribble speed
SDLK_ESCAPE SDLK_RCTRL SDLK_LEFT SDLK_RIGHT SDLK_UP SDLK_DOWN SDLK_p
data MatchState = MatchState {
pitchlist :: DisplayList
, matchgoal1 :: ImageInfo
, matchgoal2 :: ImageInfo
, matchgoal1shadow :: ImageInfo
, matchgoal2shadow :: ImageInfo
, currkeys :: [SDLKey]
, pitchsize :: (Float, Float)
, campos :: (Float, Float)
, hometeam :: Team
, awayteam :: Team
, controlledpl :: Maybe PlayerID
, ballplay :: BallPlay
, ball :: Ball
, pendingevents :: [MatchEvent]
, lasttouch :: Maybe PlayerID
, matchfont1 :: Font
, matchfont2 :: Font
, randomgen :: StdGen
, matchtime :: (Bool, Float) -- half time?, seconds
, paused :: Bool
, kickpower :: Int
, frametime :: Float
, homekickoff :: Bool
, homeattacksup :: Bool
, params :: MatchParams
}
$(deriveMods ''MatchState)
modHomeplayers :: (PlayerMap -> PlayerMap) -> MatchState -> MatchState
modHomeplayers f = modHometeam (modPlayers f)
modAwayplayers :: (PlayerMap -> PlayerMap) -> MatchState -> MatchState
modAwayplayers f = modAwayteam (modPlayers f)
sModHomegoals :: (Int -> Int) -> Match ()
sModHomegoals f = modify $ modHometeam (modGoals f)
sModAwaygoals :: (Int -> Int) -> Match ()
sModAwaygoals f = modify $ modAwayteam (modGoals f)
modPlayer :: PlayerID -> (Player -> Player) -> MatchState -> MatchState
modPlayer (pln, True) f = modHomeplayers (M.adjust f pln)
modPlayer (pln, False) f = modAwayplayers (M.adjust f pln)
homeplayers :: MatchState -> PlayerMap
homeplayers = players . hometeam
awayplayers :: MatchState -> PlayerMap
awayplayers = players . awayteam
hometeamname :: MatchState -> String
hometeamname = teamname . hometeam
awayteamname :: MatchState -> String
awayteamname = teamname . awayteam
homegoals :: MatchState -> Int
homegoals = goals . hometeam
awaygoals :: MatchState -> Int
awaygoals = goals . awayteam
homeformation :: MatchState -> Formation
homeformation = formation . hometeam
awayformation :: MatchState -> Formation
awayformation = formation . awayteam
findPlayer :: PlayerID -> MatchState -> Maybe Player
findPlayer (pln, True) m = M.lookup pln (homeplayers m)
findPlayer (pln, False) m = M.lookup pln (awayplayers m)
modAllPlayers :: (Player -> Player) -> MatchState -> MatchState
modAllPlayers f m = modHomeplayers (M.map f) (modAwayplayers (M.map f) m)
sModAllPlayers ::
(Player -> Player) -> Match ()
sModAllPlayers f = modify $ modAllPlayers f
sModPlayer ::
PlayerID -> (Player -> Player) -> Match ()
sModPlayer p f = modify $ modPlayer p f
type Match = StateT MatchState IO