318 lines
8.8 KiB
Haskell
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
|