This commit is contained in:
2025-10-22 09:30:19 +01:00
parent 2f06c56185
commit 30da635990
4 changed files with 75 additions and 116 deletions
+1 -67
View File
@@ -1,18 +1,12 @@
module Dodge.DrWdWd where
module Dodge.DrWdWd (doDrWdWd) where
import Dodge.ShiftPoint
import Linear
import Data.IntMap.Merge.Strict
import Control.Lens
import Data.Foldable
import qualified Data.IntSet as IS
import Dodge.Base
import Dodge.Block.Debris
import Dodge.Data.World
import Dodge.LevelGen.DoorPane
--import Dodge.Placement.PlaceSpot.TriggerDoor
import Dodge.SoundLogic
import Dodge.Wall.Move
import Dodge.WorldBool
import Geometry
@@ -20,41 +14,8 @@ doDrWdWd :: DrWdWd -> Door -> World -> World
doDrWdWd dww = case dww of
DrWdId -> const id
DrWdMakeDoorDebris -> makeDoorDebris
DrWdMechanismStepwise nsteps wlids pss -> doorMechanismStepwise nsteps wlids pss
DoorMechanism -> doorMechanism
DoorLerp -> doorLerp
-- TODO sort out why DoorClosed status does not update correctly 22/06/23
doorMechanism :: Door -> World -> World
doorMechanism dr w = case mvDir of
Just d ->
w
& flip (IS.foldl' (flip (`translateWallID` d))) (_drWallIDs dr)
& moveUpdate
& cWorld . lWorld . doors . ix drid . drPos . each %~ (+.+ d)
-- & updateDoorEdges (_drObstacleType dr) (_drObstructs dr)
Nothing -> w
where
toOpen = doWdBl (_drTrigger dr) w
mvDir
| toOpen && _drStatus dr == DoorOpen = Nothing -- Not sure why necessary
| toOpen && dist dpos dop > 0.5 = Just $ vecBetweenSpeed speed dpos dop
| dist dpos dcp > 0.5 = Just $ vecBetweenSpeed speed dpos dcp
| otherwise = Nothing
speed = _drSpeed dr
drid = _drID dr
moveUpdate = playSound . setStatus
playSound
| _drPushedBy dr == PushesItself = soundContinue (WallSound drid) dpos slideDoorS (Just 1)
| otherwise = id
dpos = snd $ _drPos dr
dop = snd $ _drOpenPos dr
dcp = snd $ _drClosePos dr
setStatus
| dist dpos dop < 1 = cWorld . lWorld . doors . ix drid . drStatus .~ DoorOpen
| dist dpos dcp < 1 = cWorld . lWorld . doors . ix drid . drStatus .~ DoorClosed
| otherwise = cWorld . lWorld . doors . ix drid . drStatus .~ DoorHalfway
doorLerp :: Door -> World -> World
doorLerp dr w = case newlerp of
Just x ->
@@ -94,30 +55,3 @@ doorLerp dr w = case newlerp of
| dist dpos dop < 1 = cWorld . lWorld . doors . ix drid . drStatus .~ DoorOpen
| dist dpos dcp < 1 = cWorld . lWorld . doors . ix drid . drStatus .~ DoorClosed
| otherwise = cWorld . lWorld . doors . ix drid . drStatus .~ DoorHalfway
-- TODO use vector instead of list, perhaps also memoisation of rectanglePairs
-- TODO update _drPos
-- perhaps also remove use of DoorInt in favour of DoorOpen/DoorClosed
-- perhaps only store intermediate door pos pairs, calculate all wall positions
-- on the fly
doorMechanismStepwise :: Int -> [Int] -> [(Point2, Point2)] -> Door -> World -> World
doorMechanismStepwise nsteps wlids pss dr w
| toOpen = case _drStatus dr of
DoorInt x | x == nsteps -> w
DoorInt x -> setWalls (x + 1)
_ -> w
| otherwise = case _drStatus dr of
DoorInt 0 -> w
DoorInt x -> setWalls (x -1)
_ -> w
where
drid = _drID dr
playSound = soundContinue (WallSound drid) (fst $ head pss) slideDoorS (Just 1)
toOpen = doWdBl (_drTrigger dr) w
setWalls n =
playSound (foldl' (&) w (zipWith moveWallID wlids newps))
& cWorld . lWorld . doors . ix drid . drStatus .~ DoorInt n
where
newps = uncurry (rectanglePairs 9) (pss !! n)
-- it is not at all clear that the zoning selects the correct walls