From f8e92a94e52cb0b77dcb08df0cc6c78fbae73975 Mon Sep 17 00:00:00 2001 From: Tomas Doran Date: Sat, 18 Jul 2020 21:45:34 +0100 Subject: [PATCH] Add a load of things I'm using for reference --- README | 13 ++++++++ TODO | 3 +- screen/attack.go | 76 ++++++++++++++++++--------------------------- screen/castspell.go | 51 ++++++++++++++---------------- screen/grow.go | 12 +++---- screen/move.go | 19 ++++++++---- screen/waitfor.go | 41 +++++++++++++++--------- 7 files changed, 112 insertions(+), 103 deletions(-) create mode 100644 README diff --git a/README b/README new file mode 100644 index 0000000..a179f97 --- /dev/null +++ b/README @@ -0,0 +1,13 @@ +https://web.archive.org/web/19991006003843/http://www.gre.ac.uk/~bm10/chaos/rules.txt + +https://www.giantbomb.com/chaos-the-battle-of-wizards/3030-9342/ + +http://rk.nvg.ntnu.no/sinclair/instructions/chaos.html + +https://web.archive.org/web/20160214004030/http://www.zxsoftware.co.uk/Data/Spectrum/C/instructions/Chaos.txt + +https://www.gameinformer.com/b/features/archive/2014/02/25/what-makes-chaos-the-battle-of-wizards-a-classic.aspx + +https://chaosremakes.fandom.com/wiki/Comments_on_Chaos + + diff --git a/TODO b/TODO index a2e2320..b444bf3 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,8 @@ Bug / missing feature list: Tree spells Castle/Citadel spells Mounts - Killing wizards + Killing wizard animation + Nicer end screen Combat spells Law/Chaos rating doing anything + being global Board inspect character diff --git a/screen/attack.go b/screen/attack.go index 91ce9cd..dc53288 100644 --- a/screen/attack.go +++ b/screen/attack.go @@ -7,7 +7,6 @@ import ( "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" - "github.com/bobtfish/mayhem/fx" "github.com/bobtfish/mayhem/logical" "github.com/bobtfish/mayhem/movable" "github.com/bobtfish/mayhem/render" @@ -55,62 +54,47 @@ func (screen *EngagedAttack) Step(ss pixel.Picture, win *pixelgl.Window) GameScr type DoAttack struct { *WithBoard - Fx *fx.Fx AttackerV logical.Vec DefenderV logical.Vec PlayerIdx int MovedCharacters map[movable.Movable]bool } -func (screen *DoAttack) Enter(ss pixel.Picture, win *pixelgl.Window) { - ClearScreen(ss, win) - fmt.Printf("Enter DoAttack screen, place fx\n") - fx := fx.FxAttack() - screen.Fx = fx - screen.WithBoard.Grid.PlaceGameObject(screen.DefenderV, fx) -} +func (screen *DoAttack) Enter(ss pixel.Picture, win *pixelgl.Window) {} func (screen *DoAttack) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { - batch := screen.WithBoard.DrawBoard(ss, win) - batch.Draw(win) - - // Run animation till attack is finished - if screen.Fx.RemoveMe() { - - // Work out what happened. This is overly simple, but equivalent to what the original game does :) - defender := screen.WithBoard.Grid.GetGameObject(screen.DefenderV) - defenceRating := defender.(movable.Attackable).GetDefence() + rand.Intn(9) - attacker := screen.WithBoard.Grid.GetGameObject(screen.AttackerV) - attackRating := attacker.(movable.Attackerable).GetCombat() + rand.Intn(9) - - fmt.Printf("Attack rating %d defence rating %d\n", attackRating, defenceRating) - if attackRating > defenceRating { - // If the defender can be killed, kill them. Otherwise remove them - ob, corpsable := defender.(movable.Corpseable) - fmt.Printf("Defender is %T corpsable %v ob %T(%v)\n", defender, corpsable, ob, ob) - makesCorpse := corpsable && ob.CanMakeCorpse() - if makesCorpse { - fmt.Printf("make corpse\n") - ob.MakeCorpse() - } else { - fmt.Printf("remove defender as no corpse\n") - died := screen.WithBoard.Grid.GetGameObjectStack(screen.DefenderV).RemoveTopObject() - if KillIfPlayer(died, screen.WithBoard.Grid) { - if WeHaveAWinner(screen.WithBoard.Players) { - return &WinnerScreen{ - WithBoard: screen.WithBoard, - } + // Work out what happened. This is overly simple, but equivalent to what the original game does :) + defender := screen.WithBoard.Grid.GetGameObject(screen.DefenderV) + defenceRating := defender.(movable.Attackable).GetDefence() + rand.Intn(9) + attacker := screen.WithBoard.Grid.GetGameObject(screen.AttackerV) + attackRating := attacker.(movable.Attackerable).GetCombat() + rand.Intn(9) + + fmt.Printf("Attack rating %d defence rating %d\n", attackRating, defenceRating) + if attackRating > defenceRating { + // If the defender can be killed, kill them. Otherwise remove them + ob, corpsable := defender.(movable.Corpseable) + fmt.Printf("Defender is %T corpsable %v ob %T(%v)\n", defender, corpsable, ob, ob) + makesCorpse := corpsable && ob.CanMakeCorpse() + if makesCorpse { + fmt.Printf("make corpse\n") + ob.MakeCorpse() + } else { + fmt.Printf("remove defender as no corpse\n") + died := screen.WithBoard.Grid.GetGameObjectStack(screen.DefenderV).RemoveTopObject() + if KillIfPlayer(died, screen.WithBoard.Grid) { + if WeHaveAWinner(screen.WithBoard.Players) { + return &WinnerScreen{ + WithBoard: screen.WithBoard, } } } - - doCharacterMove(screen.AttackerV, screen.DefenderV, screen.WithBoard.Grid) - } - return &MoveFindCharacterScreen{ - WithBoard: screen.WithBoard, - PlayerIdx: screen.PlayerIdx, - MovedCharacters: screen.MovedCharacters, } + + doCharacterMove(screen.AttackerV, screen.DefenderV, screen.WithBoard.Grid) + } + return &MoveFindCharacterScreen{ + WithBoard: screen.WithBoard, + PlayerIdx: screen.PlayerIdx, + MovedCharacters: screen.MovedCharacters, } - return screen } diff --git a/screen/castspell.go b/screen/castspell.go index d50d080..20b09a4 100644 --- a/screen/castspell.go +++ b/screen/castspell.go @@ -7,7 +7,6 @@ import ( "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" - "github.com/bobtfish/mayhem/fx" "github.com/bobtfish/mayhem/grid" "github.com/bobtfish/mayhem/logical" "github.com/bobtfish/mayhem/player" @@ -37,11 +36,9 @@ func NextSpellCastOrMove(playerIdx int, players []*player.Player, grid *grid.Gam } } return &Pause{ - WaitFor: &WaitFor{ - Skip: skipPause, - Grid: grid, - NextScreen: nextScreen, - }, + Skip: skipPause, + Grid: grid, + NextScreen: nextScreen, } } @@ -137,10 +134,13 @@ func (screen *TargetSpellScreen) AnimateAndCast() GameScreen { if anim != nil { screen.WithBoard.Grid.PlaceGameObject(target, anim) } - return &DoSpellCast{ - WithBoard: screen.WithBoard, - PlayerIdx: screen.PlayerIdx, - Fx: anim, + return &WaitForFx{ + NextScreen: &DoSpellCast{ + WithBoard: screen.WithBoard, + PlayerIdx: screen.PlayerIdx, + }, + Grid: screen.WithBoard.Grid, + Fx: anim, } } @@ -149,7 +149,6 @@ func (screen *TargetSpellScreen) AnimateAndCast() GameScreen { type DoSpellCast struct { *WithBoard - Fx *fx.Fx PlayerIdx int } @@ -159,22 +158,18 @@ func (screen *DoSpellCast) Enter(ss pixel.Picture, win *pixelgl.Window) { func (screen *DoSpellCast) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { batch := screen.WithBoard.DrawBoard(ss, win) batch.Draw(win) - // Wait until the spell animation is finished - if screen.Fx == nil || screen.Fx.RemoveMe() { - // Fx for spell cast finished - // Work out what happened :) - targetVec := screen.WithBoard.CursorPosition - fmt.Printf("About to call player CastSpell method\n") - success := screen.Players[screen.PlayerIdx].CastSpell(targetVec, screen.WithBoard.Grid) - fmt.Printf("Finished player CastSpell method\n") - if success { - fmt.Printf("Spell Succeeds\n") - render.NewTextDrawer(ss).DrawText("Spell Succeeds", logical.V(0, 0), win) - } else { - fmt.Printf("Spell failed\n") - render.NewTextDrawer(ss).DrawText("Spell Failed", logical.V(0, 0), win) - } - return NextSpellCastOrMove(screen.PlayerIdx, screen.Players, screen.Grid, false) + // Fx for spell cast finished + // Work out what happened :) + targetVec := screen.WithBoard.CursorPosition + fmt.Printf("About to call player CastSpell method\n") + success := screen.Players[screen.PlayerIdx].CastSpell(targetVec, screen.WithBoard.Grid) + fmt.Printf("Finished player CastSpell method\n") + if success { + fmt.Printf("Spell Succeeds\n") + render.NewTextDrawer(ss).DrawText("Spell Succeeds", logical.V(0, 0), win) + } else { + fmt.Printf("Spell failed\n") + render.NewTextDrawer(ss).DrawText("Spell Failed", logical.V(0, 0), win) } - return screen + return NextSpellCastOrMove(screen.PlayerIdx, screen.Players, screen.Grid, false) } diff --git a/screen/grow.go b/screen/grow.go index d5dc203..d886992 100644 --- a/screen/grow.go +++ b/screen/grow.go @@ -51,13 +51,11 @@ func (screen *GrowScreen) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen firstAlivePlayerIdx := NextPlayerIdx(-1, screen.WithBoard.Players) fmt.Printf("First alive player index %d\n", firstAlivePlayerIdx) return &Pause{ - WaitFor: &WaitFor{ - Grid: screen.WithBoard.Grid, - NextScreen: &TurnMenuScreen{ - Players: screen.WithBoard.Players, - Grid: screen.WithBoard.Grid, - PlayerIdx: firstAlivePlayerIdx, - }, + Grid: screen.WithBoard.Grid, + NextScreen: &TurnMenuScreen{ + Players: screen.WithBoard.Players, + Grid: screen.WithBoard.Grid, + PlayerIdx: firstAlivePlayerIdx, }, } } diff --git a/screen/move.go b/screen/move.go index 97d0572..6bc6630 100644 --- a/screen/move.go +++ b/screen/move.go @@ -6,6 +6,7 @@ import ( "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" + "github.com/bobtfish/mayhem/fx" "github.com/bobtfish/mayhem/grid" "github.com/bobtfish/mayhem/logical" "github.com/bobtfish/mayhem/movable" @@ -234,12 +235,18 @@ func DoAttackMaybe(from, to logical.Vec, playerIdx int, withBoard *WithBoard, mo fmt.Printf("Target square is attackable\n") if !ob.CheckBelongsTo(withBoard.Players[playerIdx]) { fmt.Printf("Target square belongs to a different player do attack\n") - return &DoAttack{ - AttackerV: from, - DefenderV: to, - WithBoard: withBoard, - PlayerIdx: playerIdx, - MovedCharacters: movedCharacters, + fx := fx.FxAttack() + withBoard.Grid.PlaceGameObject(to, fx) + return &WaitForFx{ + NextScreen: &DoAttack{ + AttackerV: from, + DefenderV: to, + WithBoard: withBoard, + PlayerIdx: playerIdx, + MovedCharacters: movedCharacters, + }, + Grid: withBoard.Grid, + Fx: fx, }, true } } diff --git a/screen/waitfor.go b/screen/waitfor.go index c136243..3b2a194 100644 --- a/screen/waitfor.go +++ b/screen/waitfor.go @@ -1,6 +1,7 @@ package screen import ( + "fmt" "time" "github.com/faiface/pixel" @@ -14,13 +15,14 @@ import ( type WaitFor struct { NextScreen GameScreen Grid *grid.GameGrid - Skip bool + FinishedF func() bool } func (screen *WaitFor) Enter(ss pixel.Picture, win *pixelgl.Window) {} func (screen *WaitFor) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { - if screen.Skip { + if screen.FinishedF() { + fmt.Printf("Waitfor Skip to next screen\n") return screen.NextScreen } if screen.Grid != nil { @@ -30,29 +32,38 @@ func (screen *WaitFor) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { } type Pause struct { - *WaitFor - Started time.Time + NextScreen GameScreen + Grid *grid.GameGrid + Skip bool } -func (screen *Pause) Enter(ss pixel.Picture, win *pixelgl.Window) { - screen.Started = time.Now() -} +func (screen *Pause) Enter(ss pixel.Picture, win *pixelgl.Window) {} func (screen *Pause) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { - if screen.Started.Add(time.Second).Before(time.Now()) { - screen.WaitFor.Skip = true + started := time.Now() + return &WaitFor{ + NextScreen: screen.NextScreen, + Grid: screen.Grid, + FinishedF: func() bool { + return screen.Skip || started.Add(time.Second).Before(time.Now()) + }, } - return screen.WaitFor.Step(ss, win) } type WaitForFx struct { - Fx *fx.Fx - *WaitFor + Fx *fx.Fx + NextScreen GameScreen + Grid *grid.GameGrid } +func (screen *WaitForFx) Enter(ss pixel.Picture, win *pixelgl.Window) {} + func (screen *WaitForFx) Step(ss pixel.Picture, win *pixelgl.Window) GameScreen { - if screen.Fx.RemoveMe() { - screen.WaitFor.Skip = true + return &WaitFor{ + NextScreen: screen.NextScreen, + Grid: screen.Grid, + FinishedF: func() bool { + return screen.Fx == nil || screen.Fx.RemoveMe() + }, } - return screen.WaitFor.Step(ss, win) }