diff --git a/src/Dodge/Barreloid.hs b/src/Dodge/Barreloid.hs new file mode 100644 index 000000000..cb0c97084 --- /dev/null +++ b/src/Dodge/Barreloid.hs @@ -0,0 +1,62 @@ +module Dodge.Barreloid where +import Dodge.Data +import Dodge.WorldEvent.Explosion +import Dodge.Spark +import Dodge.Creature.State +import Geometry +import Dodge.SoundLogic +import LensHelp + +import System.Random +import Data.List + +updateBarreloid :: Creature -> World -> World +updateBarreloid cr = case cr ^?! crType . barrelType of + ExplosiveBarrel -> updateExpBarrel cr + PlainBarrel -> updateBarrel cr + +-- should generate the sparks externally using new random generators +updateExpBarrel :: Creature -> World -> World +updateExpBarrel cr w + | _crHP cr > 0 = foldr ($) (hiss w & creatures . at (_crID cr) .~ newCr) pierceSparks + | otherwise = makeExplosionAt (_crPos cr) $ stopSounds w & creatures . at (_crID cr) .~ Nothing + where + g = _randGen w + damages = _csDamage $ _crState cr + pierceSparks :: [World -> World] + pierceSparks + = zipWith3 (\p a -> createBarrelSpark (_crPos cr +.+ p) (a + argV p)) + poss as colids + as = randomRs (-0.7,0.7) g + colids = randomRs (0,11) g + poss = _piercedPoints $ _csSpState $ _crState cr + newCr = Just $ applyFuseDamage $ set (crState . csDamage) [] $ damToExpBarrel damages cr + applyFuseDamage cr' = cr' & crHP %~ + subtract (length . _piercedPoints . _csSpState $ _crState cr') + hiss | null poss = id + | otherwise = soundMultiFrom [BarrelHiss 0,BarrelHiss 1] (_crPos cr) foamSprayLoopS (Just 1) + stopSounds = stopSoundFrom (BarrelHiss 0) . stopSoundFrom (BarrelHiss 1) + +updateBarrel :: Creature -> World -> World +updateBarrel cr + | _crHP cr > 0 = doDamage cr + | otherwise = creatures . at (_crID cr) .~ Nothing + +damToExpBarrel :: [Damage] -> Creature -> Creature +damToExpBarrel ds cr = foldr damToExpBarrel' (foldr damToExpBarrel' cr pierceDam) otherDam + where + (pierceDam,otherDam) = partition isPierce ds + isPierce Damage{_dmType = PIERCING{}} = True + isPierce _ = False + +damToExpBarrel' :: Damage -> Creature -> Creature +damToExpBarrel' dm cr = case _dmType dm of + PIERCING -> over (crState . csSpState . piercedPoints) ((:) $ int -.- _crPos cr) + $ cr & crHP -~ div amount 200 + POISONDAM -> cr + SPARKING -> cr +-- PUSHDAM -> cr LensHelp.& crPos .+.+~ (1 / _crMass cr *.* _dePushBack (_dmEffect dm)) + _ -> cr LensHelp.& crHP -~ amount + where + amount = _dmAmount dm + int = _dmAt dm diff --git a/src/Dodge/Creature.hs b/src/Dodge/Creature.hs index 063f06862..796d176f6 100644 --- a/src/Dodge/Creature.hs +++ b/src/Dodge/Creature.hs @@ -10,19 +10,12 @@ module Dodge.Creature , armourChaseCrit ) where import Dodge.Creature.State.Data -import Dodge.Creature.Update import Dodge.Prop.Gib --import Dodge.Item.Weapon.Grenade import Dodge.Item.Equipment.Booster import Dodge.Item.Weapon.Utility import Dodge.Item.Weapon.Drone import Dodge.Item.Craftable ---import Dodge.Creature.AlertLevel ---import Dodge.Creature.SetTarget -import Dodge.Creature.Volition -import Dodge.Creature.Test ---import Dodge.Creature.Impulse -import Dodge.Creature.SentinelAI import Dodge.Creature.LauncherCrit import Dodge.Creature.PistolCrit import Dodge.Creature.LtAutoCrit @@ -36,9 +29,7 @@ import Dodge.Item.Weapon import Dodge.Item.Equipment import Dodge.Item.Consumable import Dodge.WorldEvent.Cloud -import Dodge.Creature.YourControl import Dodge.Creature.Inanimate -import Dodge.Creature.State import Dodge.Creature.Picture --import Dodge.Creature.ChooseTarget --import Dodge.Item @@ -65,20 +56,17 @@ spawnerCrit = defaultCreature miniGunCrit :: Creature miniGunCrit = defaultCreature - { _crUpdate = defaultImpulsive [sentinelFireType (const shootTillEmpty)] --- , _crInv = IM.fromList [(0,autoRifle & itConsumption . ammoLoaded .~ 1000)] - , _crInv = IM.fromList [(0,miniGunX 3)] --- , _crInv = IM.fromList [(0,autoRifle)] + { _crInv = IM.fromList [(0,miniGunX 3)] , _crRad = 10 , _crState = defaultState , _crHP = 500 , _crMvType = defaultAimMvType } & crType . skinUpper .~ light4 red + & crType . humanoidAI .~ MiniGunAI longCrit :: Creature longCrit = defaultCreature - { _crUpdate = defaultImpulsive [sentinelFireType $ const shootTillEmpty] - , _crActionPlan = ActionPlan + { _crActionPlan = ActionPlan { _apImpulse = [] , _apAction = [] , _apStrategy = StrategyActions WatchAndWait [StartSentinelPost] @@ -88,34 +76,16 @@ longCrit = defaultCreature , _crRad = 10 , _crHP = 150 } + & crType . humanoidAI .~ LongAI & crType . skinUpper .~ light4 red multGunCrit :: Creature multGunCrit = defaultCreature { _crInv = IM.fromList [(0,volleyGun 4),(1,medkit 100)] , _crRad = 10 , _crHP = 300 - , _crUpdate = defaultImpulsive [sentinelExtraWatchUpdate - [ ( const $ not . crWeaponReady - , \_ _ -> StrategyActions Reload reloadActions - ) - , (const $ not . crSafeDistFromTarg 150 - , \_ cr -> StrategyActions Flee - [const (not . crSafeDistFromTarg 150) `DoActionWhile` UseTarget (fleeFrom cr) - `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ] - ) - , (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) - [ drawwp `DoActionThen` shootFirstMiss `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ] - ) - ] - ] } & crType . skinUpper .~ light4 red - where - drawwp = DoActionIfElse NoAction (const crIsAiming) (DoActionThen drawWeapon (WaitThen 50 NoAction)) - reloadActions = - [ holsterWeapon - , WaitThen 1 $ DoActionWhileInterrupt NoAction (const crIsReloading) (DoImpulses [ChangeStrategy WatchAndWait]) - ] + & crType . humanoidAI .~ MultGunAI addArmour :: Creature -> Creature addArmour = over crInv insarmour @@ -130,7 +100,6 @@ startCr = defaultCreature , _crDir = pi/2 , _crMvDir = pi/2 , _crID = 0 - , _crUpdate = stateUpdate yourControl , _crRad = 10 , _crMass = 10 , _crHP = 1000 diff --git a/src/Dodge/Creature/ArmourChase.hs b/src/Dodge/Creature/ArmourChase.hs index 3af192452..c2804e722 100644 --- a/src/Dodge/Creature/ArmourChase.hs +++ b/src/Dodge/Creature/ArmourChase.hs @@ -4,36 +4,16 @@ module Dodge.Creature.ArmourChase ) where import Dodge.Data import Dodge.Default ---import Dodge.Creature.State -import Dodge.Creature.Update import Dodge.Creature.ChaseCrit ---import Dodge.Creature.ChainUpdates -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception ---import Dodge.Creature.Impulse -import Dodge.Creature.Action import Dodge.Item.Equipment import Dodge.Item.Consumable ---import Picture import qualified Data.IntMap.Strict as IM import Control.Lens flockArmourChaseCrit :: Creature flockArmourChaseCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ watchUpdateStrat [] - , const doStrategyActions - , performActions - , targetYouWhenCognizant - , setTargetMv (\_ -> _targetCr . _crIntention) - , flockACC - , perceptionUpdate [0] - , goToTarget - , const overrideMeleeCloseTarget - , const (crMeleeCooldown %~ max 0 . subtract 1) - ] - , _crName = "armourChaseCrit" + { _crName = "armourChaseCrit" , _crHP = 300 , _crInv = IM.fromList [(0,frontArmour) @@ -49,6 +29,7 @@ flockArmourChaseCrit = defaultCreature , _crGroup = ShieldGroup , _crMvType = defaultChaseMvType } + & crType . humanoidAI .~ FlockArmourChaseAI armourChaseCrit :: Creature armourChaseCrit = chaseCrit { _crName = "armourChaseCrit" diff --git a/src/Dodge/Creature/AutoCrit.hs b/src/Dodge/Creature/AutoCrit.hs index 05e5cf9c9..8c69e4025 100644 --- a/src/Dodge/Creature/AutoCrit.hs +++ b/src/Dodge/Creature/AutoCrit.hs @@ -3,28 +3,19 @@ module Dodge.Creature.AutoCrit ) where import Dodge.Data import Dodge.Default -import Dodge.Creature.Update -import Dodge.Creature.SentinelAI ---import Dodge.Creature.ChooseTarget ---import Dodge.Creature.Impulse ---import Dodge.Creature.State ---import Dodge.Creature.State.Data import Dodge.Item.Weapon.BulletGuns import Dodge.Item.Consumable ---import Geometry import Picture ---import Dodge.RandomHelp --- ---import Data.Maybe + import qualified Data.IntMap.Strict as IM import Control.Lens autoCrit :: Creature autoCrit = defaultCreature - { _crUpdate = defaultImpulsive [sentinelAI] - , _crInv = IM.fromList [(0,autoGun),(1,medkit 100)] + { _crInv = IM.fromList [(0,autoGun),(1,medkit 100)] , _crRad = 10 , _crHP = 300 , _crMvType = defaultAimMvType } & crType . skinUpper .~ light4 red + & crType . humanoidAI .~ AutoAI diff --git a/src/Dodge/Creature/ChaseCrit.hs b/src/Dodge/Creature/ChaseCrit.hs index 6e48c105d..8ebc07e84 100644 --- a/src/Dodge/Creature/ChaseCrit.hs +++ b/src/Dodge/Creature/ChaseCrit.hs @@ -6,18 +6,11 @@ module Dodge.Creature.ChaseCrit import Dodge.Data import Dodge.Default import Dodge.Creature.Picture -import Dodge.Creature.Update -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Action -import Dodge.Creature.Perception import Dodge.Item.Consumable import Dodge.Item.Equipment import Dodge.SoundLogic ---import Geometry import Picture ---import Dodge.RandomHelp ---import Data.Maybe import qualified Data.IntMap.Strict as IM import Control.Lens --import System.Random @@ -37,19 +30,7 @@ invisibleChaseCrit = chaseCrit & crInvEquipped . at 0 ?~ OnLeftWrist chaseCrit :: Creature chaseCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ const doStrategyActions - , performActions - , const overrideMeleeCloseTarget - , const setViewPos - , setMvPos - , chaseCritMv - , chaseCritPerceptionUpdate [0] - , targetYouWhenCognizant - , const searchIfDamaged - , const (crMeleeCooldown %~ max 0 . subtract 1) - ] - , _crName = "chaseCrit" + { _crName = "chaseCrit" , _crHP = 150 , _crInv = IM.fromList [(0,medkit 200)] , _crMeleeCooldown = 0 @@ -66,3 +47,4 @@ chaseCrit = defaultCreature ] 50 0 , _crMvType = defaultChaseMvType } + & crType . humanoidAI .~ ChaseAI diff --git a/src/Dodge/Creature/Inanimate.hs b/src/Dodge/Creature/Inanimate.hs index fed435bce..66549dc16 100644 --- a/src/Dodge/Creature/Inanimate.hs +++ b/src/Dodge/Creature/Inanimate.hs @@ -9,23 +9,14 @@ module Dodge.Creature.Inanimate ) where import Dodge.Data import Dodge.Creature.Lamp -import Dodge.WorldEvent.Explosion -import Dodge.Spark import Dodge.Default -import Dodge.Creature.State import qualified IntMapHelp as IM -import Geometry -import Dodge.SoundLogic import LensHelp -import System.Random -import Data.List - barrel :: Creature barrel = defaultInanimate - { _crUpdate = updateBarrel - , _crHP = 500 - , _crType = Barreloid + { _crHP = 500 + , _crType = Barreloid PlainBarrel , _crState = defaultState {_csSpState = Barrel [] } @@ -34,57 +25,11 @@ barrel = defaultInanimate explosiveBarrel :: Creature explosiveBarrel = defaultInanimate - { _crUpdate = updateExpBarrel - , _crHP = 400 - , _crType = Barreloid + { _crHP = 400 + , _crType = Barreloid ExplosiveBarrel , _crState = defaultState {_csSpState = Barrel [] } , _crInv = IM.empty -- IM.fromList [(0,frontArmour)] } & crMaterial .~ Crystal -updateBarrel :: Creature -> World -> World -updateBarrel cr - | _crHP cr > 0 = doDamage cr - | otherwise = creatures . at (_crID cr) .~ Nothing - --- should generate the sparks externally using new random generators -updateExpBarrel :: Creature -> World -> World -updateExpBarrel cr w - | _crHP cr > 0 = foldr ($) (hiss w & creatures . at (_crID cr) .~ newCr) pierceSparks - | otherwise = makeExplosionAt (_crPos cr) $ stopSounds w & creatures . at (_crID cr) .~ Nothing - where - g = _randGen w - damages = _csDamage $ _crState cr - pierceSparks :: [World -> World] - pierceSparks - = zipWith3 (\p a -> createBarrelSpark (_crPos cr +.+ p) (a + argV p)) - poss as colids - as = randomRs (-0.7,0.7) g - colids = randomRs (0,11) g - poss = _piercedPoints $ _csSpState $ _crState cr - newCr = Just $ applyFuseDamage $ set (crState . csDamage) [] $ damToExpBarrel damages cr - applyFuseDamage cr' = cr' & crHP %~ - subtract (length . _piercedPoints . _csSpState $ _crState cr') - hiss | null poss = id - | otherwise = soundMultiFrom [BarrelHiss 0,BarrelHiss 1] (_crPos cr) foamSprayLoopS (Just 1) - stopSounds = stopSoundFrom (BarrelHiss 0) . stopSoundFrom (BarrelHiss 1) - -damToExpBarrel :: [Damage] -> Creature -> Creature -damToExpBarrel ds cr = foldr damToExpBarrel' (foldr damToExpBarrel' cr pierceDam) otherDam - where - (pierceDam,otherDam) = partition isPierce ds - isPierce Damage{_dmType = PIERCING{}} = True - isPierce _ = False - -damToExpBarrel' :: Damage -> Creature -> Creature -damToExpBarrel' dm cr = case _dmType dm of - PIERCING -> over (crState . csSpState . piercedPoints) ((:) $ int -.- _crPos cr) - $ cr & crHP -~ div amount 200 - POISONDAM -> cr - SPARKING -> cr --- PUSHDAM -> cr LensHelp.& crPos .+.+~ (1 / _crMass cr *.* _dePushBack (_dmEffect dm)) - _ -> cr LensHelp.& crHP -~ amount - where - amount = _dmAmount dm - int = _dmAt dm diff --git a/src/Dodge/Creature/Lamp.hs b/src/Dodge/Creature/Lamp.hs index 862efd2a1..1c887e767 100644 --- a/src/Dodge/Creature/Lamp.hs +++ b/src/Dodge/Creature/Lamp.hs @@ -3,48 +3,17 @@ module Dodge.Creature.Lamp , colorLamp ) where import Dodge.Data -import Dodge.Material.Sound import Dodge.Default -import Dodge.LightSource -import Dodge.WorldEvent.Flash -import Dodge.WorldEvent.Sound -import Dodge.Creature.State -import Geometry -import qualified IntMapHelp as IM -import LensHelp - +import Geometry.Data colorLamp :: Point3 -- color of lamp -> Float -- height of lamp -> Creature colorLamp col h = defaultInanimate - { _crUpdate = initialiseColorLamp col h - , _crHP = 100 - , _crType = Lampoid h + { _crHP = 100 + , _crType = Lampoid h col Nothing , _crRad = 3 , _crMass = 3 } - lamp :: Float -> Creature lamp = colorLamp 0.75 - -initialiseColorLamp :: Point3 -> Float -> Creature -> World -> World -initialiseColorLamp col h cr w = w - & lightSources . at lsid ?~ lsColPosID col (addZ h $ _crPos cr) lsid - & creatures . ix (_crID cr) . crUpdate .~ updateLamp h lsid - where - lsid = IM.newKey $ _lightSources w - -updateLamp :: Float -> Int -> Creature -> World -> World -updateLamp h i cr w - | _crHP cr < 0 = w - & explosionFlashAt cpos - & originsIDsAt [MaterialSound Glass n | n <- [0,1,2]] (destroyMatS Glass) cpos - & lightSources . at i .~ Nothing - & creatures . at cid .~ Nothing - | otherwise = w - & lightSources . ix i . lsParam . lsPos .~ addZ h cpos - & doDamage cr - where - cpos = _crPos cr - cid = _crID cr diff --git a/src/Dodge/Creature/LauncherCrit.hs b/src/Dodge/Creature/LauncherCrit.hs index 27c7ef224..c4d35df44 100644 --- a/src/Dodge/Creature/LauncherCrit.hs +++ b/src/Dodge/Creature/LauncherCrit.hs @@ -4,18 +4,7 @@ module Dodge.Creature.LauncherCrit where import Dodge.Data import Dodge.Default ---import Dodge.Creature.ChainUpdates -import Dodge.Creature.Test -import Dodge.Creature.Volition -import Dodge.Creature.Strategy -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception ---import Dodge.Creature.State -import Dodge.Creature.Update import Dodge.Item.Weapon.Launcher ---import Dodge.Creature.Impulse -import Dodge.Creature.Action -import Geometry.Data import Picture import qualified Data.IntMap.Strict as IM @@ -23,53 +12,13 @@ import Control.Lens launcherCrit :: Creature launcherCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ performActions - , watchUpdateStrat - [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) [retreatFire]) - , (const crAwayFromPost, const goToPostStrat) - ] - , perceptionUpdate [0] - , const doStrategyActions - , const reloadOverride - , targetYouWhenCognizant - , const $ overrideInternal - (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr) - (crActionPlan . apStrategy .~ WatchAndWait) - ] - , _crInv = IM.fromList [(0,launcher)] + { _crInv = IM.fromList [(0,launcher)] , _crRad = 10 , _crState = defaultState , _crHP = 300 } & crType . skinUpper .~ light4 red + & crType . humanoidAI .~ LauncherAI -retreatFire :: Action -retreatFire = ImpulsesList ( [ UseItem ] : replicate 20 [ Turn 0.16 ]) - `DoActionThen` - holsterWeapon - `DoActionThen` - ImpulsesList ( replicate 30 [ MoveForward 3 ]) - `DoActionThen` - drawWeapon - `DoActionThen` - ImpulsesList ( [UseItem] : replicate 20 [ Turn $ negate 0.16 ] ) - `DoActionThen` - holsterWeapon - `DoActionThen` - ImpulsesList ( replicate 15 [ MoveForward 3 ] ) - `DoActionThen` - drawWeapon - `DoActionThen` - ImpulsesList ( - replicate 100 [UseItem, ImpulseUseTarget $ \tcr -> TurnToward (_crPos tcr) (pi/16) ] ) - `DoActionThen` - 20 - `WaitThen` - holsterWeapon - `DoActionThen` - ImpulsesList ( replicate 15 [ MoveForward 3 ] ) - `DoActionThen` - DoImpulses [ChangeStrategy WatchAndWait] diff --git a/src/Dodge/Creature/LtAutoCrit.hs b/src/Dodge/Creature/LtAutoCrit.hs index 3b8879727..36375ff47 100644 --- a/src/Dodge/Creature/LtAutoCrit.hs +++ b/src/Dodge/Creature/LtAutoCrit.hs @@ -3,17 +3,8 @@ module Dodge.Creature.LtAutoCrit ) where import Dodge.Data import Dodge.Default -import Dodge.Creature.Update -import Dodge.Creature.Action -import Dodge.Creature.Test -import Dodge.Creature.Volition -import Dodge.Creature.Strategy ---import Dodge.Creature.ChooseTarget -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception import Dodge.Item.Weapon.BulletGuns import Dodge.Item.Consumable -import Geometry import Picture import qualified Data.IntMap.Strict as IM @@ -21,43 +12,10 @@ import Control.Lens ltAutoCrit :: Creature ltAutoCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ performActions - , watchUpdateStrat - [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) - [DoActionIf (const $ not . crIsAiming) drawWeapon - ,DoActionThen - (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement) - (DoImpulses [ChangeStrategy WatchAndWait]) - ] - ) - , (const crAwayFromPost, const goToPostStrat) - ] - , perceptionUpdate [0] - , const doStrategyActions - , const reloadOverride - , targetYouWhenCognizant - , const $ overrideInternal - (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr) - (crActionPlan . apStrategy .~ WatchAndWait) - ] - , _crInv = IM.fromList [(0,autoPistol),(1,medkit 100)] + { _crInv = IM.fromList [(0,autoPistol),(1,medkit 100)] , _crRad = 10 , _crHP = 500 } + & crType . humanoidAI .~ LtAutoAI & crType . skinUpper .~ light4 red -chooseMovement :: Creature -> World -> Action -chooseMovement cr w - | dist cpos p > 200 = DoImpulses [UseItem,TurnToward p 0.05 , MoveForward 3] - | dist cpos p < 80 = DoImpulses [UseItem,TurnToward p 0.05, MoveForward (-3) ] - | errorAngleVV 22 (p' -.- cpos) (unitVectorAtAngle (_crDir cr)) < 0.4 - = DoImpulses [UseItem,TurnToward p' 0.01, Move (V2 0 3)] - | otherwise - = DoImpulses [UseItem,TurnToward p' 0.05, Move (V2 0 3)] - where - cpos = _crPos cr - tcr = _creatures w IM.! 0 - p = _crPos tcr - v = vNormal $ p -.- cpos - p' = p +.+ 0.5 *.* (v -.- 20 *.* normalizeV v) diff --git a/src/Dodge/Creature/PistolCrit.hs b/src/Dodge/Creature/PistolCrit.hs index 92ee09639..b28c7cc22 100644 --- a/src/Dodge/Creature/PistolCrit.hs +++ b/src/Dodge/Creature/PistolCrit.hs @@ -3,109 +3,21 @@ module Dodge.Creature.PistolCrit ) where import Dodge.Data import Dodge.Default -import Dodge.Creature.Update -import Dodge.Creature.Test -import Dodge.Creature.Action -import Dodge.Creature.Volition -import Dodge.Creature.Strategy -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception ---import Dodge.Creature.State.Data import Dodge.Item.Weapon.BulletGuns import Dodge.Item.Consumable -import Geometry import Picture -import RandomHelp -import Data.Maybe import qualified Data.IntMap.Strict as IM import Control.Lens pistolCrit :: Creature pistolCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ performActions - , watchUpdateStrat - [ (crHasTargetLOS, \w cr -> StrategyActions (ShootAt 0) - [DoActionIf (const $ not . crIsAiming) drawWeapon,chooseMovement cr w]) - , (const crAwayFromPost, const goToPostStrat) - ] - , perceptionUpdate [0] - , const doStrategyActions - , const reloadOverride - , targetYouWhenCognizant - , const $ overrideInternal - (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr) - (crActionPlan . apStrategy .~ WatchAndWait) - ] - , _crInv = IM.fromList [(0,pistol),(1,medkit 100)] + { _crInv = IM.fromList [(0,pistol),(1,medkit 100)] , _crRad = 10 , _crHP = 500 } + & crType . humanoidAI .~ PistolAI & crType . skinUpper .~ light4 red -chooseMovement :: Creature -> World -> Action -chooseMovement cr w = chooseMovement' cr w - `DoActionThen` - DoImpulses [ChangeStrategy WatchAndWait] -chooseMovement' :: Creature -> World -> Action -chooseMovement' cr w = takeOneWeighted [chargeProb,retreatProb,strafeProb,strafeProb] - [chargeActions - ,retreatActions ycr cr - ,strafeLeftActions - ,strafeRightActions - ] & evalState $ g - where - g = _randGen w - cpos = _crPos cr - ycr = _creatures w IM.! 0 - ypos = _crPos ycr - chargeProb | dist cpos ypos > 300 = 5 - | dist cpos ypos > 150 = 1 - | otherwise = 0 - strafeProb | dist cpos ypos > 150 = 1 - | otherwise = 0 - retreatProb | dist cpos ypos < 200 = 1 :: Float - | otherwise = 0 - chargeActions = - [TurnToward ypos 0.1] - `DoImpulsesAlongside` - 3 - `DoReplicate` - ImpulsesList (replicate 9 [Move (V2 3 0)] ++ [[Move (V2 3 0),UseItem]]) - strafeLeftActions = - DoImpulses [TurnToward yposr (2*pi)] - `DoActionThen` - 3 - `DoReplicate` - ImpulsesList (replicate 9 [Move (V2 0 3)] ++ [[Move (V2 0 3),UseItem]]) - strafeRightActions = - DoImpulses [TurnToward yposl (2*pi)] - `DoActionThen` - 3 - `DoReplicate` - ImpulsesList (replicate 9 [Move (V2 0 (-3))] ++ [[Move (V2 0 (-3)),UseItem]]) - yposl = ypos -.- 100 *.* vNormal (normalizeV $ ypos -.- cpos) - yposr = ypos +.+ 100 *.* vNormal (normalizeV $ ypos -.- cpos) - -retreatActions :: Creature -> Creature -> Action -retreatActions tcr cr = - [TurnToward retreatOffset 0.2] - `DoImpulsesAlongside` - 3 - `DoReplicate` - ImpulsesList (replicate 9 [Move (V2 (-3) 0)] ++ [[UseItem]]) - where - cpos = _crPos cr - tpos = _crPos tcr - retreatOffset = - let a | dist cpos tpos < 50 = 0 - | isLeftOfA (_crDir cr) (argV $ tpos -.- cpos) - = -0.7 - | otherwise = 0.7 - in fromMaybe tpos $ intersectLineLine' cpos - (cpos +.+ rotateV a (tpos -.- cpos)) - tpos - (tpos +.+ vNormal (cpos -.- tpos)) diff --git a/src/Dodge/Creature/SpreadGunCrit.hs b/src/Dodge/Creature/SpreadGunCrit.hs index b98f0e858..319019b58 100644 --- a/src/Dodge/Creature/SpreadGunCrit.hs +++ b/src/Dodge/Creature/SpreadGunCrit.hs @@ -3,64 +3,19 @@ module Dodge.Creature.SpreadGunCrit ) where import Dodge.Data import Dodge.Default -import Dodge.Creature.Update -import Dodge.Creature.Test -import Dodge.Creature.Action -import Dodge.Creature.Volition -import Dodge.Creature.Strategy -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception ---import Dodge.Creature.State.Data import Dodge.Item.Weapon.BulletGuns import Dodge.Item.Consumable -import Geometry import Picture ---import Dodge.RandomHelp ---import Data.Maybe import qualified Data.IntMap.Strict as IM import Control.Lens spreadGunCrit :: Creature spreadGunCrit = defaultCreature - { _crUpdate = defaultImpulsive - [performActions - ,watchUpdateStrat - [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) - [DoActionIf (const $ not . crIsAiming) drawWeapon - ,DoActionThen - (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovement) - (DoImpulses [ChangeStrategy WatchAndWait]) - ] - ) - , (const crAwayFromPost, const goToPostStrat) - ] - ,perceptionUpdate [0] - ,const doStrategyActions - ,const reloadOverride - ,targetYouWhenCognizant - ,const $ overrideInternal - (\cr -> crHasTarget cr && crStratConMatches (GetTo (V2 0 0)) cr) - (\ cr -> cr & crActionPlan . apStrategy .~ WatchAndWait) - ] - , _crInv = IM.fromList [(0,bangStick 6),(1,medkit 100)] + { _crInv = IM.fromList [(0,bangStick 6),(1,medkit 100)] , _crRad = 10 , _crHP = 500 } + & crType . humanoidAI .~ SpreadGunAI & crType . skinUpper .~ light4 red -chooseMovement :: Creature -> World -> Action -chooseMovement cr w - | dist cpos p < 30 && safeAngleVV (p -.- cpos) (unitVectorAtAngle (_crDir cr)) > pi - = DoImpulses [UseItem, MoveForward (-3)] - | d < 30 = DoImpulses [UseItem,TurnToward p 0.06] - | d < 60 = DoImpulses [UseItem,TurnToward p 0.06,MoveForward 3] - | d < 100 = DoImpulses [TurnToward p 0.06, MoveForward 3 ] - | d < 200 = DoImpulses [TurnToward p (0.06 + 0.002 *(d-100)), MoveForward 3 ] - | otherwise - = DoImpulses [TurnToward p 0.26, MoveForward 3] - where - d = dist cpos p - cpos = _crPos cr - tcr = _creatures w IM.! 0 - p = _crPos tcr diff --git a/src/Dodge/Creature/State.hs b/src/Dodge/Creature/State.hs index 4c582e062..25f7bddfd 100644 --- a/src/Dodge/Creature/State.hs +++ b/src/Dodge/Creature/State.hs @@ -62,8 +62,7 @@ checkDeath cr w & corpseOrGib cr where removecr - | _crID cr == 0 = (creatures . ix (_crID cr) . crUpdate .~ const id) - . (creatures . ix (_crID cr) . crType .~ NonDrawnCreature) + | _crID cr == 0 = (creatures . ix (_crID cr) . crType .~ NonDrawnCreature) . (creatures . ix (_crID cr) . crHP .~ 0) -- hack to get around player creature being killed but left with more than 0 hp | otherwise = creatures . at (_crID cr) .~ Nothing diff --git a/src/Dodge/Creature/SwarmCrit.hs b/src/Dodge/Creature/SwarmCrit.hs index dbacb9175..f3e9a518a 100644 --- a/src/Dodge/Creature/SwarmCrit.hs +++ b/src/Dodge/Creature/SwarmCrit.hs @@ -4,30 +4,13 @@ module Dodge.Creature.SwarmCrit import Dodge.Data import Dodge.Default import Dodge.Creature.Picture -import Dodge.Creature.Update ---import Dodge.Creature.ChainUpdates -import Dodge.Creature.Boid -import Dodge.Creature.ReaderUpdate -import Dodge.Creature.Perception ---import Dodge.Creature.Impulse ---import Dodge.Creature.State import Picture import Control.Lens swarmCrit :: Creature swarmCrit = defaultCreature - { _crUpdate = defaultImpulsive - [ flockToPointUsing' (encircleDistP 100) (meleeHeadingMove 0.1 0.1 (pi/4) 3.9) - , const (crMeleeCooldown %~ max 0 . subtract 1) - , perceptionUpdate [0] - , const doStrategyActions - , targetYouWhenCognizant - ] --- , doStrategyActions --- , targetYouWhenCognizant - - , _crHP = 1 + { _crHP = 1 , _crRad = 2 , _crMass = 2 , _crCorpse = basicCrCorpse @@ -35,6 +18,7 @@ swarmCrit = defaultCreature , _crMeleeCooldown = 0 } & crType . skinUpper .~ light4 yellow + & crType . humanoidAI .~ SwarmAI --swarmCritMoveFunc :: Creature -> Point2 -> Creature -> Point2 --swarmCritMoveFunc tcr cenp cr diff --git a/src/Dodge/Creature/Update.hs b/src/Dodge/Creature/Update.hs index bf8b89159..2f4314e19 100644 --- a/src/Dodge/Creature/Update.hs +++ b/src/Dodge/Creature/Update.hs @@ -3,10 +3,23 @@ import Dodge.Data import Dodge.Creature.State import Dodge.Creature.Impulse import Dodge.Creature.ChainUpdates +import Dodge.Lampoid +import Dodge.Humanoid +import Dodge.Turretoid +import Dodge.Barreloid import LensHelp import System.Random +updateCreature :: Creature -> World -> World +updateCreature cr = case _crType cr of + Lampoid{} -> updateLampoid cr + Humanoid{} -> updateHumanoid cr + Turretoid{} -> updateTurretoid cr + Barreloid{} -> updateBarreloid cr + NonDrawnCreature -> id + + -- bit of a hack to get new random generators after each creature's update defaultImpulsive :: [World -> Creature -> Creature] -> Creature -> World -> World diff --git a/src/Dodge/Data.hs b/src/Dodge/Data.hs index 6f605ee60..eb0e9c16b 100644 --- a/src/Dodge/Data.hs +++ b/src/Dodge/Data.hs @@ -10,6 +10,7 @@ circular imports are probably not a good idea. {-# LANGUAGE DerivingStrategies #-} module Dodge.Data ( module Dodge.Data + , module Dodge.Data.Payload , module Dodge.Data.RadarSweep , module Dodge.Data.PosEvent , module Dodge.Data.EnergyBall @@ -53,6 +54,7 @@ module Dodge.Data , module Dodge.Data.RadarBlip , module Dodge.Data.PathGraph ) where +import Dodge.Data.Payload import Dodge.Data.RadarSweep import Dodge.Data.PosEvent import Dodge.Data.EnergyBall @@ -306,15 +308,6 @@ data Gust = Gust , _guVel :: Point2 , _guTime :: Int } -data CreatureType - = Humanoid - { _skinHead :: Color - , _skinUpper :: Color - , _skinLower :: Color - } - | Barreloid - | Lampoid {_lampHeight :: Float} - | NonDrawnCreature data Creature = Creature { _crPos :: Point2 , _crOldPos :: Point2 @@ -325,7 +318,6 @@ data Creature = Creature , _crTwist :: Float , _crType :: CreatureType , _crID :: Int - , _crUpdate :: Creature -> World -> World , _crRad :: Float , _crMass :: Float , _crHP :: Int @@ -1344,7 +1336,6 @@ makeLenses ''EquipParams makeLenses ''TerminalCommand makeLenses ''TerminalInput makeLenses ''GenParams -makeLenses ''CreatureType makeLenses ''Corpse ----- ROOM LENSES diff --git a/src/Dodge/Data/Ammo.hs b/src/Dodge/Data/Ammo.hs new file mode 100644 index 000000000..b54b66ceb --- /dev/null +++ b/src/Dodge/Data/Ammo.hs @@ -0,0 +1,4 @@ +--{-# LANGUAGE TemplateHaskell #-} +--{-# LANGUAGE StrictData #-} +module Dodge.Data.Ammo where + diff --git a/src/Dodge/Data/Creature.hs b/src/Dodge/Data/Creature.hs index 8e8e33b32..56f0978a5 100644 --- a/src/Dodge/Data/Creature.hs +++ b/src/Dodge/Data/Creature.hs @@ -2,6 +2,8 @@ {-# LANGUAGE StrictData #-} module Dodge.Data.Creature where import Sound.Data +import Geometry.Data +import Color import Control.Lens data CamouflageStatus = FullyVisible @@ -31,6 +33,22 @@ data CrMvType , _mvTurnJit :: Float , _mvAimSpeed :: Float -> Float } +data HumanoidAI = YourAI | ChaseAI | InanimateAI | SpreadGunAI | PistolAI + | LtAutoAI | LauncherAI | SwarmAI | AutoAI | FlockArmourChaseAI | MiniGunAI + | LongAI | MultGunAI +data CreatureType + = Humanoid + { _skinHead :: Color + , _skinUpper :: Color + , _skinLower :: Color + , _humanoidAI :: HumanoidAI + } + | Barreloid {_barrelType :: BarrelType} + | Lampoid {_lampHeight :: Float, _lampColor :: Point3, _lampLSID :: Maybe Int} + | Turretoid + | NonDrawnCreature +data BarrelType = PlainBarrel | ExplosiveBarrel makeLenses ''CreatureStatistics makeLenses ''Vocalization makeLenses ''CrMvType +makeLenses ''CreatureType diff --git a/src/Dodge/Data/Payload.hs b/src/Dodge/Data/Payload.hs new file mode 100644 index 000000000..b58905f3f --- /dev/null +++ b/src/Dodge/Data/Payload.hs @@ -0,0 +1,4 @@ +--{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE StrictData #-} +module Dodge.Data.Payload where +data Payload = ExplosionPayload | DudPayload diff --git a/src/Dodge/Data/Projectile.hs b/src/Dodge/Data/Projectile.hs new file mode 100644 index 000000000..858bbbb89 --- /dev/null +++ b/src/Dodge/Data/Projectile.hs @@ -0,0 +1,8 @@ +--{-# LANGUAGE TemplateHaskell #-} +--{-# LANGUAGE StrictData #-} +module Dodge.Data.Projectile where +--import Dodge.Data.Ammo +--import Geometry.Data +--import Control.Lens + +data ProjectileType = ShellType diff --git a/src/Dodge/Data/TeslaArc.hs b/src/Dodge/Data/TeslaArc.hs new file mode 100644 index 000000000..7c40f8a52 --- /dev/null +++ b/src/Dodge/Data/TeslaArc.hs @@ -0,0 +1,12 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE StrictData #-} +module Dodge.Data.TeslaArc where +import Geometry.Data +import Color +import Control.Lens +data TeslaArc = TeslaArc + { _taPoints :: [Point2] + , _taTimer :: Int + , _taColor :: Color + } +makeLenses ''TeslaArc diff --git a/src/Dodge/Default/Creature.hs b/src/Dodge/Default/Creature.hs index 1637dab42..fc5ceb7bf 100644 --- a/src/Dodge/Default/Creature.hs +++ b/src/Dodge/Default/Creature.hs @@ -19,7 +19,6 @@ defaultCreature = Creature , _crTwist = 0 , _crID = 1 , _crType = defaultCreatureSkin - , _crUpdate = const id , _crRad = 10 , _crMass = 10 , _crHP = 100 @@ -55,7 +54,7 @@ defaultCreature = Creature , _crCamouflage = FullyVisible } defaultCreatureSkin :: CreatureType -defaultCreatureSkin = Humanoid (greyN 0.9) (light4 green) (greyN 0.3) +defaultCreatureSkin = Humanoid (greyN 0.9) (light4 green) (greyN 0.3) InanimateAI defaultInanimate :: Creature defaultInanimate = defaultCreature & crActionPlan .~ Inanimate diff --git a/src/Dodge/Humanoid.hs b/src/Dodge/Humanoid.hs new file mode 100644 index 000000000..2e264d0be --- /dev/null +++ b/src/Dodge/Humanoid.hs @@ -0,0 +1,279 @@ +module Dodge.Humanoid where +import Dodge.Data +import Dodge.Creature.Boid +import Dodge.Creature.YourControl +import Dodge.Creature.State +import Dodge.Creature.Impulse +import Dodge.Creature.ChainUpdates +import Dodge.Creature.Test +import Dodge.Creature.Volition +import LensHelp +import Dodge.Creature.ReaderUpdate +import Dodge.Creature.Action +import Dodge.Creature.Perception +import Dodge.Creature.Strategy +import Dodge.Creature.SentinelAI +import qualified IntMapHelp as IM +import Geometry +import RandomHelp + +import Data.Maybe + +updateHumanoid :: Creature -> World -> World +updateHumanoid cr = case cr ^?! crType . humanoidAI of + ChaseAI -> defaultImpulsive + [ const doStrategyActions + , performActions + , const overrideMeleeCloseTarget + , const setViewPos + , setMvPos + , chaseCritMv + , chaseCritPerceptionUpdate [0] + , targetYouWhenCognizant + , const searchIfDamaged + , const (crMeleeCooldown %~ max 0 . subtract 1) + ] cr + SpreadGunAI -> defaultImpulsive + [performActions + ,watchUpdateStrat + [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) + [DoActionIf (const $ not . crIsAiming) drawWeapon + ,DoActionThen + (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovementSpreadGun) + (DoImpulses [ChangeStrategy WatchAndWait]) + ] + ) + , (const crAwayFromPost, const goToPostStrat) + ] + ,perceptionUpdate [0] + ,const doStrategyActions + ,const reloadOverride + ,targetYouWhenCognizant + ,const $ overrideInternal + (\cr' -> crHasTarget cr' && crStratConMatches (GetTo (V2 0 0)) cr') + (\cr' -> cr' & crActionPlan . apStrategy .~ WatchAndWait) + ] cr + PistolAI -> defaultImpulsive + [ performActions + , watchUpdateStrat + [ (crHasTargetLOS, \w cr' -> StrategyActions (ShootAt 0) + [DoActionIf (const $ not . crIsAiming) drawWeapon,chooseMovementPistol cr' w]) + , (const crAwayFromPost, const goToPostStrat) + ] + , perceptionUpdate [0] + , const doStrategyActions + , const reloadOverride + , targetYouWhenCognizant + , const $ overrideInternal + (\cr' -> crHasTarget cr' && crStratConMatches (GetTo (V2 0 0)) cr') + (crActionPlan . apStrategy .~ WatchAndWait) + ] cr + LtAutoAI -> defaultImpulsive + [ performActions + , watchUpdateStrat + [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) + [DoActionIf (const $ not . crIsAiming) drawWeapon + ,DoActionThen + (DoActionWhile crHasTargetLOS $ ArbitraryAction chooseMovementLtAuto) + (DoImpulses [ChangeStrategy WatchAndWait]) + ] + ) + , (const crAwayFromPost, const goToPostStrat) + ] + , perceptionUpdate [0] + , const doStrategyActions + , const reloadOverride + , targetYouWhenCognizant + , const $ overrideInternal + (\cr' -> crHasTarget cr' && crStratConMatches (GetTo (V2 0 0)) cr') + (crActionPlan . apStrategy .~ WatchAndWait) + ] cr + LauncherAI -> defaultImpulsive + [ performActions + , watchUpdateStrat + [ (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) [retreatFireLauncher]) + , (const crAwayFromPost, const goToPostStrat) + ] + , perceptionUpdate [0] + , const doStrategyActions + , const reloadOverride + , targetYouWhenCognizant + , const $ overrideInternal + (\cr' -> crHasTarget cr' && crStratConMatches (GetTo (V2 0 0)) cr') + (crActionPlan . apStrategy .~ WatchAndWait) + ] cr + SwarmAI -> defaultImpulsive + [ flockToPointUsing' (encircleDistP 100) (meleeHeadingMove 0.1 0.1 (pi/4) 3.9) + , const (crMeleeCooldown %~ max 0 . subtract 1) + , perceptionUpdate [0] + , const doStrategyActions + , targetYouWhenCognizant + ] cr + AutoAI -> defaultImpulsive [sentinelAI] cr + FlockArmourChaseAI -> defaultImpulsive + [ watchUpdateStrat [] + , const doStrategyActions + , performActions + , targetYouWhenCognizant + , setTargetMv (\_ -> _targetCr . _crIntention) + , flockACC + , perceptionUpdate [0] + , goToTarget + , const overrideMeleeCloseTarget + , const (crMeleeCooldown %~ max 0 . subtract 1) + ] cr + MiniGunAI -> defaultImpulsive [sentinelFireType (const shootTillEmpty)] cr + LongAI -> defaultImpulsive [sentinelFireType $ const shootTillEmpty] cr + MultGunAI -> defaultImpulsive [sentinelExtraWatchUpdate + [ ( const $ not . crWeaponReady + , \_ _ -> StrategyActions Reload reloadActions + ) + , (const $ not . crSafeDistFromTarg 150 + , \_ cr' -> StrategyActions Flee + [const (not . crSafeDistFromTarg 150) `DoActionWhile` UseTarget (fleeFrom cr') + `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ] + ) + , (crHasTargetLOS, \_ _ -> StrategyActions (ShootAt 0) + [ drawwp `DoActionThen` shootFirstMiss `DoActionThen` DoImpulses [ChangeStrategy WatchAndWait] ] + ) + ] + ] cr + YourAI -> stateUpdate yourControl cr + InanimateAI -> id + where + drawwp = DoActionIfElse NoAction (const crIsAiming) (DoActionThen drawWeapon (WaitThen 50 NoAction)) + reloadActions = + [ holsterWeapon + , WaitThen 1 $ DoActionWhileInterrupt NoAction (const crIsReloading) (DoImpulses [ChangeStrategy WatchAndWait]) + ] +-- bit of a hack to get new random generators after each creature's update +defaultImpulsive :: [World -> Creature -> Creature] + -> Creature -> World -> World +defaultImpulsive = fmap (fmap updateRandGen) . stateUpdate . impulsiveAIBefore . chainCreatureUpdates + where + updateRandGen w = let (_,g) = randomR (0,1::Int) (_randGen w) + in w & randGen .~ g + +chooseMovementSpreadGun :: Creature -> World -> Action +chooseMovementSpreadGun cr w + | dist cpos p < 30 && safeAngleVV (p -.- cpos) (unitVectorAtAngle (_crDir cr)) > pi + = DoImpulses [UseItem, MoveForward (-3)] + | d < 30 = DoImpulses [UseItem,TurnToward p 0.06] + | d < 60 = DoImpulses [UseItem,TurnToward p 0.06,MoveForward 3] + | d < 100 = DoImpulses [TurnToward p 0.06, MoveForward 3 ] + | d < 200 = DoImpulses [TurnToward p (0.06 + 0.002 *(d-100)), MoveForward 3 ] + | otherwise + = DoImpulses [TurnToward p 0.26, MoveForward 3] + where + d = dist cpos p + cpos = _crPos cr + tcr = _creatures w IM.! 0 + p = _crPos tcr + +chooseMovementPistol :: Creature -> World -> Action +chooseMovementPistol cr w = chooseMovementPistol' cr w + `DoActionThen` + DoImpulses [ChangeStrategy WatchAndWait] + +chooseMovementPistol' :: Creature -> World -> Action +chooseMovementPistol' cr w = takeOneWeighted [chargeProb,retreatProb,strafeProb,strafeProb] + [chargeActions + ,retreatActionsPistol ycr cr + ,strafeLeftActions + ,strafeRightActions + ] & evalState $ g + where + g = _randGen w + cpos = _crPos cr + ycr = _creatures w IM.! 0 + ypos = _crPos ycr + chargeProb | dist cpos ypos > 300 = 5 + | dist cpos ypos > 150 = 1 + | otherwise = 0 + strafeProb | dist cpos ypos > 150 = 1 + | otherwise = 0 + retreatProb | dist cpos ypos < 200 = 1 :: Float + | otherwise = 0 + chargeActions = + [TurnToward ypos 0.1] + `DoImpulsesAlongside` + 3 + `DoReplicate` + ImpulsesList (replicate 9 [Move (V2 3 0)] ++ [[Move (V2 3 0),UseItem]]) + strafeLeftActions = + DoImpulses [TurnToward yposr (2*pi)] + `DoActionThen` + 3 + `DoReplicate` + ImpulsesList (replicate 9 [Move (V2 0 3)] ++ [[Move (V2 0 3),UseItem]]) + strafeRightActions = + DoImpulses [TurnToward yposl (2*pi)] + `DoActionThen` + 3 + `DoReplicate` + ImpulsesList (replicate 9 [Move (V2 0 (-3))] ++ [[Move (V2 0 (-3)),UseItem]]) + yposl = ypos -.- 100 *.* vNormal (normalizeV $ ypos -.- cpos) + yposr = ypos +.+ 100 *.* vNormal (normalizeV $ ypos -.- cpos) + +retreatActionsPistol :: Creature -> Creature -> Action +retreatActionsPistol tcr cr = + [TurnToward retreatOffset 0.2] + `DoImpulsesAlongside` + 3 + `DoReplicate` + ImpulsesList (replicate 9 [Move (V2 (-3) 0)] ++ [[UseItem]]) + where + cpos = _crPos cr + tpos = _crPos tcr + retreatOffset = + let a | dist cpos tpos < 50 = 0 + | isLeftOfA (_crDir cr) (argV $ tpos -.- cpos) + = -0.7 + | otherwise = 0.7 + in fromMaybe tpos $ intersectLineLine' cpos + (cpos +.+ rotateV a (tpos -.- cpos)) + tpos + (tpos +.+ vNormal (cpos -.- tpos)) + +chooseMovementLtAuto :: Creature -> World -> Action +chooseMovementLtAuto cr w + | dist cpos p > 200 = DoImpulses [UseItem,TurnToward p 0.05 , MoveForward 3] + | dist cpos p < 80 = DoImpulses [UseItem,TurnToward p 0.05, MoveForward (-3) ] + | errorAngleVV 22 (p' -.- cpos) (unitVectorAtAngle (_crDir cr)) < 0.4 + = DoImpulses [UseItem,TurnToward p' 0.01, Move (V2 0 3)] + | otherwise + = DoImpulses [UseItem,TurnToward p' 0.05, Move (V2 0 3)] + where + cpos = _crPos cr + tcr = _creatures w IM.! 0 + p = _crPos tcr + v = vNormal $ p -.- cpos + p' = p +.+ 0.5 *.* (v -.- 20 *.* normalizeV v) + +retreatFireLauncher :: Action +retreatFireLauncher = ImpulsesList ( [ UseItem ] : replicate 20 [ Turn 0.16 ]) + `DoActionThen` + holsterWeapon + `DoActionThen` + ImpulsesList ( replicate 30 [ MoveForward 3 ]) + `DoActionThen` + drawWeapon + `DoActionThen` + ImpulsesList ( [UseItem] : replicate 20 [ Turn $ negate 0.16 ] ) + `DoActionThen` + holsterWeapon + `DoActionThen` + ImpulsesList ( replicate 15 [ MoveForward 3 ] ) + `DoActionThen` + drawWeapon + `DoActionThen` + ImpulsesList ( + replicate 100 [UseItem, ImpulseUseTarget $ \tcr -> TurnToward (_crPos tcr) (pi/16) ] ) + `DoActionThen` + 20 + `WaitThen` + holsterWeapon + `DoActionThen` + ImpulsesList ( replicate 15 [ MoveForward 3 ] ) + `DoActionThen` + DoImpulses [ChangeStrategy WatchAndWait] diff --git a/src/Dodge/Lampoid.hs b/src/Dodge/Lampoid.hs new file mode 100644 index 000000000..bc941a5f6 --- /dev/null +++ b/src/Dodge/Lampoid.hs @@ -0,0 +1,29 @@ +module Dodge.Lampoid where +import Dodge.Data +import Dodge.Material.Sound +import Dodge.WorldEvent.Flash +import Dodge.WorldEvent.Sound +import Dodge.Creature.State +import Dodge.LightSource +import Geometry +import LensHelp +import qualified IntMapHelp as IM +updateLampoid :: Creature -> World -> World +updateLampoid cr w = case cr ^?! crType . lampLSID of + Nothing -> let i = IM.newKey (_lightSources w) + in w & lightSources . at i ?~ lsColPosID lcol (addZ h cpos) i + Just i + | _crHP cr < 0 -> w + & explosionFlashAt cpos + & originsIDsAt [MaterialSound Glass n | n <- [0,1,2]] (destroyMatS Glass) cpos + & lightSources . at i .~ Nothing + & creatures . at cid .~ Nothing + | otherwise -> w + & lightSources . ix i . lsParam . lsPos .~ addZ h cpos + & doDamage cr + where + cpos = _crPos cr + cid = _crID cr + crtype = _crType cr + h = _lampHeight crtype + lcol = _lampColor crtype diff --git a/src/Dodge/Machine/Update.hs b/src/Dodge/Machine/Update.hs index d82aaebec..008b914ac 100644 --- a/src/Dodge/Machine/Update.hs +++ b/src/Dodge/Machine/Update.hs @@ -9,8 +9,6 @@ import Dodge.WorldEvent.Explosion import Dodge.FloorItem import Dodge.Item.Weapon.BatteryGuns import Dodge.Default -import Dodge.Creature.State -import Dodge.Creature.Impulse import Dodge.Movement.Turn import Geometry import LensHelp @@ -64,7 +62,6 @@ updateTurret rotSpeed mc w & crOldPos .~ mcpos & crRad .~ 1 & crDir .~ mcdir - & crUpdate .~ stateUpdate followThenClearImpulses & crStance . posture .~ Aiming & crMaterial .~ Crystal Just cid -> w' diff --git a/src/Dodge/Payload.hs b/src/Dodge/Payload.hs new file mode 100644 index 000000000..d79478f80 --- /dev/null +++ b/src/Dodge/Payload.hs @@ -0,0 +1,9 @@ +module Dodge.Payload where +import Geometry.Data +import Dodge.Data +import Dodge.WorldEvent.Explosion + +usePayload :: Payload -> Point2 -> World -> World +usePayload payload = case payload of + ExplosionPayload -> makeExplosionAt + DudPayload -> const id diff --git a/src/Dodge/Placement/Instance/Turret.hs b/src/Dodge/Placement/Instance/Turret.hs index d81ce0b09..fe7118f40 100644 --- a/src/Dodge/Placement/Instance/Turret.hs +++ b/src/Dodge/Placement/Instance/Turret.hs @@ -1,20 +1,13 @@ module Dodge.Placement.Instance.Turret where import Color import Dodge.Data -import Dodge.Creature.State -import Dodge.Creature.Impulse import Dodge.LevelGen.Data import Dodge.Default import Dodge.Movement.Turn ---import Dodge.Creature.Impulse.UseItem import Dodge.FloorItem import Dodge.Wall.Delete import Dodge.WorldEvent.Explosion import Dodge.Item.Weapon.BatteryGuns ---import Dodge.Item.Weapon.BulletGun.Cane ---import Dodge.SoundLogic.LoadSound ---import Dodge.SoundLogic ---import Dodge.Item.Draw import Geometry import ShapePicture import Shape @@ -74,7 +67,6 @@ updateTurret rotSpeed mc w & crOldPos .~ mcpos & crRad .~ 1 & crDir .~ mcdir - & crUpdate .~ stateUpdate followThenClearImpulses & crStance . posture .~ Aiming & crMaterial .~ Crystal Just cid -> w' diff --git a/src/Dodge/Projectile.hs b/src/Dodge/Projectile.hs new file mode 100644 index 000000000..cfeb0284e --- /dev/null +++ b/src/Dodge/Projectile.hs @@ -0,0 +1,68 @@ +module Dodge.Projectile where + +--createProjectile :: ProjectileType -> Item -> Creature -> World -> World +--createProjectile pt = case pt of +-- ShellType -> fireShell +-- +--fireShell :: Item -> Creature -> World -> World +--fireShell it cr = makeShell it cr $ \pj -> pjEffAtTime 35 (trySpinByCID (_crID cr) spinamount) pj +-- . pjThrust thrustdelay pj +-- . reduceSpinBy (1-fromIntegral spindrag*2 / 200) pj +-- . decTimMvVel pj +-- . moveShell pj +-- where +-- params = _itParams it +-- spindrag = _shellSpinDrag params +-- spinamount = _shellSpinAmount params +-- thrustdelay = _shellThrustDelay params +-- +--makeShell :: Item -> Creature -> (Projectile -> World -> World) -> World -> World +--makeShell it cr theupdate w = w & props %~ IM.insert i Shell +-- { _prPos = pos +-- , _pjZ = 20 +-- , _pjStartPos = pos +-- , _pjVel = rotateV dir (V2 1 0) +-- , _pjID = i +-- , _pjUpdate = theupdate +-- , _pjAcc = rotateV dir (V2 3 0) +-- , _pjDir = dir +-- , _pjSpin = 0 +-- , _pjPayload = _amPayload $ _laAmmoType am +-- , _pjTimer = 50 +-- } +-- where +-- i = IM.newKey $ _props w +-- dir = _crDir cr +-- pos = _crPos cr +.+ rotateV dir (V2 (_crRad cr + 1) 0) +-- am = _itConsumption it +-- +--moveShell :: Prop -- ^ Projectile id +-- -> World +-- -> World +--moveShell pj w +-- | time > 40 = if circOnSomeWall oldPos 4 w +-- then doExplode +-- else w +-- | anythingHitCirc 2 oldPos newPos w = doExplode +-- | time > -300 = w +-- | otherwise = doExplode +-- where +-- time = _pjTimer pj +-- doExplode = w +-- & usePayload (_pjPayload pj) oldPos +-- & stopSoundFrom (ShellSound i) +-- & props %~ IM.delete i +-- i = _pjID pj +-- oldPos = _prPos pj +-- vel = _pjVel pj +-- newPos = oldPos +.+ vel +-- +--usePjCreation :: Item -> Creature -> World -> World +--usePjCreation it = createProjectile (_amPjCreation (_laAmmoType (_itConsumption it))) it +-- +--usePjCreationX :: Int -> Item -> Creature -> World -> World +--usePjCreationX i it cr = foldr f +-- (_amPjCreation (_laAmmoType (_itConsumption it)) it cr) +-- [1..i-1] +-- where +-- f n = (. _amPjCreation (_laAmmoType (_itConsumption it)) it (cr & crDir +~ (2*pi*fromIntegral n / fromIntegral i))) diff --git a/src/Dodge/Render/ShapePicture.hs b/src/Dodge/Render/ShapePicture.hs index e07d9d4c7..6d27dd42c 100644 --- a/src/Dodge/Render/ShapePicture.hs +++ b/src/Dodge/Render/ShapePicture.hs @@ -80,7 +80,8 @@ drawCreature cr = case _crType cr of , setDepth 0.049 . color (greyN 0.5) $ circleSolid 8 , color (greyN 0.5) $ circleSolid 8 ]) cr - Lampoid h -> picAtCrPosNoRot1 (lampCrPic h) cr + Lampoid{_lampHeight=h} -> picAtCrPosNoRot1 (lampCrPic h) cr + Turretoid -> mempty NonDrawnCreature -> mempty lampCrPic :: Float -> Picture diff --git a/src/Dodge/Tesla/Arc/Draw.hs b/src/Dodge/Tesla/Arc/Draw.hs new file mode 100644 index 000000000..71f43e375 --- /dev/null +++ b/src/Dodge/Tesla/Arc/Draw.hs @@ -0,0 +1,12 @@ +module Dodge.Tesla.Arc.Draw where +import Dodge.Data.TeslaArc +import Geometry +import Picture +drawTeslaArc :: TeslaArc -> Picture +drawTeslaArc pt = setLayer BloomNoZWrite $ pictures + [ setDepth 20.5 $ color (brightX 2 1 $ _taColor pt) $ thickLine 3 ps + , setDepth 20 $ color (V4 0 0 0 0.5) $ thickLine 10 ps + ] + where + ps = _taPoints pt + diff --git a/src/Dodge/Turretoid.hs b/src/Dodge/Turretoid.hs new file mode 100644 index 000000000..e3f92703c --- /dev/null +++ b/src/Dodge/Turretoid.hs @@ -0,0 +1,7 @@ +module Dodge.Turretoid where +import Dodge.Data +import Dodge.Creature.State +import Dodge.Creature.Impulse + +updateTurretoid :: Creature -> World -> World +updateTurretoid = stateUpdate followThenClearImpulses diff --git a/src/Dodge/Update.hs b/src/Dodge/Update.hs index a6d11911d..1d62921c2 100644 --- a/src/Dodge/Update.hs +++ b/src/Dodge/Update.hs @@ -5,6 +5,7 @@ Description : Simulation update -} module Dodge.Update ( updateUniverse ) where import Dodge.Data +import Dodge.Creature.Update import Dodge.RadarSweep import Dodge.PosEvent import Dodge.Spark @@ -94,7 +95,7 @@ functionalUpdate cfig w = checkEndGame . updateIMl' _terminals tmUpdate -- . updateIMl _machines mcChooseUpdate . updateIMl' _machines updateMachine - . updateIMl _creatures _crUpdate + . updateIMl' _creatures updateCreature -- creatures should be updated early so that crOldPos is set before any position change . over creatures (fmap setOldPos) . updateCreatureGroups