256 lines
7.8 KiB
Haskell
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
|