Files
loop/src/Dodge/Item/Weapon/SprayGuns.hs
T
2022-03-25 19:04:13 +00:00

211 lines
6.2 KiB
Haskell

module Dodge.Item.Weapon.SprayGuns
( poisonSprayer
, flameSpitter
, blowTorch
, flameThrower
, flameTorrent
, flameWall
) where
import Dodge.Data
--import Dodge.Data.SoundOrigin
--import Dodge.Base
--import Dodge.Zone
--import Dodge.Picture.Layer
--import Dodge.SoundLogic
import Dodge.SoundLogic.LoadSound
--import Dodge.Creature.Action
import Dodge.WorldEvent
import Dodge.Default
--import Dodge.Item.Weapon.BulletGuns
--import Dodge.Item.Weapon.InventoryDisplay
import Dodge.Item.Weapon.TriggerType
--import Dodge.Item.Weapon.ExtraEffect
--import Dodge.Item.Weapon.UseEffect
import Dodge.Item.Weapon.AmmoParams
import Dodge.Default.Weapon
--import Dodge.Item.Attachment
import Geometry
--import Geometry.Vector3D
import Picture
import Shape
import ShapePicture
import LensHelp
import Data.Traversable
import qualified Data.IntMap.Strict as IM
import Control.Monad.State
--import Data.Function
import System.Random
poisonSprayer :: Item
poisonSprayer = flameThrower
{ _itName = "POISONSPRAYER"
, _itType = POISONSPRAYER
}
& itConsumption . aoType .~ GasAmmo
{ _amString = "POISONGAS"
, _amCreateGas = aGasCloud
}
& itUse . useMods .~
[ ammoCheckI
, withSoundForI foamSprayLoopS 5
, useAmmoAmount 1
-- , spreadNumI
]
flamerPic :: Item -> SPic
flamerPic it =
( colorSH yellow $
translateSHf tx ty (upperPrismPoly tz $ polyCirc 3 r)
++ upperPrismPoly 5 (rectNESW 2 18 (-2) 0)
, color black $ translate3 (V3 tx ty (tz+0.01)) $ circleSolid (r * am)
)
where
tx = 4
ty = - 6
tz = 3
r = 5
am = fractionLoadedAmmo2 it
flameSpitter :: Item
flameSpitter = flameThrower
& itName .~ "FLAMESPITTER"
& itType .~ FLAMESPITTER
& itConsumption . ammoBaseMax .~ 10
& itConsumption . reloadTime .~ 20
& itParams . sprayNozzles . ix 0 . nzPressure .~ 4
& itUse . useAim . aimStance .~ OneHand
& itUse . useDelay .~ FixedRate {_rateMax =12,_rateTime = 0}
& itUse . useMods .~
[ ammoCheckI
, useTimeCheck
, lockInvFor 10
, repeatOnFrames [1..9]
, withRandomItemParams f
, useAmmoAmount 1
, withSidePushI 5
, withSidePushAfterI 20
]
where
f = do
nzpres <- state $ randomR (3,4)
return $ sprayNozzles . ix 0 . nzPressure .~ nzpres
flameTorrent :: Item
flameTorrent = flameThrower
& itName .~ "FLAMETORRENT"
& itType .~ FLAMETORRENT
& itUse . useAim . aimZoom .~ defaultItZoom
& itParams . sprayNozzles . ix 0 %~
( (nzPressure .~ 10)
. (nzMaxWalkAngle .~ 1.5)
. (nzWalkSpeed .~ 0.05)
)
blowTorch :: Item
blowTorch = flameThrower
& itName .~ "BLOWTORCH"
& itType .~ BLOWTORCH
flameWall :: Item
flameWall = flameThrower
& itName .~ "FLAMEWALL"
& itType .~ 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
}
flameThrower :: Item
flameThrower = defaultAutoGun
{ _itName = "FLAMETHROWER"
, _itType = FLAMETHROWER
, _itConsumption = defaultAmmo
{ _ammoBaseMax = 250
, _ammoLoaded = 0
, _reloadTime = 100
, _aoType = GasAmmo
{_amString = "FLAME"
,_amCreateGas = aFlame
}
}
, _itUse = ruseInstant (overNozzles useGasParams) NoHammer
[ ammoCheckI
, useAmmoAmount 1
, withSidePushI 5
--, withTempLight 1 100 (V3 1 0 0)
, withSidePushAfterI 20
]
& useAim . aimSpeed .~ 0.5
& useAim . aimZoom .~ defaultItZoom {_itZoomMax = 5, _itZoomMin = 1.5}
& useAim . aimStance .~ TwoHandTwist
-- , _itFloorPict = flamerPic
-- , _itZoom = defaultItZoom
, _itAttachment = NoItAttachment
, _itParams = Sprayer
{ _sprayNozzles =
[ Nozzle
{ _nzPressure = 4
, _nzDir = 0
, _nzMaxWalkAngle = 0.2
, _nzWalkSpeed = 0.01
, _nzCurrentWalkAngle = 0
, _nzLength = 10
}
]
}
, _itDimension = ItemDimension
{ _dimRad = 7
, _dimCenter = V3 9 0 0
, _dimPortage = HeldItem
{ _handlePos = 5
, _muzPos = 18
}
, _dimSPic = flamerPic
}
-- , _itFloorPict = flamerPic
}
aGasCloud :: Float -> Point2 -> Float -> Creature -> World -> World
aGasCloud pressure pos dir cr = makeGasCloud pos
$ (_crPos cr -.- _crOldPos cr) +.+ pressure *.* unitVectorAtAngle dir
overNozzles :: (Nozzle -> Item -> Creature -> World -> World)
-> Item -> Creature -> World -> World
overNozzles = overNozzles' . overNozzle
overNozzles' :: (Item -> Creature -> World -> Nozzle -> (World,Nozzle))
-> Item -> Creature -> World -> World
overNozzles' eff it cr w = neww & creatures . ix cid . crInv . ix i . itParams . sprayNozzles .~ newNozzles
where
cid = _crID cr
i = _crInvSel $ _creatures w IM.! cid
(neww,newNozzles) = mapAccumR (eff it cr) w $ _sprayNozzles (_itParams it)
overNozzle :: (Nozzle -> Item -> Creature -> World -> World)
-> Item -> Creature -> World -> Nozzle -> (World, Nozzle)
overNozzle eff it cr w nz =
( eff nz it (cr & crDir +~ wa + na) w & randGen .~ g
, nz & nzCurrentWalkAngle .~ wa)
where
na = _nzDir nz
(walkamount, g) = randomR (-aspeed,aspeed) (_randGen w)
aspeed = _nzWalkSpeed nz
maxa = _nzMaxWalkAngle nz
wa = min maxa $ max (negate maxa) (_nzCurrentWalkAngle nz + walkamount)
useGasParams :: Nozzle -> Item -> Creature -> World -> World
useGasParams nz it cr = _amCreateGas (_aoType (_itConsumption it)) (_nzPressure nz) pos dir cr
where
dir = _crDir cr
pos = _crPos cr +.+ (_nzLength nz *.* unitVectorAtAngle (_crDir cr))
aFlame :: Float -> Point2 -> Float -> Creature -> World -> World
aFlame pressure pos dir cr w = w & instantParticles .:~ aFlameParticle t pos vel (Just $ _crID cr)
where
(t,_) = randomR (99,101) (_randGen w)
vel = (_crPos cr -.- _crOldPos cr) +.+ pressure *.* unitVectorAtAngle dir