Files
loop/src/Dodge/Placement/Instance/Turret.hs
T
2021-12-05 16:54:08 +00:00

95 lines
3.0 KiB
Haskell

module Dodge.Placement.Instance.Turret where
import Color
import Dodge.Data
import Dodge.LevelGen.Data
import Dodge.Default
import Dodge.FloorItem
import Dodge.Wall.Delete
import Dodge.WorldEvent.Explosion
import Dodge.Item.Weapon.BatteryGuns
import Dodge.SoundLogic.LoadSound
import Dodge.SoundLogic
import Dodge.Item.Draw
import Geometry
import ShapePicture
import Shape
import Dodge.Base
import Dodge.Base.Collide
import Data.List
import Control.Lens
import qualified Data.IntMap.Strict as IM
putLasTurret :: Float -> Placement
putLasTurret rotSpeed = sps0 $ PutMachine blue (reverse $ square wdth) defaultMachine
{ _mcDraw = drawTurret
, _mcUpdate = updateTurret rotSpeed
, _mcType = lasTurret
, _mcHP = 50000
}
lasTurret :: MachineType
lasTurret = Turret
{ _tuWeapon = lasGun
, _tuTurnSpeed = 0.1
, _tuFireTime = 0
}
updateTurret :: Float -> Machine -> World -> World
updateTurret rotSpeed mc w
| _mcHP mc < 1 = w & machines %~ IM.delete mcid
& deleteWallIDs (_mcWallIDs mc)
& makeExplosionAt mcpos
& copyItemToFloor mcpos lasGun
| otherwise = w & doDamage & maybeFire & elecDamBranch
where
doDamage = machines . ix mcid %~
( (mcDamage .~ [Electrical (min 2500 $ max 0 (elecDam - 10)) 0 0 0])
. (mcHP -~ dam)
)
elecDamBranch
| elecDam < 10 = updateFiringStatus . doTurn
| otherwise = id
-- TODO make this use the same function as the lasgun
maybeFire
| _tuFireTime (_mcType mc) > 0
= ( particles %~ (makeLaserAt 5 (mcpos + 15 *.* unitVectorAtAngle mcdir) mcdir :) )
. soundContinue (MachineSound mcid) mcpos tone440sawtoothquietS (Just 1)
| otherwise = id
mcid = _mcID mc
ypos = _crPos $ you w
mcpos = _mcPos mc
mcdir = _mcDir mc
seesYou = hasLOSIndirect mcpos ypos w
(elecDams, dams) = partition isElectrical $ _mcDamage mc
dam = sum $ map _dmAmount dams
elecDam = sum $ map _dmAmount elecDams
doTurn
| seesYou = machines . ix mcid . mcDir %~ turnTo rotSpeed mcpos ypos
| otherwise = id
closeFireAngle = seesYou && angleVV (ypos -.- mcpos) (unitVectorAtAngle mcdir) < 1
updateFiringStatus
| closeFireAngle = machines . ix mcid . mcType . tuFireTime .~ 20
| otherwise = machines . ix mcid . mcType . tuFireTime %~ (max 0 . subtract 1)
turnTo :: Float -> Point2 -> Point2 -> Float -> Float
turnTo turnSpeed sp tp a
| vToTarg == V2 0 0 = a
| angleVV vToTarg vdir <= turnSpeed
= argV vToTarg
| isLHS (sp +.+ vdir) sp tp = a - turnSpeed
| otherwise = a + turnSpeed
where
vdir = unitVectorAtAngle a
vToTarg = tp -.- sp
drawTurret :: Machine -> SPic
drawTurret mc = (rotateSH (-_mcDir mc) . colorSH blue $ upperPrismPoly 20 (square wdth)
, mempty -- setLayer 5 $ scale 0.5 0.5 $ text $ show $ _mcDir mc )
)
<> translateSPz 20 (itSPic it)
where
it = _tuWeapon $ _mcType mc
wdth :: Float
wdth = 10