Files
loop/src/Dodge/Item/Equipment.hs
T

256 lines
7.8 KiB
Haskell

module Dodge.Item.Equipment
( module Dodge.Item.Equipment.Booster
, magShield
, powerLegs
, flatShield
, wristInvisibility
, wristArmour
, brainHat
, frontArmour
, headLamp
, headLamp1
, jetPack
, speedLegs
, jumpLegs
, flameShield
) where
import Dodge.Data
import Dodge.Item.Draw
import Dodge.Item.Equipment.Booster
import Dodge.LightSource
import Dodge.Default
import Dodge.Default.Wall
import Dodge.Creature.Test
import Dodge.Creature.HandPos
import Dodge.Wall
import Dodge.Wall.ForceField
import Dodge.Magnet
import Picture
import Geometry
import qualified IntMapHelp as IM
import LensHelp
--import ShortShow
magShield :: Item
magShield = defaultEquipment
{ _itID = Nothing
, _itAttachment = AttachMInt Nothing
}
& itUse . eqEq . eqUse .~ useMagShield
& itUse . eqEq . eqSite .~ GoesOnWrist
& itType . iyBase .~ MAGSHIELD
useMagShield :: Item -> Creature -> World -> World
useMagShield it cr 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 . atMInt . _Just of
Just mgid' -> mgid'
Nothing -> IM.newKey $ _magnets w
-- it = _crInv cr IM.! invid
flameShield :: Item
flameShield = defaultEquipment
{ _itID = Nothing
} & itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ FLAMESHIELD
{- | Slows you down, blocks forward projectiles. -}
frontArmour :: Item
frontArmour = defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ FRONTARMOUR
wristArmour :: Item
wristArmour = defaultEquipment
{_itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ onEquipWristShield
& itUse . eqEq . eqUse .~ setWristShieldPos
& itUse . eqEq . eqOnRemove .~ onRemoveWristShield
& itType . iyBase .~ WRISTARMOUR
onEquipWristShield :: Item -> Creature -> World -> World
onEquipWristShield itm cr w = w
& creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itUse . eqEq . eqParams .~ EquipID i
& walls . at i ?~ forceField {_wlID = i}
& setWristShieldPos (itm & itUse . eqEq . eqParams .~ EquipID i) cr
where
i = IM.newKey (_walls w)
onRemoveWristShield :: Item -> Creature -> World -> World
onRemoveWristShield itm cr w = w
& creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itUse . eqEq . eqParams .~ NoEquipParams
& deleteWallID i
where
i = _eparamID $ _eqParams $ _eqEq $ _itUse itm
setWristShieldPos :: Item -> Creature -> World -> World
setWristShieldPos itm cr w = w
& moveWallIDUnsafe i wlline
where
i = _eparamID $ _eqParams $ _eqEq $ _itUse itm
wlline = (f (V3 (-10) 7 0), f (V3 10 7 0))
invid = _ipInvID (_itPos itm)
--wlline = (V2 10 0, V2 (-10) 100)
handtrans = case cr ^? crInvEquipped . ix invid of
Just OnLeftWrist -> \cr' -> translatePointToLeftHand cr' . g
_ -> translatePointToRightHand
g | twists cr = (+.+.+ V3 (-5) 10 0)
| otherwise = id
f = (+.+ _crPos cr) . stripZ . rotate3 (_crDir cr) . handtrans cr
flatShield :: Item
flatShield = defaultEquipment
{ _itEffect = effectOnOffHeld createShieldWall removeShieldWall
-- the above seems to work, but I am not sure why: it may break on edge
-- cases
, _itUse = RightUse
{ _rUse = \_ _ -> id
, _useDelay = NoDelay
, _useMods = []
, _useHammer = HammerUp
, _useAim = AimParams
{ _aimWeight = 5
, _aimRange = 0
, _aimZoom = ItZoom 20 0.2 1
, _aimStance = TwoHandFlat
, _aimHandlePos = 0
, _aimMuzPos = 0
}
, _heldScroll = \_ _ -> id
}
, _itInvSize = 3
}
& itType . iyBase .~ FLATSHIELD
shieldWall :: Int -> Wall
shieldWall crid = defaultWall
{_wlColor = yellow
,_wlOpacity = SeeAbove
,_wlPathable = True
,_wlWalkable = True
,_wlFireThrough = True
,_wlReflect = True
,_wlUnshadowed = 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 _ieMID $ _itEffect it of
Nothing -> let (wlid,w') = createWall ((shieldWall crid) {_wlLine = wlline,_wlID = wlid}) w
in w' & creatures . ix crid . crInv . ix invid . itEffect . ieMID ?~ 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 _ieMID $ _itEffect it of
Nothing -> w
Just wid -> w & deleteWallID wid
& creatures . ix crid . crInv . ix invid . itEffect . ieMID .~ 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
{ _ieInv = g
, _ieMID = Nothing
}
where
g itm cr w
| crSel cr == invid = f cr invid w
| otherwise = f' cr invid w
where
invid = _ipInvID $ _itPos itm
{- | Increases speed, reduces friction, cannot only move forwards. -}
jetPack :: Item
jetPack = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
} & itUse . eqEq . eqSite .~ GoesOnBack
& itType . iyBase .~ JETPACK
brainHat :: Item
brainHat = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ BRAINHAT
headLamp1 :: Item
headLamp1 = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ HEADLAMP1
headLamp :: Item
headLamp = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ HEADLAMP
createHeadLamp :: Item -> Creature -> World -> World
createHeadLamp _ cr = tempLightSources .:~ tlsTimeRadColPos 1 200 0.7
((_crPos cr `v2z` 0) +.+.+ rotate3 (_crDir cr) (translatePointToHead cr (V3 5 0 3)))
powerLegs :: Item
powerLegs = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnLegs
& itType . iyBase .~ POWERLEGS
speedLegs :: Item
speedLegs = powerLegs
& itType . iyBase .~ SPEEDLEGS
jumpLegs :: Item
jumpLegs = powerLegs
& itType . iyBase .~ JUMPLEGS
wristInvisibility :: Item
wristInvisibility = defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ overCID (crCamouflage .~ Invisible)
& itUse . eqEq . eqOnRemove .~ overCID (crCamouflage .~ FullyVisible)
& itType . iyBase .~ INVISIBILITYEQUIPMENT GoesOnWrist
overCID :: (Creature -> Creature) -> Item -> Creature -> World -> World
overCID f _ cr = creatures . ix (_crID cr) %~ f