308 lines
8.7 KiB
Haskell
308 lines
8.7 KiB
Haskell
{- |
|
|
Module : Dodge.Default
|
|
Description : Instances of data structures
|
|
|
|
This module contains prototypical data structures.
|
|
-}
|
|
module Dodge.Default where
|
|
import Dodge.Item.Weapon.ExtraEffect
|
|
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.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
|
|
, _crID = 1
|
|
, _crPict = \_ _ -> (,) mempty blank
|
|
, _crUpdate = \cr _ -> (Endo id , Just cr)
|
|
, _crRad = 10
|
|
, _crMass = 10
|
|
, _crHP = 100
|
|
, _crMaxHP = 150
|
|
, _crInv = IM.empty
|
|
, _crInvSel = 0
|
|
, _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
|
|
}
|
|
|
|
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 = Equipment
|
|
{ _itIdentity = Generic
|
|
, _itCurseStatus = Uncursed
|
|
, _itName = "genericEquipment"
|
|
, _itFloorPict = \_ -> (,) emptySH $ setLayer 0 $ onLayer FlItLayer $ polygon $ map toV2 [(-3,-3),(-3,3),(3,3),(3,-3)]
|
|
, _itEquipPict = \_ _ -> (,) emptySH blank
|
|
, _itEffect = NoItEffect
|
|
, _itHammer = HammerUp
|
|
, _itID = Nothing
|
|
, _itAimingSpeed = 1
|
|
, _itAimingRange = 0
|
|
, _itZoom = defaultItZoom
|
|
, _itAimZoom = defaultItZoom
|
|
, _itInvColor = yellow
|
|
, _itInvDisplay = _itName
|
|
, _itAimStance = LeaveHolstered
|
|
, _itDimension = defaultItemDimension
|
|
}
|
|
defaultItZoom :: ItZoom
|
|
defaultItZoom = ItZoom 20 0.2 1
|
|
defaultConsumable :: Item
|
|
defaultConsumable = Consumable
|
|
{ _itIdentity = Generic
|
|
, _itCurseStatus = Uncursed
|
|
, _itName = "genericConsumable"
|
|
, _itMaxStack = 9
|
|
, _itAmount = 1
|
|
, _cnEffect = \_ _ -> Nothing
|
|
, _itFloorPict = \_ -> (,) emptySH $ onLayer FlItLayer $ color blue $ circleSolid 3
|
|
, _itEquipPict = \_ _ -> (,) emptySH blank
|
|
, _itID = Nothing
|
|
, _itInvColor = blue
|
|
, _itInvDisplay = \it -> _itName it ++ " x" ++ show (_itAmount it)
|
|
, _itEffect = wpRecock
|
|
, _itHammer = HammerUp
|
|
, _itAimStance = LeaveHolstered
|
|
, _itDimension = defaultItemDimension
|
|
}
|
|
defaultApplyDamage :: [DamageType] -> 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 PoisonDam{} = True
|
|
isPoison _ = False
|
|
poisonDam = quot (max 0 (sum (map _dmAmount ps))) 10
|
|
doPoisonDam = over crHP (\hp -> hp - poisonDam)
|
|
|
|
applyIndividualDamage :: DamageType -> Creature -> (World -> World, Creature)
|
|
applyIndividualDamage (Concussive amount fromDir push pushexp pushRad) cr
|
|
= ( id
|
|
, over crHP (\hp -> hp - amount)
|
|
$ over crPos (+.+ (pushAmount *.* safeNormalizeV (_crPos cr -.- fromDir)))
|
|
cr
|
|
)
|
|
where
|
|
pushAmount
|
|
| dist (_crPos cr) fromDir == 0 = 0
|
|
| otherwise = min 5 $ (push*5*pushRad / (dist (_crPos cr) fromDir * _crMass cr))**pushexp
|
|
applyIndividualDamage (TorqueDam amount rot) cr
|
|
= ( id
|
|
, over crHP (\hp -> hp - amount) $ over crDir (+ rot) cr)
|
|
applyIndividualDamage (PushDam amount pback) cr
|
|
= ( id
|
|
, over crHP (\hp -> hp - amount) $ over crPos (+.+ ((1/_crMass cr) *.* pback )) cr
|
|
)
|
|
applyIndividualDamage dt cr
|
|
= ( id , over crHP (\hp -> hp - _dmAmount dt) cr )
|
|
defaultFlIt :: FloorItem
|
|
defaultFlIt = FlIt {_flItRot=0,_flIt = defaultIt, _flItPos = V2 0 0, _flItID = 0}
|
|
defaultIt :: Item
|
|
defaultIt = Consumable
|
|
{ _itIdentity = Medkit25
|
|
, _itDimension = defaultItemDimension
|
|
, _itCurseStatus = Uncursed
|
|
, _itName = "defaultIt"
|
|
, _itMaxStack = 3
|
|
, _itAmount = 2
|
|
, _cnEffect = const return
|
|
, _itFloorPict = \_ -> (,) emptySH $ onLayer FlItLayer $ polygon $ square 3
|
|
, _itEquipPict = \_ _ -> (,) emptySH blank
|
|
, _itID = Nothing
|
|
, _itInvDisplay = _itName
|
|
, _itInvColor = blue
|
|
, _itEffect = NoItEffect
|
|
, _itHammer = HammerUp
|
|
, _itAimStance = LeaveHolstered
|
|
}
|
|
defaultMachine :: Machine
|
|
defaultMachine = Machine
|
|
{ _mcID = 0
|
|
, _mcWallIDs = mempty
|
|
, _mcUpdate = defaultMachineUpdate
|
|
, _mcDraw = const mempty
|
|
, _mcPos = V2 0 0
|
|
, _mcDir = 0
|
|
, _mcHP = 1000
|
|
, _mcSensor = 0
|
|
, _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
|
|
}
|
|
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
|
|
, _lsPos = V3 0 0 50
|
|
, _lsDir = 0
|
|
, _lsRad = 700
|
|
, _lsIntensity = 0.6
|
|
, _lsPict = defLSPic
|
|
}
|
|
defLSPic :: LightSource -> Picture
|
|
defLSPic ls = setLayer 1 . translate3 (_lsPos ls) . color col $ circleSolid 4
|
|
where
|
|
col = V4 r g b 2
|
|
V3 r g b = _lsIntensity ls
|
|
defaultTLS :: TempLightSource
|
|
defaultTLS = TLS
|
|
{ _tlsPos = 0
|
|
, _tlsRad = 0
|
|
, _tlsIntensity = 0.5
|
|
, _tlsUpdate = f
|
|
, _tlsTime = 1
|
|
}
|
|
where
|
|
f _ t
|
|
| _tlsTime t <= 0 = Nothing
|
|
| otherwise = Just $ t & tlsTime -~ 1
|