Files
loop/src/Dodge/Item/Weapon/SprayGuns.hs
T

202 lines
6.2 KiB
Haskell

module Dodge.Item.Weapon.SprayGuns
( poisonSprayer
, flameSpitter
, blowTorch
, flameThrower
, flameTorrent
, flameWall
) where
import Dodge.Data
import Dodge.Reloading.Action
import Dodge.Particle.Flame
--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
& itType . iyBase .~ HELD POISONSPRAYER
& itConsumption . laAmmoType .~ 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
& 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 .~
[ 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
& 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
flameWall :: Item
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
}
flameThrower :: Item
flameThrower = defaultAutoGun
{ _itConsumption = defaultLoadable
& laMax .~ 250
& laAmmoType .~ GasAmmo
{_amString = "FLAME"
,_amCreateGas = 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
}
]
}
, _itDimension = ItemDimension
{ _dimRad = 7
, _dimCenter = V3 9 0 0
, _dimSPic = flamerPic
}
-- , _itFloorPict = flamerPic
}
& itUse . rUse .~ overNozzles useGasParams
& itUse . useDelay .~ NoDelay
& itUse . useMods .~
[ ammoCheckI
, useAmmoAmount 1
, withSidePushI 5
--, withTempLight 1 100 (V3 1 0 0)
, withSidePushAfterI 20
]
& 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
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 = crSel $ _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 (_laAmmoType (_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 = makeFlame pos vel
--w & instantParticles .:~ aFlameParticle t pos vel Nothing -- (Just $ _crID cr)
where
-- (t,_) = randomR (99,101) (_randGen w)
vel = (_crPos cr -.- _crOldPos cr) +.+ pressure *.* unitVectorAtAngle dir