Tweak item dropping, add item radius

This commit is contained in:
2021-11-19 14:04:44 +00:00
parent da83bd06a6
commit 4ef1811dd6
6 changed files with 56 additions and 32 deletions
+51 -28
View File
@@ -10,7 +10,7 @@ module Dodge.Creature.Action
, blinkAction
, maybeSizeSelf
, crAutoReload
, copyItemToFloor
, copyInvItemToFloor
, youDropItem
, pickUpItem
)
@@ -206,50 +206,73 @@ stripNoItems :: Creature -> World -> World
stripNoItems cr = creatures . ix (_crID cr) . crInv %~ IM.mapMaybe f
where
f NoItem = Nothing
f x = Just x
f x = Just x
dropUnselected :: Creature -> World -> World
dropUnselected cr w = foldr (dropItem cr) w . IM.keys $ unselectedItems
where
unselectedItems = _crInvSel cr `IM.delete` _crInv cr
dropUnselected cr w = foldr (dropItem cr) w . IM.keys
$ _crInvSel cr `IM.delete` _crInv cr
dropItem :: Creature -> Int -> World -> World
dropItem cr invid = rmInvItem cid invid . copyItemToFloor cr invid
where
cid = _crID cr
dropItem cr invid = rmInvItem (_crID cr) invid . copyInvItemToFloor cr invid
{- | Get your creature to drop the item under the cursor. -}
youDropItem :: World -> World
youDropItem w = case yourItem w ^? itCurseStatus of
Just Uncursed -> rmSelectedInvItem (_yourID w)
. copyItemToFloor (you w) (_crInvSel cr)
$ soundStart (CrSound (_crID cr)) (_crPos cr) whiteNoiseFadeOutS Nothing
w
Just Uncursed -> w
& dropItem cr (_crInvSel cr)
& soundStart (CrSound (_crID cr)) (_crPos cr) whiteNoiseFadeOutS Nothing
_ -> w
where
cr = you w
{- | Copy an inventory item to the floor. -}
copyItemToFloor
copyInvItemToFloor
:: Creature
-> Int -- ^ Inventory position
-> World
-> World
copyItemToFloor cr i w = case _crInv cr IM.! i of
copyInvItemToFloor cr i w = case _crInv cr IM.! i of
NoItem -> w
it -> over floorItems (IM.insert flid theflit) . updateLocation $ set randGen g w
where
(rot, g) = randomR (-pi,pi) $ _randGen w
offset = (_crRad cr + 2) *.* unitVectorAtAngle rot
updateLocation w' = case it ^? itID of
Just (Just i') -> w' & itemPositions . ix i' .~ OnFloor flid
_ -> w'
flid = IM.newKey $ _floorItems w
theflit = FlIt
{_flIt = it
,_flItPos = offset +.+ _crPos cr
,_flItRot = rot
,_flItID = flid
}
it -> copyItemToFloor (_crPos cr) it w
{- | Copy an item to the floor. -}
copyItemToFloor
:: Point2
-> Item
-> World
-> World
copyItemToFloor pos it w = w'
& floorItems %~ IM.insert flid theflit
& updateLocation
where
(p',w') = findWallFreeDropPoint (_itRad $ _itDimension it) pos w
rot = fst . randomR (-pi,pi) $ _randGen w
updateLocation = case it ^? itID of
Just (Just i') -> itemPositions . ix i' .~ OnFloor flid
_ -> id
flid = IM.newKey $ _floorItems w
theflit = FlIt
{_flIt = it
,_flItPos = p'
,_flItRot = rot
,_flItID = flid
}
findWallFreeDropPoint :: Float -> Point2 -> World -> (Point2,World)
findWallFreeDropPoint r p w = (head $ mapMaybe f cardinalVectors ++ [p]
, w {_randGen = g})
where
f q = testOnWall r $ p +.+ rotateV rot (10 *.* q)
testOnWall r' q | circOnSomeWall q r' w = Nothing
| otherwise = Just q
(rot, g) = randomR (0,2*pi) $ _randGen w
cardinalVectors :: [Point2]
cardinalVectors =
[ V2 1 0
, V2 0 1
, V2 (-1) 0
, V2 0 (-1)
]
{- | Pick up a specific item. -}
pickUpItem
:: Int -- ^ Creature id
+1 -1
View File
@@ -60,7 +60,7 @@ stateUpdate u cr w = case u (updateMovement cr) w of
(_crCorpse cr)
-- | Drop items according to the creature state.
dropByState :: Creature -> World -> World
dropByState cr w = foldr (copyItemToFloor cr) w is
dropByState cr w = foldr (copyInvItemToFloor cr) w is
where
is :: [Int]
is = case cr ^. crState . crDropsOnDeath of
+1
View File
@@ -409,6 +409,7 @@ data CurseStatus = Uncursed | UndroppableIdentified | UndroppableUnidentified
data ItemDimension = ItemDimension
{ _itDim :: Point3 -- length width height
, _itRad :: Float
, _itHandle :: Point3
, _itCenter :: Point3
, _muzzleLength :: Float
+1
View File
@@ -51,6 +51,7 @@ defaultGun = Weapon
defaultItemDimension :: ItemDimension
defaultItemDimension = ItemDimension
{ _itDim = V3 4 4 4
, _itRad = 10
, _itHandle = V3 2 2 2
, _itCenter = V3 2 2 2
, _muzzleLength = 5 -- how much the item projects out from the cr radius when aiming
+1 -2
View File
@@ -27,8 +27,7 @@ colCrWall w c
| otherwise = c & crPos .~ _crOldPos c
where
c'' = c & crPos %~ pushOutFromWalls rad ls
c' = c & crPos %~
pushOutFromWalls rad (reverse ls)
c' = c & crPos %~ pushOutFromWalls rad (reverse ls)
. pushOutFromWalls rad ls
. flip (collidePointWalls p1) wls -- check push throughs
rad = _crRad c + wallBuffer
+1 -1
View File
@@ -171,7 +171,7 @@ pHalf :: Point2 -> Point2 -> Point2
pHalf !a !b = 0.5 *.* (a +.+ b)
-- | Test whether a circle is on a segment by intersecting a new normal segment through the
-- center of the circle with the segment itself.
-- Returns False if the circle center is beyond the enpoints of the
-- Returns False if the circle center is beyond the endpoints of the
-- segment.
circOnSegNoEndpoints :: Point2 -> Point2 -> Point2 -> Float -> Bool
{-# INLINE circOnSegNoEndpoints #-}