module Lineup where import Debug.Trace import Data.List import Data.Maybe import Data.Ord import FRP.Yampa import FRP.Yampa.Geometry import Object import ObjectBehaviour import Message import AL import Global import BasicTypes import Helper import States import Physics lineupKickoff :: Param -> ALOut -> Time -> Team -> Int -> Int -> (ALOut, ALObj) lineupKickoff param alout time' possession scoreHome scoreAway = let (homeOos, homeObjs, maybeHomeKickers) = lineupKickoffTeam param alout Home (possession == Home) (awayOos, awayObjs, maybeAwayKickers) = lineupKickoffTeam param alout Away (possession == Away) (kicksOff, _) = if maybeHomeKickers == Nothing then fromJust maybeAwayKickers else fromJust maybeHomeKickers bid = ballId alout gid = gameId alout (ballOos, ballObjs) = lineupKickoffBall param bid kicksOff time' (gameOos, gameObjs) = lineupKickoffGame param gid time' possession scoreHome scoreAway in #if DEBUG_MODE trace ("Lineup durchgeführt" ++ show ((ballOos `appendAL` gameOos `appendAL` homeOos `appendAL` awayOos)) ++ show "Home=" ++ show (map fst $ assocsAL homeObjs) ++ show "Away=" ++ show (map fst $ assocsAL awayObjs)) $ #endif (ballOos `appendAL` gameOos `appendAL` homeOos `appendAL` awayOos, ballObjs `appendAL` gameObjs `appendAL` homeObjs `appendAL` awayObjs) -- ************************************************************************* -- -- Player lineups -- -- ************************************************************************* -- returns the lineup for given team on kickoff, depending on whether team -- kicks off or nor, and also the player who has the ball on kickoff (if any) lineupKickoffTeam :: Param -> ALOut -> Team -> Bool -> (ALOut, ALObj, Maybe (ObjId, ObjId)) lineupKickoffTeam param oos team kicksoff = let players = (filterAL ((== team) . fst3 . oosTeamInfo) . mapAL (ooObsObjState . snd) . filterAL isPlayerOO) oos sorted = fromAssocs $ sortBy (\(_, oos') (_, oos'') -> comparing dist oos' oos'') $ assocsAL players (kicksOffPlId, kicksOffPl) = sorted `at` 0 (kickedToPlId, kickedToPl) = sorted `at` 1 kickOffSpot = Point2 (pPitchWidth param / 2) (pPitchLength param / 2) dist oos' = distance (basePos oos') kickOffSpot basePls = if kicksoff then deleteAL kicksOffPlId $ deleteAL kickedToPlId players else players (baseOuts, baseObjs) = mkBase param team basePls (kicksOut, kicksObjs) = if kicksoff then mkObjs param team (kicksOffPlId, kicksOffPl) (kickedToPlId, kickedToPl) else (emptyAL, emptyAL) in (baseOuts `appendAL` kicksOut, baseObjs `appendAL` kicksObjs, if kicksoff then Just (kicksOffPlId, kickedToPlId) else Nothing ) isPlayerOO :: ObjOutput -> Bool isPlayerOO (ObjOutput {ooObsObjState = OOSPlayer {}}) = True isPlayerOO _ = False mkBase :: Param -> Team -> AL ObjId ObsObjState -> (AL ObjId ObjOutput, AL ObjId Object) mkBase param team oos = (mapAL (mkStandardPlayerObjOutput . snd) oos, mapAL (uncurry (mkStandardPlayerObject param team)) oos) mkObjs :: Param -> Team -> (ObjId, ObsObjState) -> (ObjId, ObsObjState) -> (AL ObjId ObjOutput, AL ObjId Object) mkObjs param team (fromId, fromPl) (toId, toPl) = let toOut = mkKickedToPlayerObjOutput param team toPl toObj = mkKickedToPlayerObject param toId team toPl fromOut = mkKicksOffPlayerObjOutput param team fromPl fromObj = mkKicksOffPlayerObject param fromId team fromPl in (fromAssocs [(toId, toOut), (fromId, fromOut)], fromAssocs [(toId, toObj), (fromId, fromObj)]) basePos :: ObsObjState -> Point2 Double basePos = piBasePosDefense. oosPlayerInfo kicksOffPosition :: Param -> Team -> Point2 Double kicksOffPosition param team -- | team == Home = Point2 42 52 -- basierend auf 80, 96 muss man noch verformeln -- | team == Away = Point2 38 44 | team == Home = Point2 (pPitchWidth param / 2 + 2) (pPitchLength param / 2 + 1) | team == Away = Point2 (pPitchWidth param / 2 - 2) (pPitchLength param / 2 - 1) kickedToPosition :: Param -> Team -> Point2 Double kickedToPosition param team -- | team == Home = Point2 35 50 -- | team == Away = Point2 45 46 | team == Home = Point2 (pPitchWidth param / 2 - 5) (pPitchLength param / 2) | team == Away = Point2 (pPitchWidth param / 2 + 5) (pPitchLength param / 2) ---------------------------------------------------------------------------------- -- -- create ObjOutput for player -- ---------------------------------------------------------------------------------- mkpoo :: Position2 -> ObsObjState -> ObjOutput mkpoo pos oos = ObjOutput oos {oosPos = pos .+! 0} NoEvent NoEvent [] mkStandardPlayerObjOutput :: ObsObjState -> ObjOutput mkStandardPlayerObjOutput oos = mkpoo (basePos oos) oos mkKickedToPlayerObjOutput :: Param -> Team -> ObsObjState -> ObjOutput mkKickedToPlayerObjOutput param = mkpoo . kickedToPosition param mkKicksOffPlayerObjOutput :: Param -> Team -> ObsObjState -> ObjOutput mkKicksOffPlayerObjOutput param = mkpoo . kicksOffPosition param ---------------------------------------------------------------------------------- -- -- create Object for player -- ---------------------------------------------------------------------------------- mkpo :: Param -> ObjId -> ObsObjState -> Position2 -> BasicState -> Angle -> Object mkpo param oid oos pos pbsInit angle0 = maker param oid 0 pos (vector3 0 0 0) angle0 (oosSelected oos) False --(oosDesignated oos) (oosTeamInfo oos) (oosPlayerInfo oos) pbsInit NoFoot (if (== Goalie) . piPlayerRole . oosPlayerInfo $ oos then TSGoalieWaitingForKickOff else if ai then TSWaitingForKickOff else TSNonAIKickingOff) where ai = not $ oosSelected oos maker = if ai then playerAI else player mkStandardPlayerObject :: Param -> Team -> ObjId -> ObsObjState -> Object mkStandardPlayerObject param team oid oos = mkpo param oid oos (basePos oos) PBSNoBall (if team == Home then 3*pi/2 else pi/2) mkKickedToPlayerObject :: Param -> ObjId -> Team -> ObsObjState -> Object mkKickedToPlayerObject param oid team oos = mkpo param oid oos (kickedToPosition param team) PBSNoBall (if team == Home then 0 else pi) mkKicksOffPlayerObject :: Param -> ObjId -> Team -> ObsObjState -> Object mkKicksOffPlayerObject param oid team oos = mkpo param oid oos (kicksOffPosition param team) PBSInPossession (if team == Home then pi else 0) -- ************************************************************************* -- -- Ball lineup -- -- ************************************************************************* lineupKickoffBall :: Param -> ObjId -> ObjId -> Time -> (ALOut, ALObj) lineupKickoffBall param ballId' playerId t0 = let (_, bobjs, boos) = mkBallInPossession param ballId' playerId t0 False playerId (pitchCenter param .+! 0) (vector3 0 0 0) [] in (fromAssocs [(ballId', boos)], fromAssocs [(ballId', bobjs)]) -- ************************************************************************* -- -- Game lineup -- -- ************************************************************************* lineupKickoffGame :: Param -> ObjId -> Time -> Team -> Int -> Int -> (ALOut, ALObj) lineupKickoffGame param oid time' possession scoreHome scoreAway = let goos = ObjOutput (OOSGame time' (scoreHome, scoreAway) (GSKickOff, GPTeamPosition possession 100 [] (pitchCenter param) time' True InPlay) possession (Point3 (-10) (-10) 0)) NoEvent NoEvent [] gobj = game param oid possession scoreHome scoreAway time' in (fromAssocs [(oid, goos)], fromAssocs [(oid, gobj)])