95 lines
3.0 KiB
Haskell
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
|