packages feed

venzone-1.0.0.0: src/Meeple/Operate.hs

module Meeple.Operate ( module M, module Meeple.Operate ) where

import Meeple.Primitives as M

import Lens.Micro.Platform
import Terminal.Game

import qualified Data.Char     as C
import qualified Line.Draw     as D


casualRandom :: (Random a, HasCasual c) => (a, a) -> c -> (a, c)
casualRandom bs c = let g       = c ^. seed
                        (i, g') = getRandom bs g in
                    (i, c & seed .~ g')


-- bool: long lock ani?
updateLockAni :: Bool -> Meeple -> Meeple
updateLockAni b (MLock l) =
            let i  = l ^. currNumeral
                a' | i >= 0    = lockAni i
                   | otherwise = creaStaticAnimation (cell '?')
                l' = l & draw .~ a'
            in

            if b then MLock l'
                 else MLock (l' & draw %~ lapse)
    where
          lockAni 0  =
                    creaAnimation
                      [(1, cell '\\'),
                       (1, cell '-'),
                       (1, cell '/')]
          lockAni wi = let n = 1
                           c = C.intToDigit . fromIntegral $ wi in
                    creaAnimation
                      [(n, cell '\\'),
                       (n, cell '-'),
                       (n, cell '/'),
                       (n, cell c)]
updateLockAni _ m       = m

isDead :: Meeple -> Bool
isDead (MDead _) = True
isDead _         = False

isPlayer :: Meeple -> Bool
isPlayer (MPlayer _) = True
isPlayer _           = False

-- if you have moved, unset new property
oldPlayer :: Player -> Player
oldPlayer p
        | not (p ^. isNew)     = p
        | p ^. speed == (0, 0) = p
        | otherwise            = p & isNew .~ False


hasSteps :: Meeple -> Bool
hasSteps (MDead _)   = False
hasSteps (MBird b)   = (not . null) (b ^. steps)
hasSteps (MDumb d)   = (not . null) (d ^. steps)
hasSteps (MKram k)   = (not . null) (k ^. steps)
hasSteps (MLock _)   = False
hasSteps (MNettle _) = False
hasSteps (MPlayer p) = (not . null) (p ^. steps)
hasSteps (MSave _)   = False
hasSteps (MSmart s)  = (not . null) (s ^. steps)
hasSteps (MSickle s) = (not . null) (s ^. steps)
hasSteps (MStar _)   = False
hasSteps (MStone s)  = (not . null) (s ^. steps)
hasSteps (MWin w)    = (not . null) (w ^. steps)
hasSteps (MWitch b)   = (not . null) (b ^. steps)

dropStep :: Meeple -> Meeple
dropStep m@(MDead _)   = m
dropStep m@(MBird _)   = m & steps %~ tail
dropStep m@(MDumb _)   = m & steps %~ tail
dropStep m@(MKram _)   = m & steps %~ tail
dropStep m@(MLock _)   = m
dropStep m@(MNettle _) = m
dropStep m@(MPlayer _) = m & steps %~ tail
dropStep m@(MSave _)   = m
dropStep m@(MSmart _)  = m & steps %~ tail
dropStep m@(MSickle _) = m & steps %~ tail
dropStep m@(MStar _)   = m
dropStep m@(MStone _)  = m & steps %~ tail
dropStep m@(MWin _)    = m & steps %~ tail
dropStep m@(MWitch _)   = m & steps %~ tail

safePrevPos :: Meeple -> Coords
safePrevPos (MDead _)     = error "safePrevPos"
safePrevPos m@(MBird _)   = m ^. prevPos
safePrevPos m@(MDumb _)   = m ^. prevPos
safePrevPos m@(MKram _)   = m ^. prevPos
safePrevPos m@(MLock _)   = m ^. position
safePrevPos m@(MNettle _) = m ^. position
safePrevPos m@(MPlayer _) = m ^. prevPos
safePrevPos m@(MSave _)   = m ^. position
safePrevPos m@(MSickle _) = m ^. prevPos
safePrevPos m@(MStar _)   = m ^. position
safePrevPos m@(MSmart _)  = m ^. prevPos
safePrevPos m@(MStone _)  = m ^. prevPos
safePrevPos m@(MWin _)    = m ^. prevPos
safePrevPos m@(MWitch _)   = m ^. prevPos

-- this generates the projectile and decides whether it is gonna be
-- spawned or aborted
genProj :: Meeple -> Meeple
genProj (MBird b) = let cs = b ^. position
                        b' = b & ready ?~ MRStone cs
                    in MBird $ spawnOrNot (1, 8) b'
genProj (MKram k) = let cs = k ^. position
                        -- (sh, k') = casualRandom (-1, 1) k
                        -- non un bel effetto grafico
                        k' = k & ready ?~ MRSickle cs (-1, 0)
                    in MKram $ spawnOrNot (1, 5) k'
genProj m@MDead {}         = m
genProj m@MPlayer {}         = m
genProj m@MStar {}         = m
genProj m@MLock {}         = m
genProj m@MNettle {}         = m
genProj m@MSickle {}         = m
genProj m@MStone {}         = m
genProj m@MDumb {}         = m
genProj m@MSmart {}         = m
genProj m@MWin {}         = m
genProj m@MWitch {}         = m
genProj m@MSave {}         = m

-- let the generated meeplelive or else
spawnOrNot :: (HasGenerator g, HasCasual g) => (Integer, Integer) -> g -> g
spawnOrNot (t, n) g =
            let (i, g') = casualRandom (1, n) g
            in if i <= t then g'                    -- let it live
                         else g' & ready .~ Nothing -- cull it


-------------
-- OPERATE --
-------------

generateSteps :: Meeple -> Meeple
generateSteps m = let ss = D.bresenham (0, 0) (m ^. speed)
                      mf (a, b) (c, d) = (a-c, b-d)
                  in m & steps .~ zipWith mf (tail ss) ss

-- touch animation
touchSave :: Save -> Save
touchSave s = s & draw .~ ani
    where
          ani = creaAnimation
                  [(2, cell '@' # color Blue Vivid),
                   (3, cell '+' # color Yellow Vivid # bold),
                   (3, cell '@' # color Blue Vivid),
                   (3, cell '+' # color Yellow Vivid # bold),
                   (3, cell '@' # color Blue Vivid)]


-- inquire --

-- similar folks don't hit each other
isSimilar :: Meeple -> Meeple -> Bool
isSimilar ma mb = meepleCategory ma == meepleCategory mb

isStingy :: Nettle -> Bool
isStingy n = (n ^. draw . to fetchFrame . to paperPlane) == "A\n"

------------------
-- CONSTRUCTORS --
------------------

-- ASCII Chars:
--   !"#$%&'()*+,-./
--   0123456789
--   :;<=>?@
--   ABCDEFGHIJKLMNOPQRSTUVWXYZ
--   [\]^_`
--   abcdefghijklmnopqrstuvwxyz
--   {|}

creaRef :: MeepRef -> [Meeple]
creaRef (MRStone cs)     = [s (-1), s 0, s 1]
    where
          s :: Integer -> Meeple
          s mh = MStone $ defaultStone (cs & _1 %~ (+1)
                                           & _2  %~(+mh))
creaRef (MRSickle cs sp) = [MSickle $ defaultSickle
                                        (cs & _1 %~ subtract 1)
                                        sp]