Implement simple swarm mechanics
This commit is contained in:
@@ -36,35 +36,6 @@ import System.Random
|
|||||||
import Foreign.ForeignPtr
|
import Foreign.ForeignPtr
|
||||||
|
|
||||||
|
|
||||||
lineOrth :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
|
||||||
lineOrth ypos crs cpos = p
|
|
||||||
where ps = map _crPos $ IM.elems crs
|
|
||||||
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
|
||||||
p | dist cen ypos < 20 = ypos
|
|
||||||
| otherwise = errorClosestPointOnLine 500 ypos (ypos +.+ vNormal (cen -.- ypos)) cpos
|
|
||||||
|
|
||||||
lineUp :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
|
||||||
lineUp ypos crs cpos = p
|
|
||||||
where ps = map _crPos $ IM.elems crs
|
|
||||||
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
|
||||||
p = (0.05 *.* ypos) +.+ (0.95 *.* errorClosestPointOnLine 500 cen ypos cpos)
|
|
||||||
|
|
||||||
holdForm :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
|
||||||
holdForm ypos crs cpos = p
|
|
||||||
where ps = map _crPos $ IM.elems crs
|
|
||||||
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
|
||||||
p | dist cen ypos < 20 = ypos
|
|
||||||
| otherwise = ypos +.+ cpos -.- cen
|
|
||||||
|
|
||||||
-- not nice, a kind of encircle
|
|
||||||
spreadOut :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
|
||||||
spreadOut ypos crs cpos = p
|
|
||||||
where ps = map _crPos $ IM.elems crs
|
|
||||||
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
|
||||||
p | dist cen ypos < 30 = ypos
|
|
||||||
| otherwise = ypos +.+ (spreadFactor *.* cpos -.- cen)
|
|
||||||
spreadFactor | dist ypos cpos > 200 = 1
|
|
||||||
| otherwise = 5
|
|
||||||
----
|
----
|
||||||
---- -- generalised swarm ai, works out where you go from the position of your flock
|
---- -- generalised swarm ai, works out where you go from the position of your flock
|
||||||
---- swarmAI :: (Point -> IM.IntMap Creature -> Point -> Point) -> Int -> World -> World
|
---- swarmAI :: (Point -> IM.IntMap Creature -> Point -> Point) -> Int -> World -> World
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ startInventory = IM.fromList (zip [0..20]
|
|||||||
,spawnGun lamp
|
,spawnGun lamp
|
||||||
,lasGun
|
,lasGun
|
||||||
,autoGun
|
,autoGun
|
||||||
|
,flamer
|
||||||
--,poisonSprayer
|
--,poisonSprayer
|
||||||
,launcher
|
,launcher
|
||||||
--,lasGun
|
--,lasGun
|
||||||
|
|||||||
@@ -2,11 +2,58 @@ module Dodge.Creature.ImpulseRat
|
|||||||
where
|
where
|
||||||
import Dodge.Data
|
import Dodge.Data
|
||||||
import Dodge.Creature.ChooseTarget
|
import Dodge.Creature.ChooseTarget
|
||||||
|
import Dodge.Creature.State.Data
|
||||||
import Dodge.Creature.Rationality.Data
|
import Dodge.Creature.Rationality.Data
|
||||||
import Geometry
|
import Geometry
|
||||||
|
|
||||||
|
import qualified Data.IntMap as IM
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
|
lineOrth :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
||||||
|
lineOrth ypos crs cpos = p
|
||||||
|
where ps = map _crPos $ IM.elems crs
|
||||||
|
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
||||||
|
p | dist cen ypos < 20 = ypos
|
||||||
|
| otherwise = errorClosestPointOnLine 500 ypos (ypos +.+ vNormal (cen -.- ypos)) cpos
|
||||||
|
|
||||||
|
lineUp :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
||||||
|
lineUp ypos crs cpos = p
|
||||||
|
where ps = map _crPos $ IM.elems crs
|
||||||
|
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
||||||
|
p = (0.05 *.* ypos) +.+ (0.95 *.* errorClosestPointOnLine 500 cen ypos cpos)
|
||||||
|
|
||||||
|
holdForm :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
||||||
|
holdForm ypos crs cpos = p
|
||||||
|
where ps = map _crPos $ IM.elems crs
|
||||||
|
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
||||||
|
p | dist cen ypos < 20 = ypos
|
||||||
|
| otherwise = ypos +.+ cpos -.- cen
|
||||||
|
|
||||||
|
-- not nice, a kind of encircle
|
||||||
|
spreadOut :: Point2 -> IM.IntMap Creature -> Point2 -> Point2
|
||||||
|
spreadOut ypos crs cpos = p
|
||||||
|
where ps = map _crPos $ IM.elems crs
|
||||||
|
cen = (1 / fromIntegral (length ps)) *.* foldr1 (+.+) ps
|
||||||
|
p | dist cen ypos < 30 = ypos
|
||||||
|
| otherwise = ypos +.+ (spreadFactor *.* cpos -.- cen)
|
||||||
|
spreadFactor | dist ypos cpos > 200 = 1
|
||||||
|
| otherwise = 5
|
||||||
|
chaseTarget'
|
||||||
|
:: (Point2 -> IM.IntMap Creature -> Point2 -> Point2)
|
||||||
|
-> (Creature -> World -> Maybe Creature) -- ^ Function for determining target
|
||||||
|
-> World
|
||||||
|
-> Creature
|
||||||
|
-> Creature
|
||||||
|
chaseTarget' f targFunc w cr = case targFunc cr w of
|
||||||
|
Nothing -> cr
|
||||||
|
Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg' p cr crTarg
|
||||||
|
where
|
||||||
|
ypos = _crPos crTarg
|
||||||
|
cpos = _crPos cr
|
||||||
|
is = _swarm $ _crGroup cr
|
||||||
|
crs = IM.restrictKeys (_creatures w) is
|
||||||
|
p = f ypos crs cpos
|
||||||
|
|
||||||
chaseTarget
|
chaseTarget
|
||||||
:: (Creature -> World -> Maybe Creature) -- ^ Function for determining target
|
:: (Creature -> World -> Maybe Creature) -- ^ Function for determining target
|
||||||
-> World
|
-> World
|
||||||
@@ -16,6 +63,23 @@ chaseTarget targFunc w cr = case targFunc cr w of
|
|||||||
Nothing -> cr
|
Nothing -> cr
|
||||||
Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg cr crTarg
|
Just crTarg -> cr & crActionPlan . crImpulse .~ chaseTarg cr crTarg
|
||||||
|
|
||||||
|
chaseTarg' :: Point2 -> Creature -> Creature -> [Impulse]
|
||||||
|
chaseTarg' p cr crT
|
||||||
|
| dist tpos cpos < combinedRad + 5
|
||||||
|
&& abs ((_crDir cr) - argV (tpos -.- cpos)) < pi/4
|
||||||
|
&& _crMeleeCooldown cr == Just 0
|
||||||
|
= [Melee (_crID crT)]
|
||||||
|
| dist tpos cpos < combinedRad + 5
|
||||||
|
&& abs ((_crDir cr) - argV (tpos -.- cpos)) < pi/4
|
||||||
|
= [ TurnToward tpos 0.05 ]
|
||||||
|
| abs ((_crDir cr) - argV (p -.- cpos)) < pi/4
|
||||||
|
= [MoveForward 2.5 , TurnToward p 0.2, RandomTurn 0.2 ]
|
||||||
|
| otherwise = [MoveForward 2.5 , TurnToward p 0.05, RandomTurn 0.2 ]
|
||||||
|
where
|
||||||
|
cpos = _crPos cr
|
||||||
|
tpos = _crPos crT
|
||||||
|
combinedRad = _crRad cr + _crRad crT
|
||||||
|
|
||||||
chaseTarg :: Creature -> Creature -> [Impulse]
|
chaseTarg :: Creature -> Creature -> [Impulse]
|
||||||
chaseTarg cr crT
|
chaseTarg cr crT
|
||||||
| dist tpos cpos < combinedRad + 5
|
| dist tpos cpos < combinedRad + 5
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import Dodge.Creature.Stance.Data
|
|||||||
import Picture.Data
|
import Picture.Data
|
||||||
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
import qualified Data.Set as S
|
import qualified Data.IntSet as IS
|
||||||
|
|
||||||
data CreatureState = CrSt
|
data CreatureState = CrSt
|
||||||
{ _goals :: [[Impulse]]
|
{ _goals :: [[Impulse]]
|
||||||
@@ -42,7 +42,7 @@ data Faction
|
|||||||
|
|
||||||
data CrGroup
|
data CrGroup
|
||||||
= LoneWolf
|
= LoneWolf
|
||||||
| Swarm { _swarm :: S.Set Int }
|
| Swarm { _swarm :: IS.IntSet }
|
||||||
|
|
||||||
makeLenses ''CreatureState
|
makeLenses ''CreatureState
|
||||||
makeLenses ''CrSpState
|
makeLenses ''CrSpState
|
||||||
|
|||||||
@@ -29,11 +29,12 @@ import System.Random
|
|||||||
|
|
||||||
swarmCrit :: Creature
|
swarmCrit :: Creature
|
||||||
swarmCrit = defaultCreature
|
swarmCrit = defaultCreature
|
||||||
{ _crUpdate = stateUpdate $ meleeCooldown $ impulsiveAI $ chaseTarget targetYouLOS
|
{ _crUpdate = stateUpdate $ meleeCooldown $ impulsiveAI $ chaseTarget' lineUp targetYouLOS
|
||||||
, _crHP = 1
|
, _crHP = 1
|
||||||
, _crRad = 4
|
, _crRad = 4
|
||||||
, _crPict = basicCrPict yellow
|
, _crPict = basicCrPict yellow
|
||||||
, _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
|
, _crInv = IM.empty -- IM.fromList [(0,frontArmour)]
|
||||||
, _crCorpse = onLayer CorpseLayer $ color (greyN 0.5) $ circleSolid 4
|
, _crCorpse = onLayer CorpseLayer $ color (greyN 0.5) $ circleSolid 4
|
||||||
, _crFaction = ColorFaction yellow
|
, _crFaction = ColorFaction yellow
|
||||||
|
, _crMeleeCooldown = Just 0
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -8,6 +8,7 @@ import Picture
|
|||||||
import Dodge.Data
|
import Dodge.Data
|
||||||
import Dodge.Room
|
import Dodge.Room
|
||||||
import Dodge.Creature.State.Data
|
import Dodge.Creature.State.Data
|
||||||
|
import Dodge.Creature.SwarmCrit
|
||||||
import Dodge.Room.Procedural
|
import Dodge.Room.Procedural
|
||||||
import Dodge.Room.RoadBlock
|
import Dodge.Room.RoadBlock
|
||||||
import Dodge.Room.Data
|
import Dodge.Room.Data
|
||||||
@@ -51,7 +52,7 @@ roomTreex = do
|
|||||||
[[StartRoom]
|
[[StartRoom]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400
|
,[SpecificRoom . pure . pure . Right $ roomGlassOctogon 400
|
||||||
& rmPS %~ ([swarmPS 0 (x,y) 0 smallChaseCrit | x <- [-20,-19.5.. 20] , y <- [200,200.5..202] ]++)
|
& rmPS %~ ([swarmPS 0 (x,y) 0 swarmCrit | x <- [-20,-19.5.. 20] , y <- [200,200.5..202] ]++)
|
||||||
]
|
]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
,[Corridor]
|
,[Corridor]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import Dodge.Data
|
|||||||
import Dodge.LevelGen.Data
|
import Dodge.LevelGen.Data
|
||||||
import Dodge.Creature.State.Data
|
import Dodge.Creature.State.Data
|
||||||
|
|
||||||
import qualified Data.Set as S
|
import qualified Data.IntSet as IS
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
swarmPS :: Int -> Point2 -> Float -> Creature -> Placement
|
swarmPS :: Int -> Point2 -> Float -> Creature -> Placement
|
||||||
@@ -22,4 +22,4 @@ setSwarm psts (PutCrit cr) w
|
|||||||
where
|
where
|
||||||
cid = _crID cr
|
cid = _crID cr
|
||||||
theSwarm = Swarm swarmSet
|
theSwarm = Swarm swarmSet
|
||||||
swarmSet = S.fromList $ map (_crID . _unPutCrit) psts
|
swarmSet = IS.fromList $ map (_crID . _unPutCrit) psts
|
||||||
|
|||||||
+2
-2
@@ -187,9 +187,9 @@ crCrSpring :: Creature -> Creature -> World -> World
|
|||||||
crCrSpring c1 c2 w
|
crCrSpring c1 c2 w
|
||||||
| id1 == id2 = w
|
| id1 == id2 = w
|
||||||
| vec == (0,0) = w
|
| vec == (0,0) = w
|
||||||
| diff < comRad = over (creatures . ix id1 . crPos) (+.+ overlap1)
|
| diff >= comRad = w
|
||||||
|
| otherwise = over (creatures . ix id1 . crPos) (+.+ overlap1)
|
||||||
$ over (creatures . ix id2 . crPos) (-.- overlap2) w
|
$ over (creatures . ix id2 . crPos) (-.- overlap2) w
|
||||||
| otherwise = w
|
|
||||||
where
|
where
|
||||||
id1 = _crID c1
|
id1 = _crID c1
|
||||||
id2 = _crID c2
|
id2 = _crID c2
|
||||||
|
|||||||
Reference in New Issue
Block a user