Files
loop/src/Dodge/Default.hs
T
2022-03-16 18:02:17 +00:00

318 lines
8.8 KiB
Haskell

{- |
Module : Dodge.Default
Description : Instances of data structures
This module contains prototypical data structures.
-}
module Dodge.Default where
import Dodge.Default.Weapon
import Dodge.Data
import Dodge.SoundLogic
import Dodge.Picture.Layer
import Dodge.Wall.Delete
import Geometry
import Picture
import ShapePicture
import Shape
import Control.Lens
import qualified Data.IntMap.Strict as IM
import qualified Data.Map.Strict as M
import qualified Data.Vector as V
import Data.List
--import Data.Monoid
defaultCreature :: Creature
defaultCreature = Creature
{ _crPos = V2 0 0
, _crOldPos = V2 0 0
, _crVel = V2 0 0
, _crDir = 0
, _crOldDir = 0
, _crMvDir = 0
, _crTwist = 0
, _crID = 1
, _crPict = \_ _ _ -> mempty
, _crUpdate = const id
, _crRad = 10
, _crMass = 10
, _crHP = 100
, _crMaxHP = 150
, _crInv = IM.empty
, _crInvSel = 0
, _crInvCapacity = 25
, _crInvLock = False
, _crInvEquipped = mempty
, _crLeftInvSel = Nothing
, _crState = defaultState
, _crCorpse = setLayer 0 $ onLayer CorpseLayer $ color (greyN 0.5) $ circleSolid 10
, _crApplyDamage = defaultApplyDamage
, _crStance = Stance
{_carriage=Walking 0 WasLeftForward
,_posture=AtEase
,_strideLength = yourDefaultStrideLength
}
, _crVocalization = Mute
, _crActionPlan = ActionPlan [] [] WatchAndWait [LiveLongAndProsper]
, _crPerception = defaultPerceptionState
, _crMemory = defaultCreatureMemory
, _crMeleeCooldown = 0
, _crFaction = NoFaction
, _crIntention = defaultIntention
, _crGroup = LoneWolf
, _crMvType = defaultAimMvType
}
defaultInanimate :: Creature
defaultInanimate = defaultCreature & crActionPlan .~ Inanimate
defaultCreatureMemory :: MemoryState
defaultCreatureMemory = MemoryState
{ _soundsToInvestigate = []
}
defaultInvSize :: Int
defaultInvSize = 20
defaultPerceptionState :: PerceptionState
defaultPerceptionState = PerceptionState
{ _crAwakeLevel = Lethargic
, _crAttentionDir = AttentiveTo IM.empty
, _crAwarenessLevel = IM.empty
, _crVision = defaultVision
, _crAudition = defaultAudition
}
defaultVision :: Vision
defaultVision = Eyes
{ _viFOV = f
, _viDist = g
}
where
f x | abs x < 0.5 * pi = 1
| otherwise = 0
g x | x > 500 = 0
| otherwise = 1
defaultAudition :: Audition
defaultAudition = Ears
{ _auDist = \x -> x * x
}
defaultIntention :: Intention
defaultIntention = Intention
{ _targetCr = Nothing
, _mvToPoint = Nothing
, _viewPoint = Nothing
}
defaultChaseMvType :: CrMvType
defaultChaseMvType = ChaseMvType
{ _mvSpeed = 3
, _mvTurnRad = f
, _mvTurnJit = 0.2
}
where
f x | x > pi / 4 = 0.2
| otherwise = 0.05
defaultAimMvType :: CrMvType
defaultAimMvType = AimMvType
{ _mvSpeed = 3
, _mvTurnRad = const 0.2
, _mvTurnJit = 0.05
, _mvAimSpeed = f
}
where
f x | x > pi/8 = 0.2
| otherwise = 0.01
defaultAimingCrit :: Creature
defaultAimingCrit = defaultCreature { _crMvType = defaultAimMvType }
yourDefaultSpeed :: Float
yourDefaultSpeed = 4
yourDefaultStrideLength :: Int
yourDefaultStrideLength = 40
defaultState :: CreatureState
defaultState = CrSt
{ _crDamage = []
, _crPastDamage = V.fromList $ replicate 20 []
, _crSpState = GenCr
, _crDropsOnDeath = DropAll
}
defaultEquipment :: Item
defaultEquipment = Item
{ _itCurseStatus = Uncursed
, _itType = NOTDEFINED
, _itName = "genericEquipment"
-- ,_itIdentity = Generic
, _itEquipPict = \_ _ -> (,) emptySH blank
, _itEffect = NoItEffect
, _itID = Nothing
, _itInvColor = yellow
, _itInvDisplay = \it -> [_itName it]
, _itInvSize = 1
, _itDimension = defItDimCol yellow
, _itConsumption = NoConsumption
, _itUse = EquipUse {_eqUse = \_ _ -> id}
, _itScroll = \ _ _ -> id
, _itAttachment = NoItAttachment
, _itParams = NoParams
, _itTweaks = NoTweaks
, _itModules = M.empty
, _itScope = NoScope
, _itTargeting = NoTargeting
, _itValue = defaultItemValue
}
defaultItZoom :: ItZoom
defaultItZoom = ItZoom 20 0.2 1
defaultConsumable :: Item
defaultConsumable = Item
{ _itUse = NoUse
-- , _itIdentity = Generic
, _itInvSize = 1
, _itCurseStatus = Uncursed
, _itName = "genericConsumable"
, _itConsumption = ItemItselfConsumable {_itAmount = 1}
, _itEquipPict = \_ _ -> mempty
, _itID = Nothing
, _itInvColor = blue
, _itInvDisplay = \it -> [_itName it ++ " x" ++ show (_itAmount $ _itConsumption it)]
, _itEffect = NoItEffect
, _itScroll = \_ _ -> id
, _itAttachment = NoItAttachment
, _itType = NoCombineType
, _itParams = NoParams
, _itDimension = defItDimCol blue
, _itTweaks = NoTweaks
, _itModules = M.empty
, _itScope = NoScope
, _itTargeting = NoTargeting
, _itValue = defaultItemValue
}
defaultApplyDamage :: [Damage] -> Creature -> (World -> World, Creature)
defaultApplyDamage ds cr = (id, doPoisonDam $ foldl' (flip $ \d c -> snd $ applyIndividualDamage d c) cr ds')
where
(ps,ds') = partition isPoison ds
isPoison Damage{_dmType=PoisonDam} = True
isPoison _ = False
poisonDam = quot (max 0 (sum (map _dmAmount ps))) 10
doPoisonDam = over crHP (\hp -> hp - poisonDam)
applyDamageEffect :: Damage -> DamageEffect -> Creature -> Creature
applyDamageEffect dm de cr = case de of
NoDamageEffect -> cr
PushDamage push pushexp pushRad -> cr
& crPos %~ (+.+ (pushAmount *.* squashNormalizeV (_crPos cr -.- fromDir)))
where
pushAmount
| dist (_crPos cr) fromDir == 0 = 0
| otherwise = min 5 $ (push*5*pushRad / (dist (_crPos cr) fromDir * _crMass cr))**pushexp
PushBackDamage pback -> cr
& crPos %~ (+.+ ((1/_crMass cr) *.* pback ))
TorqueDamage rot -> cr & crDir +~ rot
where
fromDir = _dmFrom dm
applyIndividualDamage :: Damage -> Creature -> (World -> World, Creature)
applyIndividualDamage dm cr = ( id
, cr
& crHP -~ _dmAmount dm
& applyDamageEffect dm (_dmEffect dm)
)
defaultFlIt :: FloorItem
defaultFlIt = FlIt {_flItRot=0,_flIt = defaultConsumable, _flItPos = V2 0 0, _flItID = 0}
defaultMachine :: Machine
defaultMachine = Machine
{ _mcID = 0
, _mcWallIDs = mempty
, _mcUpdate = defaultMachineUpdate
, _mcDraw = const mempty
, _mcPos = V2 0 0
, _mcDir = 0
, _mcHP = 1000
, _mcSensorAmount = 0
, _mcSensorToggle = False
, _mcDamage = []
, _mcLSs = []
, _mcType = StaticMachine
}
defaultMachineUpdate :: Machine -> World -> World
defaultMachineUpdate mc
| _mcHP mc < 1 = (machines %~ IM.delete mcid)
. deleteWallIDs (_mcWallIDs mc)
| otherwise = machines . ix mcid %~ ( (mcDamage .~ []) . (mcHP -~ dams) )
where
dams = sum $ map _dmAmount $ _mcDamage mc
mcid = _mcID mc
defaultDrawButton :: Color -> Button -> SPic
defaultDrawButton col bt =
( translateSHz 15 . colorSH col $ upperPrismPoly 5 buttonGeometry
, mempty
)
where
buttonGeometry
| _btState bt == BtOff = rectNSEW 10 (-1) width (-width)
| otherwise = rectNSEW 2 (-1) width (-width)
width = 8
defaultButton :: Button
defaultButton = Button
{ _btPict = defaultDrawButton (dark red)
, _btPos = V2 0 0
, _btRot = 0
, _btEvent = \b w -> set (buttons . ix (_btID b) . btState) BtNoLabel
. soundStart (LeverSound 0) (_btPos b) click1S Nothing $ w
, _btID = 0
, _btText = "Button"
, _btState = BtOff
, _btTerminalParams = NoTerminalParams
}
defaultPT :: Prop
defaultPT = Projectile
{ _pjPos = V2 0 0
, _pjStartPos = V2 0 0
, _pjVel = V2 0 0
, _prDraw = const mempty
, _pjID = 0
, _pjUpdate = const id
}
defaultPP :: PressPlate
defaultPP = PressPlate
{ _ppPict = onLayer PressPlateLayer . color (dim . dim $ bright blue) $ circleSolid 5
, _ppPos = V2 0 0
, _ppRot = 0
, _ppEvent = const id
, _ppID = -1
, _ppText = "Pressure plate"
}
defaultLS :: LightSource
defaultLS = LS
{ _lsID = 0
, _lsParam = LSParam
{ _lsPos = V3 0 0 50
, _lsRad = 700
, _lsCol = 0.6
}
, _lsDir = 0
, _lsPict = defLSPic
}
defLSPic :: LightSource -> Picture
defLSPic ls = setLayer 1 . translate3 (_lsPos $ _lsParam ls) . color col $ circleSolid 4
where
col = V4 r g b 2
V3 r g b = _lsCol $ _lsParam ls
defaultTLS :: TempLightSource
defaultTLS = TLS
{ _tlsParam = LSParam
{ _lsPos = 0
, _lsRad = 0
, _lsCol = 0.5
}
, _tlsUpdate = f
, _tlsTime = 1
}
where
f _ t
| _tlsTime t <= 0 = Nothing
| otherwise = Just $ t & tlsTime -~ 1
upHammer :: HammerType
upHammer = HasHammer HammerUp