module Game.LambdaHack.Common.AtomicCmd
( Atomic(..), CmdAtomic(..), SfxAtomic(..), HitAtomic(..)
, undoCmdAtomic, undoSfxAtomic, undoAtomic
) where
import Data.Binary
import Data.Text (Text)
import GHC.Generics (Generic)
import Game.LambdaHack.Common.Actor
import Game.LambdaHack.Common.Animation
import qualified Game.LambdaHack.Common.Color as Color
import qualified Game.LambdaHack.Common.Effect as Effect
import Game.LambdaHack.Common.Faction
import qualified Game.LambdaHack.Common.Feature as F
import Game.LambdaHack.Common.Item
import qualified Game.LambdaHack.Common.Kind as Kind
import Game.LambdaHack.Common.Level
import Game.LambdaHack.Common.Msg
import Game.LambdaHack.Common.Perception
import Game.LambdaHack.Common.Point
import Game.LambdaHack.Common.State
import Game.LambdaHack.Common.Time
import Game.LambdaHack.Common.Vector
import Game.LambdaHack.Content.ItemKind as ItemKind
import Game.LambdaHack.Content.TileKind as TileKind
data Atomic =
CmdAtomic !CmdAtomic
| SfxAtomic !SfxAtomic
deriving (Show, Eq, Generic)
instance Binary Atomic
data CmdAtomic =
CreateActorA !ActorId !Actor ![(ItemId, Item)]
| DestroyActorA !ActorId !Actor ![(ItemId, Item)]
| CreateItemA !ItemId !Item !Int !Container
| DestroyItemA !ItemId !Item !Int !Container
| SpotActorA !ActorId !Actor ![(ItemId, Item)]
| LoseActorA !ActorId !Actor ![(ItemId, Item)]
| SpotItemA !ItemId !Item !Int !Container
| LoseItemA !ItemId !Item !Int !Container
| MoveActorA !ActorId !Point !Point
| WaitActorA !ActorId !Time !Time
| DisplaceActorA !ActorId !ActorId
| MoveItemA !ItemId !Int !Container !Container
| AgeActorA !ActorId !Time
| HealActorA !ActorId !Int
| HasteActorA !ActorId !Speed
| PathActorA !ActorId !(Maybe [Vector]) !(Maybe [Vector])
| ColorActorA !ActorId !Color.Color !Color.Color
| QuitFactionA !FactionId !(Maybe Actor) !(Maybe Status) !(Maybe Status)
| LeadFactionA !FactionId !(Maybe ActorId) !(Maybe ActorId)
| DiplFactionA !FactionId !FactionId !Diplomacy !Diplomacy
| AlterTileA !LevelId !Point !(Kind.Id TileKind) !(Kind.Id TileKind)
| SearchTileA !ActorId !Point !(Kind.Id TileKind) !(Kind.Id TileKind)
| SpotTileA !LevelId ![(Point, Kind.Id TileKind)]
| LoseTileA !LevelId ![(Point, Kind.Id TileKind)]
| AlterSmellA !LevelId !Point !(Maybe Time) !(Maybe Time)
| SpotSmellA !LevelId ![(Point, Time)]
| LoseSmellA !LevelId ![(Point, Time)]
| AgeLevelA !LevelId !Time
| AgeGameA !Time
| DiscoverA !LevelId !Point !ItemId !(Kind.Id ItemKind)
| CoverA !LevelId !Point !ItemId !(Kind.Id ItemKind)
| PerceptionA !LevelId !PerActor !PerActor
| RestartA !FactionId !Discovery !FactionPers !State !DebugModeCli !Text
| RestartServerA !State
| ResumeA !FactionId !FactionPers
| ResumeServerA !State
| KillExitA !FactionId
| SaveBkpA
| MsgAllA !Msg
deriving (Show, Eq, Generic)
instance Binary CmdAtomic
data SfxAtomic =
StrikeD !ActorId !ActorId !Item !HitAtomic
| RecoilD !ActorId !ActorId !Item !HitAtomic
| ProjectD !ActorId !ItemId
| CatchD !ActorId !ItemId
| ActivateD !ActorId !ItemId
| CheckD !ActorId !ItemId
| TriggerD !ActorId !Point !F.Feature
| ShunD !ActorId !Point !F.Feature
| EffectD !ActorId !(Effect.Effect Int)
| MsgFidD !FactionId !Msg
| MsgAllD !Msg
| DisplayPushD !FactionId
| DisplayDelayD !FactionId
| RecordHistoryD !FactionId
deriving (Show, Eq, Generic)
instance Binary SfxAtomic
data HitAtomic = HitD | HitBlockD | MissBlockD
deriving (Show, Eq, Generic)
instance Binary HitAtomic
undoCmdAtomic :: CmdAtomic -> Maybe CmdAtomic
undoCmdAtomic cmd = case cmd of
CreateActorA aid body ais -> Just $ DestroyActorA aid body ais
DestroyActorA aid body ais -> Just $ CreateActorA aid body ais
CreateItemA iid item k c -> Just $ DestroyItemA iid item k c
DestroyItemA iid item k c -> Just $ CreateItemA iid item k c
SpotActorA aid body ais -> Just $ LoseActorA aid body ais
LoseActorA aid body ais -> Just $ SpotActorA aid body ais
SpotItemA iid item k c -> Just $ LoseItemA iid item k c
LoseItemA iid item k c -> Just $ SpotItemA iid item k c
MoveActorA aid fromP toP -> Just $ MoveActorA aid toP fromP
WaitActorA aid fromWait toWait -> Just $ WaitActorA aid toWait fromWait
DisplaceActorA source target -> Just $ DisplaceActorA target source
MoveItemA iid k c1 c2 ->Just $ MoveItemA iid k c2 c1
AgeActorA aid t -> Just $ AgeActorA aid (timeNegate t)
HealActorA aid n -> Just $ HealActorA aid (n)
HasteActorA aid delta -> Just $ HasteActorA aid (speedNegate delta)
PathActorA aid fromPath toPath -> Just $ PathActorA aid toPath fromPath
ColorActorA aid fromCol toCol -> Just $ ColorActorA aid toCol fromCol
QuitFactionA fid mb fromSt toSt -> Just $ QuitFactionA fid mb toSt fromSt
LeadFactionA fid source target -> Just $ LeadFactionA fid target source
DiplFactionA fid1 fid2 fromDipl toDipl ->
Just $ DiplFactionA fid1 fid2 toDipl fromDipl
AlterTileA lid p fromTile toTile -> Just $ AlterTileA lid p toTile fromTile
SearchTileA aid p fromTile toTile -> Just $ SearchTileA aid p toTile fromTile
SpotTileA lid ts -> Just $ LoseTileA lid ts
LoseTileA lid ts -> Just $ SpotTileA lid ts
AlterSmellA lid p fromSm toSm -> Just $ AlterSmellA lid p toSm fromSm
SpotSmellA lid sms -> Just $ LoseSmellA lid sms
LoseSmellA lid sms -> Just $ SpotSmellA lid sms
AgeLevelA lid t -> Just $ AgeLevelA lid (timeNegate t)
AgeGameA t -> Just $ AgeGameA (timeNegate t)
DiscoverA lid p iid ik -> Just $ CoverA lid p iid ik
CoverA lid p iid ik -> Just $ DiscoverA lid p iid ik
PerceptionA lid outPer inPer -> Just $ PerceptionA lid inPer outPer
RestartA{} -> Just cmd
RestartServerA{} -> Just cmd
ResumeA{} -> Nothing
ResumeServerA{} -> Nothing
KillExitA{} -> Nothing
SaveBkpA -> Nothing
MsgAllA{} -> Nothing
undoSfxAtomic :: SfxAtomic -> SfxAtomic
undoSfxAtomic cmd = case cmd of
StrikeD source target item b -> RecoilD source target item b
RecoilD source target item b -> StrikeD source target item b
ProjectD aid iid -> CatchD aid iid
CatchD aid iid -> ProjectD aid iid
ActivateD aid iid -> CheckD aid iid
CheckD aid iid -> ActivateD aid iid
TriggerD aid p feat -> ShunD aid p feat
ShunD aid p feat -> TriggerD aid p feat
EffectD{} -> cmd
MsgFidD{} -> cmd
MsgAllD{} -> cmd
DisplayPushD{} -> cmd
DisplayDelayD{} -> cmd
RecordHistoryD{} -> cmd
undoAtomic :: Atomic -> Maybe Atomic
undoAtomic (CmdAtomic cmd) = fmap CmdAtomic $ undoCmdAtomic cmd
undoAtomic (SfxAtomic sfx) = Just $ SfxAtomic $ undoSfxAtomic sfx