215 lines
6.4 KiB
Haskell
215 lines
6.4 KiB
Haskell
module Dodge.Item.Equipment where
|
|
import Dodge.Data
|
|
import Dodge.Item.Draw
|
|
import Dodge.Item.Weapon.InventoryDisplay
|
|
import Dodge.Default
|
|
import Dodge.Default.Wall
|
|
import Dodge.Creature.Test
|
|
import Dodge.Creature.HandPos
|
|
import Dodge.Wall
|
|
import Dodge.Magnet
|
|
import Picture
|
|
import Geometry
|
|
import ShapePicture
|
|
import Shape
|
|
import qualified IntMapHelp as IM
|
|
import LensHelp
|
|
|
|
import Data.Maybe
|
|
magShield :: Item
|
|
magShield = defaultEquipment
|
|
{ _itType = MAGSHIELD
|
|
, _itName = "MAGSHIELD"
|
|
, _itUse = EquipUse useMagShield GoesOnWrist
|
|
, _itEquipPict = \_ _ -> (,) emptySH blank
|
|
, _itID = Nothing
|
|
, _itAttachment = ItMInt Nothing
|
|
}
|
|
useMagShield :: Creature -> Int -> World -> World
|
|
useMagShield cr invid w = w & magnets . at mgid ?~ themagnet
|
|
where
|
|
themagnet = Magnet
|
|
{_mgID = mgid
|
|
,_mgUpdate = Just . (mgUpdate .~ const Nothing)
|
|
,_mgPos = _crPos cr
|
|
,_mgField = curveAroundField 50 200
|
|
}
|
|
mgid = case it ^? itAttachment . itMInt . _Just of
|
|
Just mgid' -> mgid'
|
|
Nothing -> IM.newKey $ _magnets w
|
|
it = _crInv cr IM.! invid
|
|
|
|
flameShield :: Item
|
|
flameShield = defaultEquipment
|
|
{ _itType = FLAMESHIELD
|
|
, _itName = "FLAMESHIELD"
|
|
, _itUse = EquipUse
|
|
{_eqUse = \_ _ -> id
|
|
,_eqSite = GoesOnChest
|
|
}
|
|
, _itEquipPict = \cr _ -> (,) emptySH $ setDepth 20 $ pictures [color cyan $ circle (_crRad cr+2)]
|
|
, _itID = Nothing
|
|
}
|
|
{- | Slows you down, blocks forward projectiles. -}
|
|
frontArmour :: Item
|
|
frontArmour = defaultEquipment
|
|
{ _itType = FRONTARMOUR
|
|
, _itName = "FARMOUR"
|
|
, _itUse = EquipUse
|
|
{_eqUse = \_ _ -> id
|
|
,_eqSite = GoesOnChest
|
|
}
|
|
, _itEquipPict = pictureOnEquip (emptySH , setDepth 20 $ pictures
|
|
[color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
|
|
,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
|
|
])
|
|
, _itEffect = NoItEffect
|
|
, _itID = Nothing
|
|
}
|
|
pictureOnEquip :: SPic -> Creature -> Item -> SPic
|
|
pictureOnEquip sp cr itm = fromMaybe mempty $ do
|
|
i <- _itInvPos itm
|
|
epos <- cr^? crInvEquipped . ix i
|
|
return $ equipPosition epos cr sp
|
|
equipPosition :: EquipPosition -> Creature -> SPic -> SPic
|
|
equipPosition epos cr sh = case epos of
|
|
OnLeftWrist -> translateToLeftHand cr sh
|
|
OnRightWrist -> translateToRightHand cr $ mirrorSPxz sh
|
|
_ -> sh
|
|
|
|
flatShield :: Item
|
|
flatShield = defaultEquipment
|
|
{ _itEquipPict = pictureWeaponAim flatShieldEquipSPic
|
|
, _itEffect = effectOnOffHeld createShieldWall removeShieldWall
|
|
-- the above seems to work, but I am not sure why: it may break on edge
|
|
-- cases
|
|
, _itName = "FLATSHIELD"
|
|
, _itType = FLATSHIELD
|
|
, _itUse = RightUse
|
|
{ _rUse = \_ _ -> id
|
|
, _useDelay = NoDelay
|
|
, _useMods = []
|
|
, _useHammer = NoHammer
|
|
, _useAim = AimParams
|
|
{ _aimWeight = 5
|
|
, _aimRange = 0
|
|
, _aimZoom = ItZoom 20 0.2 1
|
|
, _aimStance = TwoHandFlat
|
|
}
|
|
}
|
|
, _itInvSize = 3
|
|
, _itInvDisplay = \it -> head (basicItemDisplay it) :
|
|
["*" ++ replicate 13 ' ' ++ "*"
|
|
,"*" ++ replicate 13 ' ' ++ "*"
|
|
]
|
|
}
|
|
flatShieldEquipSPic :: Item -> SPic
|
|
flatShieldEquipSPic _ =
|
|
( colorSH yellow $ upperPrismPoly 10 (rectWH 2 10)
|
|
, mempty
|
|
)
|
|
effectOnEquip :: (Creature -> Item -> World -> World) -> ItEffect
|
|
effectOnEquip f = ItInvEffectID
|
|
{ _itInvEffect = g f
|
|
, _itEffectID = Nothing
|
|
}
|
|
where
|
|
g f' itm cr w
|
|
| _crInvSel cr == invid = f' cr (_crInv (_creatures w IM.! _crID cr) IM.! invid) w
|
|
| otherwise = w
|
|
where
|
|
invid = fromJust $ _itInvPos itm
|
|
|
|
shieldWall :: Int -> Wall
|
|
shieldWall crid = defaultWall
|
|
{_wlColor = yellow
|
|
,_wlOpacity = SeeAbove
|
|
,_wlPathable = True
|
|
,_wlWalkable = True
|
|
,_wlFireThrough = True
|
|
,_wlReflect = True
|
|
,_wlDraw = False
|
|
,_wlRotateTo = False
|
|
,_wlStructure = CreaturePart crid shieldWallDamage
|
|
}
|
|
|
|
-- TODO the reflection should be controled by the particle
|
|
shieldWallDamage :: Damage -> Wall -> Int -> World -> World
|
|
shieldWallDamage dm _ crid w = case _dmType dm of
|
|
-- Lasering -> w
|
|
_ | isMovementDam dm -> w & creatures . ix crid . crState . crDamage .:~ dm
|
|
_ -> w
|
|
|
|
createShieldWall :: Creature -> Int -> World -> World
|
|
createShieldWall cr invid w = case _itEffectID $ _itEffect it of
|
|
Nothing -> let (wlid,w') = createWall ((shieldWall crid) {_wlLine = wlline}) w
|
|
in w' & creatures . ix crid . crInv . ix invid . itEffect . itEffectID ?~ wlid
|
|
Just wid -> moveWallID wid wlline w
|
|
where
|
|
crid = _crID cr
|
|
it = _crInv (_creatures w IM.! crid) IM.! invid
|
|
wlline = (a,b)
|
|
crdirv = unitVectorAtAngle $ _crDir cr
|
|
crpos = _crPos cr
|
|
rad = _crRad cr + 2
|
|
a = crpos +.+ rad *.* crdirv -.- 10 *.* therot crdirv
|
|
b = crpos +.+ rad *.* crdirv +.+ 10 *.* therot crdirv
|
|
therot | crIsAiming' cr = vNormal
|
|
| otherwise = rotateV (twoFlatHRot cr) . vNormal
|
|
removeShieldWall :: Creature -> Int -> World -> World
|
|
removeShieldWall cr invid w = case _itEffectID $ _itEffect it of
|
|
Nothing -> w
|
|
Just wid -> w & deleteWallID wid
|
|
& creatures . ix crid . crInv . ix invid . itEffect . itEffectID .~ Nothing
|
|
where
|
|
crid = _crID cr
|
|
it = _crInv (_creatures w IM.! crid) IM.! invid
|
|
|
|
effectOnOffHeld
|
|
:: (Creature -> Int -> World -> World) -- ^ effect when held
|
|
-> (Creature -> Int -> World -> World) -- ^ effect when not held
|
|
-> ItEffect
|
|
effectOnOffHeld f f' = ItInvEffectID
|
|
{ _itInvEffect = g
|
|
, _itEffectID = Nothing
|
|
}
|
|
where
|
|
g itm cr w
|
|
| _crInvSel cr == invid = f cr invid w
|
|
| otherwise = f' cr invid w
|
|
where
|
|
invid = fromJust $ _itInvPos itm
|
|
|
|
{- | Increases speed, reduces friction, cannot only move forwards. -}
|
|
jetPack :: Item
|
|
jetPack = defaultEquipment
|
|
{ _itType = JETPACK
|
|
, _itName = "JETPACK"
|
|
, _itEquipPict = \_ _ -> (,) emptySH $ setDepth 20
|
|
$ pictures [color yellow $ polygon $ rectNSEW 5 (-5) (-3) (-11) ]
|
|
, _itEffect = NoItEffect
|
|
, _itID = Nothing
|
|
}
|
|
|
|
powerLegs :: Item
|
|
powerLegs = defaultEquipment
|
|
{ _itType = POWERLEGS
|
|
, _itName = "POWERLEGS"
|
|
, _itUse = EquipUse
|
|
{_eqUse = \_ _ -> id
|
|
,_eqSite = GoesOnLegs
|
|
}
|
|
, _itEffect = NoItEffect
|
|
, _itID = Nothing
|
|
}
|
|
speedLegs :: Item
|
|
speedLegs = powerLegs
|
|
{ _itType = SPEEDLEGS
|
|
, _itName = "SPEEDLEGS"
|
|
}
|
|
jumpLegs :: Item
|
|
jumpLegs = powerLegs
|
|
{ _itType = JUMPLEGS
|
|
, _itName = "JUMPLEGS"
|
|
}
|