This commit is contained in:
2022-07-27 12:49:23 +01:00
parent 6554d219dc
commit 8d17ce66e9
106 changed files with 2911 additions and 2678 deletions
+2 -2
View File
@@ -3,5 +3,5 @@ import Dodge.Data
import Data.Maybe
import Control.Lens
itStackAmount :: Item -> IcAmount
itStackAmount it = fromMaybe 1 $ it ^? itConsumption . icAmount
itStackAmount :: Item -> ItAmount
itStackAmount it = fromMaybe 1 $ it ^? itUse . useAmount
+1 -1
View File
@@ -16,7 +16,7 @@ charFiringStratI
:: [(Char, ChainEffect)] -- ^ Different firing effects for different characters
-> ChainEffect
charFiringStratI strats eff item cr w = case w ^? cWorld . creatures . ix cid . crInv
. ix (crSel $ _creatures (_cWorld w) IM.! cid) . itAttachment . atCharMode of
. ix (crSel $ _creatures (_cWorld w) IM.! cid) . itUse . heldScroll . hsCharMode of
Just (c :<| _) -> fromMaybe id (Prelude.lookup c strats) eff item cr w
_ -> w
where
+2 -6
View File
@@ -14,12 +14,8 @@ import qualified IntMapHelp as IM
medkit :: Int -> Item
medkit i = defaultConsumable
{ _itUse = ConsumeUse
{_cUse = CHeal i
}
, _itID = Nothing
}
& itType . iyBase .~ MEDKIT i
& itUse . cUse .~ CHeal i
& itType . iyBase .~ Consumable (MEDKIT i)
heal25 :: Int -> World -> Maybe World
heal25 = heal 25
+1 -1
View File
@@ -13,7 +13,7 @@ makeTypeCraftNum :: Int -> CraftType -> Item
makeTypeCraftNum i ct = defaultCraftable
& itInvSize .~ 0.5
& itCurseStatus .~ Uncursed
& itConsumption .~ ItemItselfConsumable (IcAmount i)
& itUse . useAmount .~ fromIntegral i
& itType . iyBase .~ CRAFT ct
makeTypeCraft :: CraftType -> Item
+75 -71
View File
@@ -1,105 +1,109 @@
module Dodge.Item.Display
( itemDisplay
, selectedItemDisplay
, itemString
)
where
import Dodge.Module
import Dodge.Data
import Dodge.Inventory.ItemSpace
import Padding
import LensHelp
module Dodge.Item.Display (
itemDisplay,
selectedItemDisplay,
itemString,
) where
import Data.Maybe
import Data.Sequence
import Dodge.Data
import Dodge.Inventory.ItemSpace
import Dodge.Module
import LensHelp
import Padding
itemDisplay :: Item -> [String]
itemDisplay it = itemDisplayWithNumber (showConsumption (_itUse it)) it
itemDisplayWithNumber :: String -> Item -> [String]
itemDisplayWithNumber numberstr it =
Prelude.take (itSlotsTaken it) $
(midPadL 15 ' ' thename (' ' : numberstr) ++ theparam) :
catMaybes [maybeWarmupStatus it, maybeRateStatus it]
++ moduleStrings it
++ repeat "*"
where
thename = itemBaseName it
theparam =
fromMaybe []
. listToMaybe
$ mapMaybe
($ it)
[ maybeModeStatus
]
itemString :: Item -> String
itemString = head . itemDisplay
itemBaseName :: Item -> String
itemBaseName it = case _iyBase $ _itType it of
itemBaseName it = case _iyBase $ _itType it of
CRAFT str -> show str
HELD hit -> case hit ^? xNum of
Just i -> takeWhile (/=' ') (show hit) ++ show i
HELD hit -> case hit ^? xNum of
Just i -> takeWhile (/= ' ') (show hit) ++ show i
Nothing -> show hit
x -> show x
itemDisplayWithNumber :: String -> Item -> [String]
itemDisplayWithNumber numberstr it = Prelude.take (itSlotsTaken it) $
(midPadL 15 ' ' thename (' ' : numberstr) ++ theparam)
: catMaybes [maybeWarmupStatus it,maybeRateStatus it]
++ moduleStrings it ++ repeat "*"
where
thename = itemBaseName it
theparam = fromMaybe []
. listToMaybe
$ mapMaybe ($ it)
[ maybeModeStatus
]
LEFT lit -> show lit
EQUIP eit -> show eit
Consumable cit -> show cit
selectedItemDisplay :: Creature -> Item -> [String]
selectedItemDisplay cr it = itemDisplayWithNumber (showSelectedConsumption cr (_itConsumption it)) it
selectedItemDisplay cr it = itemDisplayWithNumber (showSelectedConsumption cr (_itUse it)) it
{- | Displays the item name, ammo if loaded, and any selected '_itCharMode'. -}
-- TODO make work on remote launchers
itemDisplay :: Item -> [String]
itemDisplay it = itemDisplayWithNumber (showConsumption (_itConsumption it)) it
-- | Displays the item name, ammo if loaded, and any selected '_itCharMode'.
showSelectedConsumption :: Creature -> ItemUse -> String
showSelectedConsumption cr iu = case iu of
RightUse{} -> showReloadProgress cr (_heldConsumption iu)
LeftUse{} -> showAutoRechargeProgress (_leftConsumption iu)
EquipUse{} -> ""
_ -> show $ iu ^?! useAmount . getItAmount -- partial, be careful if adding new data constructors
showSelectedConsumption :: Creature -> ItemConsumption -> String
showSelectedConsumption cr ic = case ic of
LoadableAmmo{} -> showReloadProgress cr ic
AutoRecharging {} -> showAutoRechargeProgress ic
ChargeableAmmo{} -> show $ _wpCharge ic
ItemItselfConsumable{} -> show (_icAmount ic)
NoConsumption -> ""
showAutoRechargeProgress :: LeftConsumption -> String
showAutoRechargeProgress lc = case lc of
AutoRecharging{}
| _arLoaded lc < _arMax lc -> show (_arProgress lc) ++ "C" ++ show (_arLoaded lc)
| otherwise -> show (_arLoaded lc)
ChargeableAmmo{} -> show (_wpCharge lc)
showAutoRechargeProgress :: ItemConsumption -> String
showAutoRechargeProgress ic
| l < _arMax ic = show (_arProgress ic) ++ "C" ++ show l
| otherwise = show l
where
l = _arLoaded ic
showReloadProgress :: Creature -> ItemConsumption -> String
showReloadProgress :: Creature -> HeldConsumption -> String
showReloadProgress cr ic = case cr ^?! crInvSel . iselAction of
ReloadAction i la _ -> show i ++ showLoadActionType la (_laLoaded ic)
_ -> case ic ^? laProgress . _Just . ix 0 of
Nothing -> show $ _laLoaded ic
Just la -> show (_actionTime la) ++ showLoadActionType la (_laLoaded ic)
showLoadProgress :: Int -> Maybe [LoadAction] -> String
showLoadProgress x mlas = case mlas ^? _Just . ix 0 of
Just la -> show (_actionTime la) ++ showLoadActionType la x
Nothing -> show x
showConsumption :: ItemUse -> String
showConsumption iu = case iu of
RightUse{} -> showReloadProgress' (_heldConsumption iu)
LeftUse{} -> showAutoRechargeProgress (_leftConsumption iu)
EquipUse{} -> ""
_ -> show $ iu ^?! useAmount . getItAmount
showConsumption :: ItemConsumption -> String
showConsumption ic = case ic of
LoadableAmmo{} -> showLoadProgress (_laLoaded ic) (_laProgress ic)
AutoRecharging {} -> showAutoRechargeProgress ic
ChargeableAmmo{} -> show $ _wpCharge ic
ItemItselfConsumable{} -> show (_icAmount ic)
NoConsumption -> ""
showReloadProgress' :: HeldConsumption -> String
showReloadProgress' ic = case ic ^? laProgress . _Just . ix 0 of
Nothing -> show $ _laLoaded ic
Just la -> show (_actionTime la) ++ showLoadActionType la (_laLoaded ic)
showLoadActionType :: LoadAction -> Int -> String
showLoadActionType la x = case la of
LoadEject {} -> "E"
LoadInsert {} -> "L"
LoadAdd {} -> "A" ++ show x
LoadPrime {} -> "P"
LoadEject{} -> "E"
LoadInsert{} -> "L"
LoadAdd{} -> "A" ++ show x
LoadPrime{} -> "P"
maybeWarmupStatus :: Item -> Maybe String
maybeWarmupStatus it = case it ^? itUse . useDelay . warmMax of
Nothing -> Nothing
Just m -> case m - (_warmTime . _useDelay $ _itUse it) of
x | x <= 1 -> Just "*WARM"
| otherwise -> let n = show x
in Just $ Prelude.take (5 - Prelude.length n) "*WARM" ++ n
Just m -> case m - (_warmTime . _useDelay $ _itUse it) of
x
| x <= 1 -> Just "*WARM"
| otherwise ->
let n = show x
in Just $ Prelude.take (5 - Prelude.length n) "*WARM" ++ n
maybeModeStatus :: Item -> Maybe String
maybeModeStatus it = case it ^? itAttachment of
Just AttachCharMode {_atCharMode = (c :<| _)} -> Just [' ',c]
Just AttachMode {_atMode = i} -> Just $ show i
_ -> Nothing
maybeModeStatus it = case it ^? itUse . heldScroll of
Just HeldScrollCharMode{_hsCharMode = (c :<| _)} -> Just [' ', c]
Just HeldScrollInt{_hsInt = i} -> Just $ show i
_ -> Nothing
maybeRateStatus :: Item -> Maybe String
maybeRateStatus it = case it ^? itUse . useDelay . rateMaxMax of
+9 -16
View File
@@ -16,15 +16,7 @@ itemSPic it = foldMap (modulesSPic it) (_iyModules $ _itType it) <> case it ^. i
HELD ht -> heldItemSPic ht it
LEFT lt -> leftItemSPic lt it
EQUIP et -> equipItemSPic et it
NOTDEFINED -> defSPic
EFFGUN _ -> defSPic
AUTOEFFGUN _ -> defSPic
--
--
KEYCARD _ -> noShape (setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) keyPic)
--
MEDKIT _ -> defSPic
Consumable {} -> defSPic
equipItemSPic :: EquipItemType -> Item -> SPic
equipItemSPic et _ = case et of
@@ -100,6 +92,7 @@ heldItemSPic ht it = case ht of
DRONELAUNCHER -> defSPic
SHATTERGUN -> shatterGunSPic
HELDDETECTOR dt -> noPic (colorSH (detectorColor dt) $ upperPrismPoly 3 $ rectWH 2 2)
KEYCARD _ -> noShape (setDepth 0 $ translate (-5) (-5) $ rotate (pi/2.5) keyPic)
torchShape :: Shape
torchShape = colorSH blue
@@ -132,7 +125,7 @@ baseStickShape :: Shape
baseStickShape = colorSH green $ upperPrismPoly 3 $ rectXH 10 2
stickClip :: Item -> Shape
stickClip it = case it ^? itConsumption . laLoaded of
stickClip it = case it ^? itUse . heldConsumption . laLoaded of
Just x | x > 0 -> foldMap f [0..x-1]
_ -> mempty
where
@@ -163,7 +156,7 @@ baseRifleShape :: Shape
baseRifleShape = colorSH red $ upperPrismPoly 3 $ rectXH 25 2
makeSingleClipAt :: Point3 -> Item -> Shape
makeSingleClipAt p it = case it ^? itConsumption . laLoaded of
makeSingleClipAt p it = case it ^? itUse . heldConsumption . laLoaded of
Just 0 -> mempty
_ -> translateSH p $ upperPrismPoly 1 $ square 1.5
@@ -172,7 +165,7 @@ makeTinClipAt r p it = translateSH p . overPosSH (rotate3z r) $ upperPrismPoly 1
$ rectNSWE 0 (-y) (-2) 2
where
y = fromIntegral y' * 0.3
y' = fromMaybe 0 $ it ^? itConsumption . laLoaded
y' = fromMaybe 0 $ it ^? itUse . heldConsumption . laLoaded
volleyGunSPic :: Int -> Item -> SPic
volleyGunSPic i it = noPic $
@@ -183,7 +176,7 @@ volleyGunSPic i it = noPic $
caneClipX :: Int -> Item -> Shape
caneClipX i it = case it ^? itConsumption . laLoaded of
caneClipX i it = case it ^? itUse . heldConsumption . laLoaded of
Just la | la > 0 -> foldMap
( (\y -> translateSH (V3 5 0 3) . upperPrismPoly 1 $ map (+.+ V2 0 y) $ square 1.5)
. (\k -> fromIntegral k * 5 - ((fromIntegral i - 1) * 2.5)))
@@ -191,9 +184,9 @@ caneClipX i it = case it ^? itConsumption . laLoaded of
_ -> mempty
miniGunXPictItem :: Int -> Item -> SPic
miniGunXPictItem i it = miniGunXPict i spin (_laLoaded $ _itConsumption it)
miniGunXPictItem i it = miniGunXPict i spin (_laLoaded $ _heldConsumption (_itUse it))
where
spin = (-10) * _laLoaded (_itConsumption it) + _warmTime (_useDelay $ _itUse it)
spin = (-10) * _laLoaded (_heldConsumption (_itUse it)) + _warmTime (_useDelay $ _itUse it)
miniGunXPict :: Int -> Int -> Int -> SPic
miniGunXPict i spin _ =
@@ -216,7 +209,7 @@ baseSonicShape :: Shape
baseSonicShape = colorSH rose $ upperPrismPoly 3 $ rectXH 25 2
revolverClip :: Item -> Shape
revolverClip it = case it ^? itConsumption . laLoaded of
revolverClip it = case it ^? itUse . heldConsumption . laLoaded of
Just al | al > 0 -> translateSH (V3 5 0 1) $ foldMap f [1..al]
_ -> mempty
where
+220 -184
View File
@@ -1,109 +1,120 @@
module Dodge.Item.Equipment
( module Dodge.Item.Equipment.Booster
, torch
, magShield
, powerLegs
, flatShield
, wristInvisibility
, wristArmour
, hat
, brainHat
, frontArmour
, headLamp
, headLamp1
, jetPack
, speedLegs
, jumpLegs
, flameShield
module Dodge.Item.Equipment (
module Dodge.Item.Equipment.Booster,
torch,
magShield,
powerLegs,
flatShield,
wristInvisibility,
wristArmour,
hat,
brainHat,
frontArmour,
headLamp,
headLamp1,
jetPack,
speedLegs,
jumpLegs,
flameShield,
useMagShield,
setWristShieldPos,
createHeadLamp,
overCID,
onEquipWristShield,
onRemoveWristShield,
createShieldWall,
removeShieldWall,
) where
, useMagShield
, setWristShieldPos
, createHeadLamp
, overCID
, onEquipWristShield
, onRemoveWristShield
, createShieldWall
, removeShieldWall
) where
import Dodge.Data
import Dodge.Item.Draw
import Dodge.Item.Equipment.Booster
import Dodge.LightSource
import Dodge.Default
import Dodge.Creature.Test
import Data.Maybe
import Dodge.Creature.HandPos
import Dodge.Creature.Test
import Dodge.Data
import Dodge.Default
import Dodge.Item.Equipment.Booster
import Dodge.Item.HeldOffset
import Dodge.LightSource
import Dodge.Wall
import Dodge.Wall.ForceField
import Picture
import Geometry
import qualified IntMapHelp as IM
import LensHelp
import Data.Maybe
import Picture
magShield :: Item
magShield = defaultEquipment
{ _itID = Nothing
, _itAttachment = AttachMInt Nothing
}
& itUse . eqEq . eqUse .~ EMagShield --useMagShield
& itUse . eqEq . eqSite .~ GoesOnWrist
& itType . iyBase .~ EQUIP MAGSHIELD
magShield =
defaultEquipment
{ _itID = Nothing
, _itAttachment = AttachMInt Nothing
}
& itUse . eqEq . eqUse .~ EMagShield --useMagShield
& itUse . eqEq . eqSite .~ GoesOnWrist
& itType . iyBase .~ EQUIP MAGSHIELD
useMagShield :: Item -> Creature -> World -> World
useMagShield it cr w = w & cWorld . magnets . at mgid ?~ themagnet
where
themagnet = Magnet
{_mgID = mgid
,_mgUpdate = MagnetUpdateTimer 1
,_mgPos = _crPos cr
,_mgField = MagnetBuBuCurveAroundField 50 200
}
themagnet =
Magnet
{ _mgID = mgid
, _mgUpdate = MagnetUpdateTimer 1
, _mgPos = _crPos cr
, _mgField = MagnetBuBuCurveAroundField 50 200
}
mgid = case it ^? itAttachment . atMInt . _Just of
Just mgid' -> mgid'
Nothing -> IM.newKey $ _magnets (_cWorld w)
-- it = _crInv cr IM.! invid
flameShield :: Item
flameShield = defaultEquipment
{ _itID = Nothing
} & itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ EQUIP FLAMESHIELD
{- | Slows you down, blocks forward projectiles. -}
flameShield :: Item
flameShield =
defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ EQUIP FLAMESHIELD
-- | Slows you down, blocks forward projectiles.
frontArmour :: Item
frontArmour = defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ EQUIP FRONTARMOUR
frontArmour =
defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnChest
& itType . iyBase .~ EQUIP FRONTARMOUR
wristArmour :: Item
wristArmour = defaultEquipment
{_itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ EonWristShield --onEquipWristShield
& itUse . eqEq . eqUse .~ EWristShield --setWristShieldPos
& itUse . eqEq . eqOnRemove .~ EoffWristShield --onRemoveWristShield
& itType . iyBase .~ EQUIP WRISTARMOUR
wristArmour =
defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ EonWristShield --onEquipWristShield
& itUse . eqEq . eqUse .~ EWristShield --setWristShieldPos
& itUse . eqEq . eqOnRemove .~ EoffWristShield --onRemoveWristShield
& itType . iyBase .~ EQUIP WRISTARMOUR
onEquipWristShield :: Item -> Creature -> World -> World
onEquipWristShield itm cr w = w
& cWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itUse . eqEq . eqParams .~ EquipID i
& cWorld . walls . at i ?~ forceField {_wlID = i}
& setWristShieldPos (itm & itUse . eqEq . eqParams .~ EquipID i) cr
onEquipWristShield itm cr w =
w
& cWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itUse . eqEq . eqParams .~ EquipID i
& cWorld . walls . at i ?~ forceField{_wlID = i}
& setWristShieldPos (itm & itUse . eqEq . eqParams .~ EquipID i) cr
where
i = IM.newKey (_walls (_cWorld w))
onRemoveWristShield :: Item -> Creature -> World -> World
onRemoveWristShield itm cr w = w
& cWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itUse . eqEq . eqParams .~ NoEquipParams
& deleteWallID i
onRemoveWristShield itm cr w =
w
& cWorld . 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
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))
@@ -112,160 +123,185 @@ setWristShieldPos itm cr w = w
handtrans = case cr ^? crInvEquipped . ix invid of
Just OnLeftWrist -> \cr' -> translatePointToLeftHand cr' . g
_ -> translatePointToRightHand
g | twists cr = (+.+.+ V3 (-5) 10 0)
| otherwise = id
g
| twists cr = (+.+.+ V3 (-5) 10 0)
| otherwise = id
f = (+.+ _crPos cr) . stripZ . rotate3 (_crDir cr) . handtrans cr
torch :: Item
torch = defaultWeapon
& itEffect .~ effectOnOffHeld CreateHeldLight NoInvEffect-- createHeldLight (const $ const id)
& itType . iyBase .~ HELD TORCH
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 10
torch =
defaultWeapon
& itEffect .~ effectOnOffHeld CreateHeldLight NoInvEffect -- createHeldLight (const $ const id)
& itType . iyBase .~ HELD TORCH
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 10
flatShield :: Item
flatShield = defaultWeapon
& itEffect .~ effectOnOffHeld CreateShieldWall RemoveShieldWall --createShieldWall removeShieldWall
-- the above seems to work, but I am not sure why: it may break on edge
-- cases
& itUse .~ defaultrUse
{ _rUse = HeldDoNothing
, _useDelay = NoDelay
, _useMods = HeldModNothing
, _useHammer = HammerUp
, _useAim = AimParams
{ _aimWeight = 5
, _aimRange = 0
, _aimZoom = ItZoom 20 0.2 1
, _aimStance = TwoHandFlat
, _aimHandlePos = 0
, _aimMuzPos = 0
}
}
& itInvSize .~ 3
& itType . iyBase .~ HELD FLATSHIELD
flatShield =
defaultWeapon
& itEffect .~ effectOnOffHeld CreateShieldWall RemoveShieldWall
& itUse
.~ defaultrUse
{ _useAim =
AimParams
{ _aimWeight = 5
, _aimRange = 0
, _aimZoom = ItZoom 20 0.2 1
, _aimStance = TwoHandFlat
, _aimHandlePos = 0
, _aimMuzPos = 0
}
}
& itInvSize .~ 3
& itType . iyBase .~ HELD 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
}
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
---- Lasering -> w
-- _ | isMovementDam dm -> w & creatures . ix crid . crState . crDamage .:~ dm
-- _ -> w
createShieldWall :: Item -> Creature -> World -> World
createShieldWall it cr w = case _ieMID $ _itEffect it of
Nothing -> let (wlid,w') = createWall ((shieldWall crid) {_wlLine = wlline,_wlID = wlid}) w
in w' & cWorld . creatures . ix crid . crInv . ix invid . itEffect . ieMID ?~ wlid
createShieldWall it cr w = case it ^? itEffect . ieMID . _Just of
Nothing ->
let (wlid, w') = createWall ((shieldWall crid){_wlLine = wlline, _wlID = wlid}) w
in w' & cWorld . creatures . ix crid . crInv . ix invid . itEffect . ieMID ?~ wlid
Just wid -> moveWallID wid wlline w
where
invid = fromJust $ _itID it
crid = _crID cr
wlline = (a,b)
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
therot
| crIsAiming cr = vNormal
| otherwise = rotateV (twoFlatHRot cr) . vNormal
removeShieldWall :: Item -> Creature -> World -> World
removeShieldWall it cr w = case _ieMID $ _itEffect it of
Nothing -> w
Just wid -> w & deleteWallID wid
& cWorld . creatures . ix crid . crInv . ix invid . itEffect . ieMID .~ Nothing
Just wid ->
w & deleteWallID wid
& cWorld . creatures . ix crid . crInv . ix invid . itEffect . ieMID .~ Nothing
where
crid = _crID cr
invid = fromJust (_itID it)
effectOnOffHeld
:: ItInvEffect -- ^ effect when held
-> ItInvEffect -- ^ effect when not held
-> ItEffect
effectOnOffHeld f f' = ItInvEffectID
{ _ieInv = OnOffHeldEffect f f'
, _ieMID = Nothing
}
effectOnOffHeld ::
-- | effect when held
ItInvEffect ->
-- | effect when not held
ItInvEffect ->
ItEffect
effectOnOffHeld f f' =
ItInvEffectID
{ _ieInv = OnOffHeldEffect f f'
, _ieMID = Nothing
}
{- | Increases speed, reduces friction, cannot only move forwards. -}
-- | Increases speed, reduces friction, cannot only move forwards.
jetPack :: Item
jetPack = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
} & itUse . eqEq . eqSite .~ GoesOnBack
& itType . iyBase .~ EQUIP JETPACK
jetPack =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnBack
& itType . iyBase .~ EQUIP JETPACK
brainHat :: Item
brainHat = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP BRAINHAT
brainHat =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP BRAINHAT
hat :: Item
hat = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HAT
hat =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HAT
headLamp1 :: Item
headLamp1 = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ EHeadLamp --createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HEADLAMP1
headLamp :: Item
headLamp = defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ EHeadLamp --createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HEADLAMP
headLamp1 =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ EHeadLamp --createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HEADLAMP1
headLamp :: Item
headLamp =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqUse .~ EHeadLamp --createHeadLamp
& itUse . eqEq . eqSite .~ GoesOnHead
& itType . iyBase .~ EQUIP HEADLAMP
createHeadLamp :: Item -> Creature -> World -> World
createHeadLamp _ cr = cWorld . tempLightSources .:~ tlsTimeRadColPos 1 200 0.7
((_crPos cr `v2z` 0) +.+.+ rotate3 (_crDir cr) (translatePointToHead cr (V3 5 0 3)))
createHeadLamp _ cr =
cWorld . 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 .~ EQUIP POWERLEGS
powerLegs =
defaultEquipment
{ _itEffect = NoItEffect
, _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnLegs
& itType . iyBase .~ EQUIP POWERLEGS
speedLegs :: Item
speedLegs = powerLegs
& itType . iyBase .~ EQUIP SPEEDLEGS
speedLegs =
powerLegs
& itType . iyBase .~ EQUIP SPEEDLEGS
jumpLegs :: Item
jumpLegs = powerLegs
& itType . iyBase .~ EQUIP JUMPLEGS
jumpLegs =
powerLegs
& itType . iyBase .~ EQUIP JUMPLEGS
wristInvisibility :: Item
wristInvisibility = defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ ECamouflage Invisible --overCID (crCamouflage .~ Invisible)
& itUse . eqEq . eqOnRemove .~ ECamouflage FullyVisible --overCID (crCamouflage .~ FullyVisible)
& itType . iyBase .~ EQUIP (INVISIBILITYEQUIPMENT GoesOnWrist)
wristInvisibility =
defaultEquipment
{ _itID = Nothing
}
& itUse . eqEq . eqSite .~ GoesOnWrist
& itUse . eqEq . eqOnEquip .~ ECamouflage Invisible --overCID (crCamouflage .~ Invisible)
& itUse . eqEq . eqOnRemove .~ ECamouflage FullyVisible --overCID (crCamouflage .~ FullyVisible)
& itType . iyBase .~ EQUIP (INVISIBILITYEQUIPMENT GoesOnWrist)
overCID :: (Creature -> Creature) -> Item -> Creature -> World -> World
overCID f _ cr = cWorld . creatures . ix (_crID cr) %~ f
+14 -78
View File
@@ -1,84 +1,20 @@
module Dodge.Item.Equipment.Booster
( boosterGun
, boostSelfL
) where
import Dodge.Data
import Dodge.Base
module Dodge.Item.Equipment.Booster (
boosterGun,
) where
import Control.Lens
import Dodge.Data.Item
import Dodge.Default.Weapon
import Geometry
import qualified IntMapHelp as IM
import Picture
import Data.Maybe
import Control.Lens
{- | Move a creature towards the mouse position, with shockwave -}
boostPoint
:: Float -- ^ boost amount
-> Creature
-> World
-> Either Point2 Point2
boostPoint x cr w = case mayp2 of
Nothing -> Right p1
Just p2 -> Left $ mvPointTowardAtSpeed r cpos $ fst p2
where
cpos = _crPos cr
r = 1.5 * _crRad cr
p1 = cpos +.+ x *.* squashNormalizeV (mouseWorldPos w -.- cpos)
mayp2 = bouncePoint (const True) 1 cpos p1 w
boostSelfL
:: Float -- ^ boost amount
-> Item
-> Creature
-> World
-> World
boostSelfL x itm cr w = case boostPoint x cr w of
Left p -> crEff p (itConsumption . laLoaded .~ 0)
Right p -> crEff p (itConsumption . laLoaded -~ 1)
where
invid = _ipInvID $ _itPos itm
cid = _crID cr
cpos = _crPos cr
r = _crRad cr
pid = fromMaybe (IM.newKey $ _props (_cWorld w))
(cr ^? crInv . ix invid . itAttachment . atInt)
crEff p ammoEff = addBoostShockwave pid p (r *.* normalizeV (p -.- cpos)) w
& cWorld . creatures . ix cid %~
(crPos .~ p)
. (crInv . ix invid %~
ammoEff
. (itEffect . ieCounter .~ 1)
. (itAttachment .~ AttachInt pid)
)
addBoostShockwave
:: Int
-> Point2
-> Point2
-> World
-> World
addBoostShockwave pjid p v w = w & cWorld . linearShockwaves %~
IM.insertWith f pjid thePJ
where
thePJ = LinearShockwave
{ _lwPos = p
, _lwID = pjid
, _lwPoints = [(p,v)]
, _lwTimer = maxT
}
f newVal oldVal = newVal & lwPoints %~ (++ _lwPoints oldVal)
maxT :: Int
maxT = 20
boosterGun :: Item
boosterGun = defaultLeftItem
{ _itInvColor = cyan
, _itConsumption = defaultChargeable
, _itUse = luseInstantNoH LBoost
, _itEffect = resetAttachmentID
}
& itType . iyBase .~ LEFT BOOSTER
boosterGun =
defaultLeftItem
{ _itInvColor = cyan
, _itUse = luseInstantNoH LBoost
, _itEffect = resetAttachmentID
}
& itType . iyBase .~ LEFT BOOSTER
resetAttachmentID :: ItEffect
resetAttachmentID = ItInvEffect ResetAttachmentEffect 0
+4 -4
View File
@@ -30,8 +30,8 @@ getItem itid w = do
InInv cid invid -> w ^? cWorld . creatures . ix cid . crInv . ix invid
VoidItm -> Nothing
pointToItem :: Applicative f =>
pointerToItem :: Applicative f =>
ItemPos -> (Item -> f Item) -> World -> f World
pointToItem (InInv cid invid) = cWorld . creatures . ix cid . crInv . ix invid
pointToItem (OnFloor flid) = cWorld . floorItems . ix flid . flIt
pointToItem _ = const pure
pointerToItem (InInv cid invid) = cWorld . creatures . ix cid . crInv . ix invid
pointerToItem (OnFloor flid) = cWorld . floorItems . ix flid . flIt
pointerToItem _ = const pure
+1 -1
View File
@@ -10,7 +10,7 @@ keyCard n = defaultEquipment
-- , _itZoom = defaultItZoom
, _itInvColor = aquamarine
}
& itType . iyBase .~ KEYCARD n
& itType . iyBase .~ HELD (KEYCARD n)
latchkey :: Int -> Item
latchkey _ = defaultEquipment
+5 -7
View File
@@ -55,8 +55,8 @@ sparkGun = teslaGun
& itParams . arcSize .~ 10
teslaGun :: Item
teslaGun = defaultBatteryGun
& itConsumption . laMax .~ 200
& itConsumption . laCycle .~ [loadEject 10, loadInsert 10 , loadPrime 60]
& itUse . heldConsumption . laMax .~ 200
& itUse . heldConsumption . laCycle .~ [loadEject 10, loadInsert 10 , loadPrime 60]
& itDimension . dimRad .~ 9
& itDimension . dimCenter .~ V3 4 0 0
& itParams .~ teslaParams
@@ -91,7 +91,7 @@ lasCircle = lasGun
& itType . iyBase .~ HELD LASCIRCLE
& itParams . lasColor .~ orange
& itParams . lasDamage .~ 2
& itConsumption . laMax .~ 10000
& itUse . heldConsumption . laMax .~ 10000
& itUse . rUse .~ HeldLaser --shootLaser
& itUse . useDelay .~ NoDelay
& itUse . rUse .~ HeldCircleLaser --circleLaser
@@ -212,7 +212,7 @@ dualBeam = lasGun
-- x' = _lasCycle $ _itParams it
lasGun :: Item
lasGun = defaultAutoBatteryGun
& itConsumption .~ ( defaultLoadable
& itUse . heldConsumption .~ ( defaultLoadable
& laMax .~ 200
& laCycle .~ [loadEject 10, loadInsert 10 , loadPrime 60]
)
@@ -225,7 +225,6 @@ lasGun = defaultAutoBatteryGun
}
& itTweaks .~ Tweakable
{ _tweakParams = IM.fromList [(0,lasGunTweak)]
, _tweakSel = 0
}
& itDimension . dimRad .~ 10
& itDimension . dimCenter .~ V3 15 0 0
@@ -247,14 +246,13 @@ lasGunTweak = TweakParam
}
tractorGun :: Item
tractorGun = lasGun
& itConsumption .~
& itUse . heldConsumption .~
( defaultLoadable
& laMax .~ 10000
& laCycle .~ [loadEject 10, loadInsert 10 , loadPrime 60] )
& itParams .~ Attracting {_attractionPower = 1}
& itTweaks .~ Tweakable
{ _tweakParams = IM.fromList [(0,tractorGunTweak)]
, _tweakSel = 0
}
& itUse . rUse .~ HeldTractor --aTractorBeam
& itUse . useDelay .~ NoDelay
+1 -1
View File
@@ -13,7 +13,7 @@ basicBullet = BulletAmmo
}
defaultBullet :: Bullet
defaultBullet = Bullet
{ _buState = NormalBulletState
{ _buDelayFraction = 1
, _buEffect = DestroyBullet
, _buSpawn = BulSpark
, _buUpdateMod = NoBulletUpdateMod
+15 -16
View File
@@ -37,8 +37,8 @@ defaultBangCane =
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 15
& itType . iyBase .~ error "undefined bangCane baseitemtype"
& itConsumption . laMax .~ 1
& itConsumption . laCycle .~ [loadPartialInsert 10 1]
& itUse . heldConsumption . laMax .~ 1
& itUse . heldConsumption . laCycle .~ [loadPartialInsert 10 1]
volleyGun :: Int -> Item
volleyGun i =
@@ -51,7 +51,7 @@ volleyGun i =
& itUse . useAim . aimZoom .~ defaultItZoom{_itZoomFac = 1.5}
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 15
& itConsumption . laMax .~ i
& itUse . heldConsumption . laMax .~ i
& itParams
.~ BulletShooter
{ _muzVel = 0.8
@@ -79,8 +79,8 @@ rifle =
defaultBangCane
& itUse . useAim . aimStance .~ TwoHandTwist
& itType . iyBase .~ HELD RIFLE
& itConsumption . laMax .~ 1
& itConsumption . laCycle .~ [loadEject 5, loadInsert 5, loadPrime 5]
& itUse . heldConsumption . laMax .~ 1
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert 5, loadPrime 5]
& itUse . useAim . aimWeight .~ 6
& itUse . useAim . aimRange .~ 1
& itUse . useAim . aimZoom .~ defaultItZoom{_itZoomFac = 2}
@@ -91,8 +91,8 @@ repeater =
rifle
& itType . iyModules . at ModRifleMag ?~ EMPTYMODULE
& itType . iyBase .~ HELD REPEATER
& itConsumption . laCycle .~ [loadEject 20, loadInsert 20, loadPrime 20]
& itConsumption . laMax .~ 15
& itUse . heldConsumption . laCycle .~ [loadEject 20, loadInsert 20, loadPrime 20]
& itUse . heldConsumption . laMax .~ 15
autoRifle :: Item
autoRifle =
@@ -120,21 +120,20 @@ miniGunUse i =
miniGunX :: Int -> Item
miniGunX i =
defaultAutoGun
{ _itConsumption =
defaultBulletLoadable
{ _laMax = 1500
, _laLoaded = 1500
}
& laCycle .~ [loadEject 40, loadInsert 40, loadPrime 40]
, _itUse =
{ _itUse =
miniGunUse i
& useDelay .~ WarmUpNoDelay{_warmTime = 0, _warmMax = 100}
& useAim . aimWeight .~ 6
& useAim . aimRange .~ 1
& useAim . aimStance .~ TwoHandTwist
& useAim . aimZoom .~ defaultItZoom{_itZoomFac = 1.5}
, -- , _itFloorPict = miniGunPictItem
_itParams =
& heldConsumption
.~ defaultBulletLoadable
{ _laMax = 1500
, _laLoaded = 1500
}
& heldConsumption . laCycle .~ [loadEject 40, loadInsert 40, loadPrime 40]
, _itParams =
BulletShooter
{ _muzVel = 1
, _rifling = 0.9
+6 -6
View File
@@ -30,8 +30,8 @@ bangRod = defaultBulletWeapon
& itUse . useMods .~ BangRodMod
& itDimension . dimRad .~ 12
& itDimension . dimCenter .~ V3 5 0 0
& itConsumption . laMax .~ 1
& itConsumption . laCycle .~ [loadEject 5, loadInsert 10 , loadPrime 5]
& itUse . heldConsumption . laMax .~ 1
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert 10 , loadPrime 5]
& itType . iyBase .~ HELD BANGROD
& itUse . useAim . aimWeight .~ 8
& itUse . useAim . aimRange .~ 1
@@ -39,7 +39,7 @@ bangRod = defaultBulletWeapon
& itUse . useAim . aimZoom .~ defaultItZoom {_itZoomFac = 1.5}
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 30
& itConsumption . laAmmoType .~ hvBullet
& itUse . heldConsumption . laAmmoType .~ hvBullet
elephantGun :: Item
elephantGun = bangRod
& itType . iyBase .~ HELD ELEPHANTGUN
@@ -51,7 +51,7 @@ elephantGun = bangRod
amr :: Item
amr = elephantGun
& itType . iyBase .~ HELD AMR
& itConsumption . laMax .~ 15
& itUse . heldConsumption . laMax .~ 15
autoAmr :: Item
autoAmr = amr
@@ -77,7 +77,7 @@ machineGun = bangRod
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimZoom .~ defaultItZoom {_itZoomFac = 1.5}
& itUse . useDelay .~ VariableRate {_rateMax = 25, _rateMaxMax = 24, _rateMinMax = 7, _rateTime = 0}
& itConsumption . laMax .~ 100
& itConsumption . laCycle .~ [loadEject 10, loadInsert 40 , loadPrime 10]
& itUse . heldConsumption . laMax .~ 100
& itUse . heldConsumption . laCycle .~ [loadEject 10, loadInsert 40 , loadPrime 10]
& itInvSize .~ 3
& itParams. torqueAfter .~ 0.2 -- not sure if this is necessary?
+5 -5
View File
@@ -36,15 +36,15 @@ bangStick i = defaultBulletWeapon
& itType . iyBase .~ HELD (BANGSTICK i)
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 10
& itConsumption . laMax .~ i
& itConsumption . laCycle .~ [loadPartialInsert 10 1]
& itUse . heldConsumption . laMax .~ i
& itUse . heldConsumption . laCycle .~ [loadPartialInsert 10 1]
baseStickSpread :: Float
baseStickSpread = 0.2
revolver :: Item
revolver = pistol
& itConsumption .~
& itUse . heldConsumption .~
(defaultBulletLoadable
& laMax .~ 6
& laCycle .~ [loadPartialInsert 10 1] )
@@ -52,7 +52,7 @@ revolver = pistol
pistol :: Item
pistol = bangStick 1
& itConsumption .~ ( defaultBulletLoadable
& itUse . heldConsumption .~ ( defaultBulletLoadable
& laMax .~ 15
& laCycle .~ [loadEject 5, loadInsert 5 , loadPrime 5] )
& itUse . useDelay . rateMax .~ 6
@@ -89,5 +89,5 @@ revolverX :: Int -> Item
revolverX i = revolver
& itUse . useDelay . rateMax .~ 8
& itUse . useMods .~ RevolverXMod
& itConsumption . laMax .~ i * 6
& itUse . heldConsumption . laMax .~ i * 6
& itType . iyBase .~ HELD (REVOLVERX i)
+6 -6
View File
@@ -82,13 +82,13 @@ bangCone = defaultBulletWeapon
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 15
& itType . iyBase .~ HELD BANGCONE
& itConsumption . laMax .~ 5
& itConsumption . laCycle .~ [loadEject 5, loadInsert 20 , loadPrime 5]
& itUse . heldConsumption . laMax .~ 5
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert 20 , loadPrime 5]
blunderbuss :: Item
blunderbuss = bangCone
& itConsumption . laMax .~ 25
& itConsumption . laCycle .~ [loadEject 5, loadInsert 30 , loadPrime 5]
& itUse . heldConsumption . laMax .~ 25
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert 30 , loadPrime 5]
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimWeight .~ 6
& itUse . useAim . aimHandlePos .~ 5
@@ -97,8 +97,8 @@ blunderbuss = bangCone
grapeCannon :: Int -> Item
grapeCannon i = blunderbuss
& itType . iyBase .~ HELD (GRAPECANNON i)
& itConsumption . laMax .~ 25 + 25 * i
& itConsumption . laCycle .~ [loadEject 5, loadInsert (30 + i * 10) , loadPrime 5]
& itUse . heldConsumption . laMax .~ 25 + 25 * i
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert (30 + i * 10) , loadPrime 5]
& itParams . recoil .~ (150 + fromIntegral i * 50)
& itParams . torqueAfter .~ (0.1 + 0.2 * fromIntegral i)
& itParams . randomOffset .~ (12 + 4 * fromIntegral i)
+2 -2
View File
@@ -16,8 +16,8 @@ droneLauncher = defaultWeapon
& itUse . useAim . aimWeight .~ 8
& itUse . useAim . aimRange .~ 0.5
& itUse . useAim . aimStance .~ TwoHandTwist
& itConsumption . laAmmoType .~ DroneAmmo { _amString = "LASDRONE" }
& itConsumption . laMax .~ 2
& itUse . heldConsumption . laAmmoType .~ DroneAmmo { _amString = "LASDRONE" }
& itUse . heldConsumption . laMax .~ 2
& itType . iyBase .~ HELD DRONELAUNCHER
lasDronesPic :: Item -> SPic
+3 -3
View File
@@ -6,17 +6,17 @@ import Dodge.Data
---- this shouldn't really be used
loadedAmmo :: Item -> Int
loadedAmmo = _laLoaded . _itConsumption
loadedAmmo = _laLoaded . _heldConsumption . _itUse
-- | _laTransfer (_itConsumption it) == NoTransfer = _laLoaded (_itConsumption it)
-- | otherwise = 0
fractionLoadedAmmo :: Item -> Float
fractionLoadedAmmo it = fromIntegral (loadedAmmo it) / fromIntegral (itmaxammo it)
where
itmaxammo = _laMax . _itConsumption
itmaxammo = _laMax . _heldConsumption . _itUse
fractionLoadedAmmo2 :: Item -> Float
fractionLoadedAmmo2 it = 1 -
(1 - fromIntegral (loadedAmmo it) / fromIntegral (itMaxAmmo it))**2
where
itMaxAmmo = _laMax . _itConsumption
itMaxAmmo = _laMax . _heldConsumption . _itUse
+102 -90
View File
@@ -1,110 +1,122 @@
module Dodge.Item.Weapon.Launcher
( launcher
, launcherX
, remoteLauncher
, fireTrackingShell
, explodeRemoteRocket
) where
module Dodge.Item.Weapon.Launcher (
launcher,
launcherX,
remoteLauncher,
fireTrackingShell,
explodeRemoteRocket,
) where
import Control.Lens
import Dodge.Data
import Dodge.Projectile.Create
import Dodge.Payload
import Dodge.Reloading.Action
import Dodge.Default.Weapon
import Dodge.Item.Location
import Dodge.Payload
import Dodge.Projectile.Create
import Dodge.Reloading.Action
import Geometry
import qualified IntMapHelp as IM
import Control.Lens
launcher :: Item
launcher = defaultWeapon
{ _itConsumption = defaultLoadable
& laAmmoType .~ ProjectileAmmo
{ _amPayload = ExplosionPayload
, _amString = "EXPLOSIVE SHELL"
, _amPjDraw = DrawShell
, _amPjCreation = CreateShell
}
& laMax .~ 1
& laLoaded .~ 1
& laCycle .~ [loadEject 30, loadInsert 30, loadPrime 10]
, _itParams = ShellLauncher
{ _shellSpinDrag = 1
, _shellSpinAmount = 2
, _shellThrustDelay = 20
launcher =
defaultWeapon
{ _itParams =
ShellLauncher
{ _shellSpinDrag = 1
, _shellSpinAmount = 2
, _shellThrustDelay = 20
}
, _itTweaks =
Tweakable
{ _tweakParams = basicAmPjMoves
}
, _itInvSize = 3
}
, _itTweaks = Tweakable
{ _tweakSel = 0
, _tweakParams = basicAmPjMoves
}
, _itInvSize = 3
}
& itDimension . dimRad .~ 9
& itDimension . dimCenter .~ V3 10 0 0
& itUse . useDelay . rateMax .~ 20
& itUse . rUse .~ HeldPJCreation --usePjCreation
& itUse . useMods .~ LauncherMod
& itUse . useAim . aimWeight .~ 8
& itUse . useAim . aimRange .~ 0.5
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 20
& itType . iyBase .~ HELD LAUNCHER
& itType . iyModules . at ModLauncherHoming ?~ EMPTYMODULE
& itDimension . dimRad .~ 9
& itDimension . dimCenter .~ V3 10 0 0
& itUse . useDelay . rateMax .~ 20
& itUse . rUse .~ HeldPJCreation --usePjCreation
& itUse . useMods .~ LauncherMod
& itUse . useAim . aimWeight .~ 8
& itUse . useAim . aimRange .~ 0.5
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimHandlePos .~ 5
& itUse . useAim . aimMuzPos .~ 20
& itUse . heldConsumption . laAmmoType .~ ProjectileAmmo
{ _amPayload = ExplosionPayload
, _amString = "EXPLOSIVE SHELL"
, _amPjDraw = DrawShell
, _amPjCreation = CreateShell
}
& itUse . heldConsumption . laMax .~ 1
& itUse . heldConsumption . laLoaded .~ 1
& itUse . heldConsumption . laCycle .~ [loadEject 30, loadInsert 30, loadPrime 10]
& itType . iyBase .~ HELD LAUNCHER
& itType . iyModules . at ModLauncherHoming ?~ EMPTYMODULE
launcherX :: Int -> Item
launcherX i = launcher
& itType . iyBase .~ HELD (LAUNCHERX i)
& itConsumption . laMax .~ i
& itConsumption . laLoaded .~ i
& itUse . rUse .~ HeldPJCreationX i
& itUse . useMods .~ LauncherXMod i
launcherX i =
launcher
& itType . iyBase .~ HELD (LAUNCHERX i)
& itUse . heldConsumption . laMax .~ i
& itUse . heldConsumption . laLoaded .~ i
& itUse . rUse .~ HeldPJCreationX i
& itUse . useMods .~ LauncherXMod i
basicAmPjMoves :: IM.IntMap TweakParam
basicAmPjMoves = IM.fromList . zip [0..] $
[spinDrag
,spinStart
,thrustParam
]
basicAmPjMoves =
IM.fromList . zip [0 ..] $
[ spinDrag
, spinStart
, thrustParam
]
spinDrag :: TweakParam
spinDrag = TweakParam
{ _tweakType = TweakSpinDrag
, _tweakVal = 1
, _tweakMax = 5
}
spinDrag =
TweakParam
{ _tweakType = TweakSpinDrag
, _tweakVal = 1
, _tweakMax = 5
}
spinStart :: TweakParam
spinStart = TweakParam
{ _tweakType = TweakSpinAmount
, _tweakVal = 2
, _tweakMax = 5
}
spinStart =
TweakParam
{ _tweakType = TweakSpinAmount
, _tweakVal = 2
, _tweakMax = 5
}
thrustParam :: TweakParam
thrustParam = TweakParam
{ _tweakType = TweakThrustDelay
, _tweakVal = 1
, _tweakMax = 5
}
thrustParam =
TweakParam
{ _tweakType = TweakThrustDelay
, _tweakVal = 1
, _tweakMax = 5
}
remoteLauncher :: Item
remoteLauncher = launcher
& itType . iyBase .~ HELD REMOTELAUNCHER
& itUse . rUse .~ HeldFireRemoteShell --fireRemoteShell
& itScope .~ RemoteScope (V2 0 0) 1 True
& itConsumption . laAmmoType . amPjDraw .~ DrawRemoteShell
remoteLauncher =
launcher
& itType . iyBase .~ HELD REMOTELAUNCHER
& itUse . rUse .~ HeldFireRemoteShell --fireRemoteShell
& itScope .~ RemoteScope (V2 0 0) 1 True
& itUse . heldConsumption . laAmmoType . amPjDraw .~ DrawRemoteShell
-- TODO consider allowing tweaking rocket speed
explodeRemoteRocket
:: Int -- ^ Item id
-> Int -- ^ Projectile id
-> World
-> World
explodeRemoteRocket itid pjid w = w
& cWorld . projectiles . ix pjid . prjUpdates .~ [PJRetireRemote itid 30 pjid]
& cWorld . projectiles . ix pjid . prjDraw .~ DrawBlankProjectile
& itPoint . itUse . rUse .~ HeldDoNothing
& usePayload (_prjPayload thepj) (_prjPos thepj)
where
itPoint = pointToItem $ _itemPositions (_cWorld w) IM.! itid
explodeRemoteRocket ::
-- | Item id
Int ->
-- | Projectile id
Int ->
World ->
World
explodeRemoteRocket itid pjid w =
w
& cWorld . projectiles . ix pjid . prjUpdates .~ [PJRetireRemote itid 30 pjid]
& cWorld . projectiles . ix pjid . prjDraw .~ DrawBlankProjectile
& itPoint . itUse . rUse .~ HeldDoNothing
& usePayload (_prjPayload thepj) (_prjPos thepj)
where
itPoint = pointerToItem $ _itemPositions (_cWorld w) IM.! itid
thepj = _projectiles (_cWorld w) IM.! pjid
+1 -1
View File
@@ -1,5 +1,5 @@
module Dodge.Item.Weapon.Remote
( pointToItem
( pointerToItem
, setRemoteScope
, setRemoteBombScope
) where
+90 -78
View File
@@ -1,95 +1,107 @@
module Dodge.Item.Weapon.SprayGuns
( poisonSprayer
, flameSpitter
, blowTorch
, flameThrower
, flameTorrent
, flameWall
) where
module Dodge.Item.Weapon.SprayGuns (
poisonSprayer,
flameSpitter,
blowTorch,
flameThrower,
flameTorrent,
flameWall,
) where
import Dodge.Data
import Dodge.Reloading.Action
import Dodge.Default
import Dodge.Reloading.Action
import Geometry
import LensHelp
poisonSprayer :: Item
poisonSprayer = flameThrower
& itType . iyBase .~ HELD POISONSPRAYER
& itConsumption . laAmmoType .~ GasAmmo
{ _amString = "POISONGAS"
, _amCreateGas = CreatePoisonGas --aGasCloud
}
& itUse . useMods .~ PoisonSprayerMod
poisonSprayer =
flameThrower
& itType . iyBase .~ HELD POISONSPRAYER
& itUse . heldConsumption . laAmmoType
.~ GasAmmo
{ _amString = "POISONGAS"
, _amCreateGas = CreatePoisonGas --aGasCloud
}
& itUse . useMods .~ PoisonSprayerMod
flameSpitter :: Item
flameSpitter = flameThrower
& itType . iyBase .~ HELD FLAMESPITTER
& itConsumption . laMax .~ 10
& itConsumption . laCycle .~ [loadEject 5, loadInsert 10 , loadPrime 20]
& itParams . sprayNozzles . ix 0 . nzPressure .~ 4
& itUse . useAim . aimStance .~ OneHand
& itUse . useDelay .~ FixedRate {_rateMax =12,_rateTime = 0}
& itUse . useMods .~ FlameSpitterMod
flameSpitter =
flameThrower
& itType . iyBase .~ HELD FLAMESPITTER
& itUse . heldConsumption . laMax .~ 10
& itUse . heldConsumption . laCycle .~ [loadEject 5, loadInsert 10, loadPrime 20]
& itParams . sprayNozzles . ix 0 . nzPressure .~ 4
& itUse . useAim . aimStance .~ OneHand
& itUse . useDelay .~ FixedRate{_rateMax = 12, _rateTime = 0}
& itUse . useMods .~ FlameSpitterMod
flameTorrent :: Item
flameTorrent = flameThrower
& itType . iyBase .~ HELD FLAMETORRENT
& itUse . useAim . aimZoom .~ defaultItZoom
& itParams . sprayNozzles . ix 0 %~
( (nzPressure .~ 10)
. (nzMaxWalkAngle .~ 1.5)
. (nzWalkSpeed .~ 0.05)
)
flameTorrent =
flameThrower
& itType . iyBase .~ HELD FLAMETORRENT
& itUse . useAim . aimZoom .~ defaultItZoom
& itParams . sprayNozzles . ix 0
%~ ( (nzPressure .~ 10)
. (nzMaxWalkAngle .~ 1.5)
. (nzWalkSpeed .~ 0.05)
)
blowTorch :: Item
blowTorch = flameThrower
& itType . iyBase .~ HELD BLOWTORCH
blowTorch =
flameThrower
& itType . iyBase .~ HELD BLOWTORCH
flameWall :: Item
flameWall = flameThrower
& itType . iyBase .~ HELD FLAMEWALL
& itParams . sprayNozzles .~ zipWith makeNozzle [0,0.6,-0.6] [2,2.5,2.5]
flameWall =
flameThrower
& itType . iyBase .~ HELD FLAMEWALL
& itParams . sprayNozzles .~ zipWith makeNozzle [0, 0.6, -0.6] [2, 2.5, 2.5]
where
makeNozzle dir pres = Nozzle
{ _nzPressure = pres
, _nzDir = dir
, _nzMaxWalkAngle = 0
, _nzWalkSpeed = 0
, _nzCurrentWalkAngle = 0
, _nzLength = 20
}
makeNozzle dir pres =
Nozzle
{ _nzPressure = pres
, _nzDir = dir
, _nzMaxWalkAngle = 0
, _nzWalkSpeed = 0
, _nzCurrentWalkAngle = 0
, _nzLength = 20
}
flameThrower :: Item
flameThrower = defaultAutoGun
{ _itConsumption = defaultLoadable
& laMax .~ 250
& laAmmoType .~ GasAmmo
{_amString = "FLAME"
,_amCreateGas = CreateFlame --aFlame
}
& laCycle .~ [loadEject 5, loadInsert 10 , loadPrime 20]
, _itParams = Sprayer
{ _sprayNozzles =
[ Nozzle
{ _nzPressure = 4
, _nzDir = 0
, _nzMaxWalkAngle = 0.2
, _nzWalkSpeed = 0.01
, _nzCurrentWalkAngle = 0
, _nzLength = 10
flameThrower =
defaultAutoGun
{ _itParams =
Sprayer
{ _sprayNozzles =
[ Nozzle
{ _nzPressure = 4
, _nzDir = 0
, _nzMaxWalkAngle = 0.2
, _nzWalkSpeed = 0.01
, _nzCurrentWalkAngle = 0
, _nzLength = 10
}
]
}
]
}
}
& itDimension . dimRad .~ 7
& itDimension . dimCenter .~ V3 9 0 0
& itUse . rUse .~ HeldOverNozzlesUseGasParams -- overNozzles useGasParams
& itUse . useDelay .~ NoDelay
& itUse . useMods .~ FlameThrowerMod
& itUse . useAim . aimWeight .~ 5
& itUse . useAim . aimZoom .~ defaultItZoom {_itZoomMax = 5, _itZoomMin = 1.5}
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimHandlePos .~ 0
& itUse . useAim . aimMuzPos .~ 18
& itType . iyBase .~ HELD FLAMETHROWER
& itDimension . dimRad .~ 7
& itDimension . dimCenter .~ V3 9 0 0
& itUse . rUse .~ HeldOverNozzlesUseGasParams -- overNozzles useGasParams
& itUse . useDelay .~ NoDelay
& itUse . useMods .~ FlameThrowerMod
& itUse . useAim . aimWeight .~ 5
& itUse . useAim . aimZoom .~ defaultItZoom{_itZoomMax = 5, _itZoomMin = 1.5}
& itUse . useAim . aimStance .~ TwoHandTwist
& itUse . useAim . aimHandlePos .~ 0
& itUse . useAim . aimMuzPos .~ 18
& itUse . heldConsumption
.~ ( defaultLoadable
& laMax .~ 250
& laAmmoType
.~ GasAmmo
{ _amString = "FLAME"
, _amCreateGas = CreateFlame --aFlame
}
& laCycle .~ [loadEject 5, loadInsert 10, loadPrime 20]
)
& itType . iyBase .~ HELD FLAMETHROWER
+13 -13
View File
@@ -141,7 +141,7 @@ ammoCheckI eff itm cr w
| _laLoaded ic <= 0 || not (_laPrimed ic) = w
| otherwise = eff itm cr $ w & cWorld . creatures . ix (_crID cr) %~ crCancelReloading
where
ic = _itConsumption itm
ic = _heldConsumption $ _itUse itm
-- combined ammo and hammer check: want to be able to auto-reload even if the
-- hammer is down?
@@ -152,13 +152,13 @@ ammoHammerCheck eff it cr w
Just HammerUp -> eff it cr $ w & cWorld . creatures . ix (_crID cr) %~ crCancelReloading
_ -> w
where
ic = _itConsumption it
ic = _heldConsumption $ _itUse it
itUseCharge :: Int -> Item -> Item
itUseCharge x = itConsumption . arLoaded %~ (max 0 . subtract x)
itUseCharge x = itUse . leftConsumption . arLoaded %~ (max 0 . subtract x)
itUseAmmo :: Int -> Item -> Item
itUseAmmo x = itConsumption . laLoaded %~ (max 0 . subtract x)
itUseAmmo x = itUse . heldConsumption . laLoaded %~ (max 0 . subtract x)
{- | Fires at an increasing rate.
Has different effect after first fire.
@@ -295,14 +295,14 @@ withSidePushAfterI maxSide eff item cr w = over (cWorld . creatures . ix cid) pu
(pushAmount, g) = randomR (-maxSide,maxSide) $ _randGen w
useAllAmmo :: ChainEffect
useAllAmmo eff item cr = eff item cr
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itConsumption . laLoaded .~ 0)
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itUse . heldConsumption . laLoaded .~ 0)
useAmmoUpTo :: Int -> ChainEffect
useAmmoUpTo amAmount eff item cr = eff item cr
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itConsumption . laLoaded
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itUse . heldConsumption . laLoaded
%~ (max 0 . subtract amAmount))
useAmmoAmount :: Int -> ChainEffect
useAmmoAmount amAmount eff item cr = eff item cr
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itConsumption . laLoaded -~ amAmount)
. (cWorld . creatures . ix (_crID cr) . crInv . ix (crSel cr) . itUse . heldConsumption . laLoaded -~ amAmount)
{- |
Applies a world effect after an item use cooldown check. -}
useTimeCheck :: ChainEffect
@@ -316,7 +316,7 @@ useTimeCheck f item cr w = case item ^? itUse . useDelay . rateTime of
{- | Applies a world effect after a hammer position check. -}
hammerCheckI :: ChainEffect
hammerCheckI f it cr w = case it ^? itUse . useHammer of
Just HammerUp | _laPrimed (_itConsumption it)
Just HammerUp | _laPrimed (_heldConsumption (_itUse it))
-> f it cr w
_ -> w
@@ -335,7 +335,7 @@ ammoUseCheck f item cr w
pointerToItem = cWorld . creatures . ix cid . crInv . ix itRef
fireCondition = crWeaponReady cr
&& _rateTime (_useDelay (_itUse item)) == 0
&& _laLoaded (_itConsumption item) > 0
&& _laLoaded (_heldConsumption (_itUse item)) > 0
-- reloadCondition = _laLoaded (_itConsumption item) == 0
{- | Applies a world effect after a hammer position check.
Arbitrary inventory position. -}
@@ -366,7 +366,7 @@ shootL f item cr w
invid = _ipInvID $ _itPos item
pointerToItem = cWorld . creatures . ix cid . crInv . ix invid
fireCondition = _rateTime (_useDelay (_itUse item)) == 0
&& _arLoaded (_itConsumption item) > 0
&& _arLoaded (_leftConsumption (_itUse item)) > 0
-- reloadCondition = _laLoaded (_itConsumption item) == 0
withItem :: (Item -> ChainEffect) -> ChainEffect
withItem g f it = g it f it
@@ -541,7 +541,7 @@ spreadLoaded eff item cr w = foldr f w dirs
dirs = subtract cd . (spread *) . fromIntegral <$> [0 .. numBulLoaded - 1]
f dir = eff item (cr & crDir +~ dir)
spread = _spreadAngle . _brlSpread . _gunBarrels $ _itParams item
numBulLoaded = _laLoaded $ _itConsumption item
numBulLoaded = _laLoaded $ _heldConsumption (_itUse item)
sideEffectOnFrame :: Int
-> (Item -> Creature -> WdWd)
@@ -571,7 +571,7 @@ duplicateLoaded :: ChainEffect
duplicateLoaded eff it cr w = foldr f w [1..numBul]
where
f _ = eff it cr
numBul = _laLoaded $ _itConsumption it
numBul = _laLoaded $ _heldConsumption (_itUse it)
duplicateLoadedBarrels :: ChainEffect
duplicateLoadedBarrels eff item cr w = foldr f w poss
@@ -582,7 +582,7 @@ duplicateLoadedBarrels eff item cr w = foldr f w poss
poss = map (rotateV (_crDir cr) . V2 0 . (*5) . (+ cp) . fromIntegral) [0 .. numBul - 1]
f pos = eff item (cr & crPos %~ (+.+ pos))
numBar = _brlNum . _gunBarrels $ _itParams item
numBul = _laLoaded $ _itConsumption item
numBul = _laLoaded $ _heldConsumption (_itUse item)
duplicateOffsetsFocus :: [Float] -> ChainEffect
duplicateOffsetsFocus xs eff item cr w = foldr f w poss
+59 -50
View File
@@ -1,60 +1,67 @@
module Dodge.Item.Weapon.Utility where
import Dodge.Data
import Control.Lens
import Data.Maybe
import Dodge.Base.Coordinate
import Dodge.Data
import Dodge.Default
import Dodge.Item.Weapon.ExtraEffect
import Dodge.Wall.ForceField
import Dodge.Wall.Move
import Geometry
import Picture
import qualified IntMapHelp as IM
import Picture
import Shape
import ShapePicture
import Data.Maybe
import Control.Lens
rewindGun :: Item
rewindGun = defaultLeftItem
{ _itInvColor = cyan
, _itConsumption = ChargeableAmmo
{ _wpMaxCharge = 250
, _wpCharge = 0
rewindGun =
defaultLeftItem
{ _itInvColor = cyan
, _itEffect = ItRewindEffect RewindEffect -- []
, _itUse =
defaultlUse
& lUse .~ LRewind --useRewindGun
& eqEq . eqSite .~ GoesOnChest
}
, _itEffect = ItRewindEffect RewindEffect-- []
, _itUse = defaultlUse
& lUse .~ LRewind --useRewindGun
& eqEq . eqSite .~ GoesOnChest
}
& itType . iyBase .~ LEFT REWINDER
& itType . iyBase .~ LEFT REWINDER
& itUse . leftConsumption
.~ ChargeableAmmo
{ _wpMaxCharge = 250
, _wpCharge = 0
}
-- needs to shift this item to the current inventory slot
shrinkGun :: Item
shrinkGun = defaultLeftItem
{_itUse = defaultlUse & lUse .~ LShrink -- hammerCheckL useShrinkGun
-- , _itFloorPict = shrinkGunPic
, _itAttachment = AttachBool True
}
& itType . iyBase .~ LEFT SHRINKER
shrinkGun =
defaultLeftItem
{ _itUse = defaultlUse & lUse .~ LShrink -- hammerCheckL useShrinkGun
-- , _itFloorPict = shrinkGunPic
, _itAttachment = AttachBool True
}
& itType . iyBase .~ LEFT SHRINKER
shrinkGunPic :: Item -> SPic
shrinkGunPic _ = noPic $ colorSH violet $ upperPrismPoly 5 $ square 5
blinkGun :: Item
blinkGun = defaultLeftItem
{ _itInvColor = cyan
, _itUse = defaultlUse
& lUse .~ LBlink --hammerCheckL (shootL $ const blinkAction)
& eqEq . eqSite .~ GoesOnWrist
-- , _itFloorPict = const . noPic . colorSH chartreuse $ upperPrismPoly 2 $ square 2
}
& itType . iyBase .~ LEFT BLINKER
blinkGun =
defaultLeftItem
{ _itInvColor = cyan
, _itUse =
defaultlUse
& lUse .~ LBlink --hammerCheckL (shootL $ const blinkAction)
& eqEq . eqSite .~ GoesOnWrist
-- , _itFloorPict = const . noPic . colorSH chartreuse $ upperPrismPoly 2 $ square 2
}
& itType . iyBase .~ LEFT BLINKER
unsafeBlinkGun :: Item
unsafeBlinkGun = blinkGun
& itType . iyBase .~ LEFT BLINKERUNSAFE
& itUse . lUse .~ LUnsafeBlink --hammerCheckL (shootL $ const unsafeBlinkAction)
& itUse . eqEq . eqViewDist ?~ 400
unsafeBlinkGun =
blinkGun
& itType . iyBase .~ LEFT BLINKERUNSAFE
& itUse . lUse .~ LUnsafeBlink --hammerCheckL (shootL $ const unsafeBlinkAction)
& itUse . eqEq . eqViewDist ?~ 400
--effectGun :: String -> (Creature -> World -> World) -> Item
--effectGun name eff = defaultWeapon
@@ -69,34 +76,36 @@ unsafeBlinkGun = blinkGun
-- }
-- & itType . iyBase .~ AUTOEFFGUN name
forceFieldGun :: Item
forceFieldGun = defaultWeapon
{ _itConsumption = defaultLoadable & laAmmoType .~ ForceFieldAmmo forceField
, _itTargeting = targetRBPress & tgDraw .~ TargetDistanceDraw
, _itParams = ParamMID Nothing
}
& itUse . rUse .~ HeldForceField --useForceFieldGun
& itUse . useDelay .~ NoDelay
& itUse . useMods .~ AmmoHammerTimeUseOneMod -- this is slightly different
forceFieldGun =
defaultWeapon
& itTargeting .~ (targetRBPress & tgDraw .~ TargetDistanceDraw)
& itParams .~ ParamMID Nothing
& itUse . rUse .~ HeldForceField --useForceFieldGun
& itUse . useDelay .~ NoDelay
& itUse . useMods .~ AmmoHammerTimeUseOneMod -- this is slightly different
-- than the list below
--[ hammerCheckI , ammoCheckI , useAmmoAmount 1]
& itType . iyBase .~ HELD FORCEFIELDGUN
& itType . iyBase .~ HELD FORCEFIELDGUN
& itUse . heldConsumption .~ (defaultLoadable & laAmmoType .~ ForceFieldAmmo forceField)
-- I believe because the targeting returns to nothing straight after you release
-- the rmb, it is possible for this to do nothing
-- TODO investigate more and fix
useForceFieldGun :: Item -> Creature -> World -> World
useForceFieldGun itm cr w = fromMaybe w $ do
useForceFieldGun itm cr w = fromMaybe w $ do
a <- _tgPos $ _itTargeting itm
let mwp = mouseWorldPos w
b = if dist a mwp < 100 then mwp else a +.+ 100 *.* normalizeV (mwp -.- a)
wlline = (a,b)
return $ w
& cWorld . walls %~ IM.insertWith (\_ x -> x) i forceField {_wlID = i}
& cWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itParams . paramMID ?~ i
& moveWallIDUnsafe i wlline
wlline = (a, b)
return $
w
& cWorld . walls %~ IM.insertWith (\_ x -> x) i forceField{_wlID = i}
& cWorld . creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itParams . paramMID ?~ i
& moveWallIDUnsafe i wlline
where
i = fromMaybe (IM.newKey (_walls (_cWorld w))) $ itm ^? itParams . paramMID . _Just
-- grapGun = defaultGun
-- grapGun = defaultGun
-- { _itName = "grapGun"
-- , _itIdentity = GrapGun
-- , _wpMaxAmmo = 1