module Dodge.Item.Weapon.Utility where import Dodge.Data import Dodge.Base.Coordinate import Dodge.Default --import Dodge.Picture.Layer import Dodge.Creature.Action import Dodge.Item.Weapon.TriggerType import Dodge.Item.Weapon.ExtraEffect import Dodge.Default.Weapon import Dodge.Wall.ForceField import Dodge.Wall.Move --import Sound.Data import Geometry import Picture import qualified IntMapHelp as IM import Shape import ShapePicture import Data.Maybe --import qualified Data.Map.Strict as M import Control.Lens --import Control.Monad rewindGun :: Item rewindGun = defaultLeftItem { _itInvColor = cyan , _itConsumption = ChargeableAmmo { _wpMaxCharge = 250 , _wpCharge = 0 } , _itEffect = ItRewindEffect rewindEffect [] , _itUse = defaultlUse & lUse .~ useRewindGun & eqEq . eqSite .~ GoesOnChest } & itType . iyBase .~ REWINDER rewindEffect :: Item -> Creature -> World -> World rewindEffect itm cr w | Just invid == _crLeftInvSel cr = w & rewindWorlds %~ (take maxcharge . (w' : )) & ptrWpCharge .~ length (_rewindWorlds w) | otherwise = w & rewindWorlds .~ [] & ptrWpCharge .~ 0 where invid = _ipInvID $ _itPos itm ptrWpCharge = creatures . ix (_crID cr) . crInv . ix invid . itConsumption . wpCharge maxcharge = _wpMaxCharge . _itConsumption $ itm w' = w & rewindWorlds .~ [] & timeFlow .~ NormalTimeFlow useRewindGun :: Item -> Creature -> World -> World useRewindGun _ _ w = case _rewindWorlds w of [w'] -> rewindusing w' [w'] (w':ws) -> rewindusing w' ws _ -> w where rewindusing w' ws = w & maybeWorld .~ Just' ( w' -- & creatures . ix (_crID cr) .~ cr & upbuts & rewindWorlds .~ ws ) upbuts = (keys .~ _keys w) . (mouseButtons .~ _mouseButtons w) -- needs to shift this item to the current inventory slot shrinkGun :: Item shrinkGun = defaultLeftItem {_itUse = defaultlUse {_lUse = hammerCheckL useShrinkGun} -- , _itFloorPict = shrinkGunPic , _itAttachment = AttachBool True } & itType . iyBase .~ SHRINKER shrinkGunPic :: Item -> SPic shrinkGunPic _ = noPic $ colorSH violet $ upperPrismPoly 5 $ square 5 -- be careful changing this around; potential problems include updating the -- creature but using the old crInvSel value -- 22.05.23 this has been changed from using invids to items useShrinkGun :: Item -> Creature -> World -> World useShrinkGun it cr w = if _atBool $ _itAttachment it then tryResize 0.5 $ stripNoItems cr . f False UndroppableIdentified . dropExcept cr invid else tryResize 1 $ f True Uncursed . setMinInvSize defaultInvSize cr where invid = _ipInvID $ _itPos it tryResize x g = maybe w g $ sizeSelf x cr w f isInUse cstatus = creatures . ix (_crID cr) . crInv . ix invid %~ ( (itAttachment . atBool .~ isInUse) . (itCurseStatus .~ cstatus) ) blinkGun :: Item blinkGun = defaultLeftItem { _itInvColor = cyan , _itUse = defaultlUse & lUse .~ hammerCheckL (shootL $ const blinkAction) & eqEq . eqSite .~ GoesOnWrist -- , _itFloorPict = const . noPic . colorSH chartreuse $ upperPrismPoly 2 $ square 2 } & itType . iyBase .~ BLINKER unsafeBlinkGun :: Item unsafeBlinkGun = blinkGun & itType . iyBase .~ BLINKERUNSAFE & itUse . lUse .~ hammerCheckL (shootL $ const unsafeBlinkAction) & itUse . eqEq . eqViewDist ?~ 400 effectGun :: String -> (Creature -> World -> World) -> Item effectGun name eff = defaultWeapon { _itUse = defaultrUse & rUse .~ const eff & useMods .~ [hammerCheckI] } & itType . iyBase .~ EFFGUN name autoEffectGun :: String -> (Creature -> World -> World) -> Item autoEffectGun name eff = defaultWeapon { _itUse = defaultrUse {_rUse = const eff} } & itType . iyBase .~ AUTOEFFGUN name forceFieldGun :: Item forceFieldGun = defaultWeapon { _itConsumption = defaultLoadable & laAmmoType .~ ForceFieldAmmo forceField , _itTargeting = targetRBPress & tgDraw .~ targetDistanceDraw , _itParams = ParamMID Nothing } & itUse . rUse .~ useForceFieldGun & itUse . useDelay .~ NoDelay & itUse . useMods .~ [ hammerCheckI , ammoCheckI , useAmmoAmount 1] & itType . iyBase .~ FORCEFIELDGUN -- 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 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 & walls %~ IM.insertWith (\_ x -> x) i forceField {_wlID = i} & creatures . ix (_crID cr) . crInv . ix (_ipInvID (_itPos itm)) . itParams . paramMID ?~ i & moveWallIDUnsafe i wlline where i = fromMaybe (IM.newKey (_walls w)) $ itm ^? itParams . paramMID . _Just -- grapGun = defaultGun -- { _itName = "grapGun" -- , _itIdentity = GrapGun -- , _wpMaxAmmo = 1 -- , _wpLoadedAmmo = 1 -- , _wpReloadTime = 40 -- , _wpReloadState = 0 -- , _itUseRate = 10 -- , _itUseTime = 0 -- , _itUse = grapFire -- , _wpSpread = 0.002 -- , _wpRange = 20 -- , _wpIsAuto = False -- , _itFloorPict = onLayer FlItLayer $ polygon [(-4,-4),(-4,4),(4,4),(4,0),(0,0),(0,-4)] -- , _itAmount = 1 -- , _itMaxStack = 1 -- , _itAimingSpeed = 1 -- , _itAimingRange = 0.5 -- }