179 lines
5.7 KiB
Haskell
179 lines
5.7 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.Picture.Layer
|
|
import Dodge.Item.Weapon.BatteryGuns
|
|
import Dodge.Creature.Test
|
|
import Dodge.Wall.Reflect
|
|
import Dodge.Wall
|
|
import Dodge.Magnet
|
|
import Picture
|
|
import Geometry
|
|
import ShapePicture
|
|
import Shape
|
|
import qualified IntMapHelp as IM
|
|
import LensHelp
|
|
|
|
magShield :: Item
|
|
magShield = defaultEquipment
|
|
{ _itType = MAGSHIELD
|
|
, _itName = "MAGSHIELD"
|
|
, _itUse = EquipUse useMagShield
|
|
, _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"
|
|
, _itEquipPict = \cr _ -> (,) emptySH $ onLayer CrLayer $ pictures [color cyan $ circle (_crRad cr+2)]
|
|
, _itID = Nothing
|
|
}
|
|
{- | Slows you down, blocks forward projectiles. -}
|
|
frontArmour :: Item
|
|
frontArmour = defaultEquipment
|
|
{ _itType = FRONTARMOUR
|
|
, _itName = "FARMOUR"
|
|
-- , _itFloorPict = \_ -> (,) emptySH $ onLayer FlItLayer $ translate 0 (-5) $ pictures
|
|
-- [color (greyN 0.1) $ thickArc 0 (pi/2) 10 5
|
|
-- ,color (greyN 0.1) $ thickArc (3*pi/2) (2*pi) 10 5
|
|
-- ]
|
|
, _itEquipPict = \_ _ -> (,) emptySH $ onLayer CrLayer $ 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
|
|
}
|
|
flatShield :: Item
|
|
flatShield = defaultEquipment
|
|
{ _itEquipPict = pictureWeaponAim flatShieldEquipSPic
|
|
, _itEffect = effectOnOffEquip 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
|
|
{ _aimSpeed = 0.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' _ cr invid w
|
|
| _crInvSel cr == invid = f' cr (_crInv (_creatures w IM.! _crID cr) IM.! invid) w
|
|
| otherwise = w
|
|
|
|
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
|
|
}
|
|
|
|
shieldWallDamage :: Damage -> Wall -> Int -> World -> World
|
|
shieldWallDamage dm wl crid w = case _dmType dm of
|
|
Lasering ->
|
|
w & instantParticles .:~ lasRayAt 5 (da +.+ normalizeV (df -.- da)) (reflDirWall df da wl)
|
|
d | isMovementDam dm -> w & creatures . ix crid . crState . crDamage .:~ dm
|
|
_ -> w
|
|
where
|
|
df = _dmFrom dm
|
|
da = _dmAt dm
|
|
|
|
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
|
|
|
|
effectOnOffEquip
|
|
:: (Creature -> Int -> World -> World) -- ^ effect when equiped
|
|
-> (Creature -> Int -> World -> World) -- ^ effect when not equiped
|
|
-> ItEffect
|
|
effectOnOffEquip f f' = ItInvEffectID
|
|
{ _itInvEffect = g
|
|
, _itEffectID = Nothing
|
|
}
|
|
where
|
|
g _ cr invid w
|
|
| _crInvSel cr == invid = f cr invid w
|
|
| otherwise = f' cr invid w
|
|
|
|
{- | Increases speed, reduces friction, cannot only move forwards. -}
|
|
jetPack :: Item
|
|
jetPack = defaultEquipment
|
|
{ _itType = JETPACK
|
|
, _itName = "JETPACK"
|
|
, _itEquipPict = \_ _ -> (,) emptySH $ onLayer CrLayer
|
|
$ pictures [color yellow $ polygon $ rectNSEW 5 (-5) (-3) (-11) ]
|
|
, _itEffect = NoItEffect
|
|
, _itID = Nothing
|
|
}
|