Files
loop/src/Dodge/Default.hs
T

181 lines
5.5 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.Data
import Dodge.Item.Data
import Dodge.Creature.Stance.Data
import Dodge.Creature.State.Data
import Dodge.Creature.AlertLevel.Data
import Dodge.SoundLogic
import Dodge.Picture.Layer
import Geometry
import Picture
import Control.Lens
import qualified Data.IntMap.Strict as IM
import Data.List
defaultCreature :: Creature
defaultCreature = Creature
{ _crPos = V2 0 0
, _crOldPos = V2 0 0
, _crVel = V2 0 0
, _crDir = 0
, _crMvDir = 0
, _crID = 1
, _crPict = \_ _ -> setLayer 0 $ onLayer CrLayer $ circleSolid 10
, _crUpdate = \ _ f cr -> (f , 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 = 40
}
, _crActionPlan = ActionPlan [] [] WatchAndWait [LiveLongAndProsper]
, _crMeleeCooldown = Nothing
, _crAwakeLevel = Vigilant
, _crAttentionDir = AttentiveTo []
, _crAwarenessLevel = IM.empty
, _crFaction = NoFaction
, _crTarget = Nothing
, _crGroup = LoneWolf
}
defaultState :: CreatureState
defaultState = CrSt
{ _crDamage = []
, _crPastDamage = []
, _crSpState = GenCr
, _crDropsOnDeath = DropAll
}
defaultEquipment :: Item
defaultEquipment = Equipment
{ _itIdentity = Generic
, _itName = "genericEquipment"
, _itMaxStack = 1
, _itAmount = 1
, _itFloorPict = setLayer 0 $ onLayer FlItLayer $ polygon $ map toV2 [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \_ _ -> blank
, _itEffect = NoItEffect
, _itHammer = HammerUp
, _itID = Nothing
, _itAimingSpeed = 1
, _itAimingRange = 0
, _itZoom = defaultItZoom
, _itInvColor = yellow
, _itInvDisplay = _itName
, _itAimStance = LeaveHolstered
}
defaultItZoom :: ItZoom
defaultItZoom = ItZoom 20 0.2 1 20 0.2 1
defaultConsumable :: Item
defaultConsumable = Consumable
{ _itIdentity = Generic
, _itName = "genericConsumable"
, _itMaxStack = 9
, _itAmount = 1
, _cnEffect = \_ _ -> Nothing
, _itFloorPict = onLayer FlItLayer $ color blue $ circleSolid 3
, _itEquipPict = \_ _ -> blank
, _itID = Nothing
, _itInvColor = blue
, _itInvDisplay = \it -> _itName it ++ " x" ++ show (_itAmount it)
, _itEffect = wpRecock
, _itHammer = HammerUp
, _itAimStance = LeaveHolstered
}
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
, _itName = "defaultIt"
, _itMaxStack = 3
, _itAmount = 2
, _cnEffect = const return
, _itFloorPict = onLayer FlItLayer $ polygon $ map toV2 [(-3,-3),(-3,3),(3,3),(3,-3)]
, _itEquipPict = \_ _ -> blank
, _itID = Nothing
, _itInvDisplay = _itName
, _itInvColor = blue
, _itEffect = NoItEffect
, _itHammer = HammerUp
, _itAimStance = LeaveHolstered
}
defaultButton :: Button
defaultButton = Button
{ _btPict = onLayer WlLayer $ color red $ polygon $ rectNSEW 5 (-5) 10 (-10)
, _btPos = V2 0 0
, _btRot = 0
, _btEvent = \b w ->
set (buttons . ix (_btID b) . btPict) (onLayer WlLayer $ color red $ polygon $ rectNSEW (-4) (-5) 10 (-10))
. set (buttons . ix (_btID b) . btState) BtNoLabel
. soundOnce 1 $ w
, _btID = 0
, _btText = "Button"
, _btState = BtOff
}
defaultPT :: Projectile
defaultPT = Projectile
{ _pjPos = V2 0 0
, _pjStartPos = V2 0 0
, _pjVel = V2 0 0
, _pjDraw = const blank
, _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"
}