Get the bridge door animations running

This commit is contained in:
2020-03-27 00:54:57 +00:00
parent 79bfab7d6b
commit 316db89148
6 changed files with 106 additions and 15 deletions

View File

@@ -33,7 +33,7 @@ const (
TypeDropdownButton MenuType = 200 TypeDropdownButton MenuType = 200
TypeComboBoxItem MenuType = 205 TypeComboBoxItem MenuType = 205
TypeAnimationSample MenuType = 220 TypeAnimationSample MenuType = 220
TypeAnimationToo MenuType = 221 // No idea why we have two of these. FONTTYPE is animation speed. TypeAnimationHover MenuType = 221 // FONTTYPE is animation speed. Only animate when hovered
TypeMainButton MenuType = 228 TypeMainButton MenuType = 228
TypeSlider MenuType = 232 TypeSlider MenuType = 232
TypeStatusBar MenuType = 233 TypeStatusBar MenuType = 233

View File

@@ -0,0 +1,11 @@
package flow
func (f *Flow) linkBridge() {
// FIXME: sometimes these doors are frozen, depending on game state
f.onClick(bridge, "2.1", f.setDriver(briefing)) // Mission briefing clickable
f.onClick(bridge, "2.2", f.setDriver(choices)) // Options door hotspot
f.setFreeze(bridge, "2.4", false) // FIXME: Enter combat door hotspot (!!!)
f.onClick(bridge, "2.6", f.setDriver(configureVehiclesUltra)) // Vehicle configure door hotspot
f.onClick(bridge, "2.8", f.setDriver(configureUltEquip)) // Squads configure door hotspot
}

View File

@@ -26,15 +26,21 @@ type driverName string
const ( const (
// Names of all the drivers // Names of all the drivers
main driverName = "main" main driverName = "Main"
levelPly driverName = "levelPly" levelPly driverName = "LevelPly"
singles driverName = "singles" singles driverName = "Singles"
randomMap driverName = "randomMap" randomMap driverName = "RandomMap"
newGame driverName = "newGame" newGame driverName = "NewGame"
loadGame driverName = "loadGame" loadGame driverName = "LoadGame"
options driverName = "options" options driverName = "Options"
kbd driverName = "keyboard" kbd driverName = "Keyboard"
bridge driverName = "bridge" bridge driverName = "Bridge"
briefing driverName = "Briefing"
choices driverName = "Choices"
ultEquip driverName = "UltEquip"
configureUltEquip driverName = "Configure_UltEquip"
configureVehiclesUltra driverName = "Configure_vehicles_ultra"
) )
var ( var (
@@ -42,7 +48,8 @@ var (
driverNames = []driverName{ driverNames = []driverName{
main, levelPly, singles, randomMap, newGame, loadGame, options, kbd, main, levelPly, singles, randomMap, newGame, loadGame, options, kbd,
bridge, bridge, briefing, choices, ultEquip,
configureVehiclesUltra,
} }
// Constants used for sliders // Constants used for sliders

View File

@@ -11,6 +11,7 @@ func init() {
registerBuilder(menus.TypeSimpleButton, registerSimpleButton) registerBuilder(menus.TypeSimpleButton, registerSimpleButton)
registerBuilder(menus.TypeInvokeButton, registerInvokeButton) registerBuilder(menus.TypeInvokeButton, registerInvokeButton)
registerBuilder(menus.TypeMainButton, registerMainButton) registerBuilder(menus.TypeMainButton, registerMainButton)
registerBuilder(menus.TypeDoorHotspot, registerDebug("Unimplemented DoorHotspot", nil))
} }
// A button without hover animation // A button without hover animation

View File

@@ -26,10 +26,6 @@ func init() {
// Needed for Arrange.mnu (???) // Needed for Arrange.mnu (???)
registerBuilder(menus.TypeSquadButton, registerDebug("Unimplemented SquadButton", nil)) registerBuilder(menus.TypeSquadButton, registerDebug("Unimplemented SquadButton", nil))
registerBuilder(menus.TypeAnimationToo, registerDebug("Unimplemented AnimationToo", nil))
// Needed for Bridge.mnu
registerBuilder(menus.TypeDoorHotspot, registerDebug("Unimplemented DoorHotspot", nil))
// Needed for Briefing.mnu // Needed for Briefing.mnu
registerBuilder(menus.TypeLineBriefing, registerDebug("Unimplemented LineBriefing", nil)) registerBuilder(menus.TypeLineBriefing, registerDebug("Unimplemented LineBriefing", nil))

View File

@@ -15,6 +15,7 @@ func init() {
registerBuilder(menus.TypeHypertext, registerHypertext) registerBuilder(menus.TypeHypertext, registerHypertext)
registerBuilder(menus.TypeOverlay, registerOverlay) registerBuilder(menus.TypeOverlay, registerOverlay)
registerBuilder(menus.TypeAnimationSample, registerAnimation) registerBuilder(menus.TypeAnimationSample, registerAnimation)
registerBuilder(menus.TypeAnimationHover, registerDebug("WIP AnimationHover", registerAnimationHover))
} }
// A non-interactive element is not a widget; it merely displays some pixels and // A non-interactive element is not a widget; it merely displays some pixels and
@@ -31,6 +32,17 @@ type noninteractive struct {
hoverImpl hoverImpl
} }
// This particular animation has entry and exit sequences, which are invoked
// when entering and leaving hover, respectively. Example: bridge doors
type animationHover struct {
noninteractive // Use the frames in here for the "enter hover" animation
exitFrames animation // and here the "exit hover" animation
atTick int // Tracks progress through the frames
opening bool
closing bool
}
func registerStatic(d *Driver, r *menus.Record) error { func registerStatic(d *Driver, r *menus.Record) error {
// FIXME: SpriteID takes precedence over SHARE if present, but is that right? // FIXME: SpriteID takes precedence over SHARE if present, but is that right?
spriteId := r.Share spriteId := r.Share
@@ -125,6 +137,38 @@ func registerAnimation(d *Driver, r *menus.Record) error {
return nil return nil
} }
func registerAnimationHover(d *Driver, r *menus.Record) error {
sprite, err := d.menu.Sprite(r.SpriteId[0])
if err != nil {
return err
}
enterFrames, err := d.menu.Images(r.SpriteId[0], r.DrawType)
if err != nil {
return err
}
exitFrames, err := d.menu.Images(r.SpriteId[0]+r.DrawType, r.DrawType)
if err != nil {
return err
}
ani := &animationHover{
noninteractive: noninteractive{
frames: animation(enterFrames),
hoverImpl: hoverImpl{text: r.Text},
rect: sprite.Rect,
},
exitFrames: animation(exitFrames),
}
d.hoverables = append(d.hoverables, ani)
d.paintables = append(d.paintables, ani)
return nil
}
func (n *noninteractive) bounds() image.Rectangle { func (n *noninteractive) bounds() image.Rectangle {
return n.rect return n.rect
} }
@@ -138,3 +182,35 @@ func (n *noninteractive) regions(tick int) []region {
return out return out
} }
func (a *animationHover) regions(tick int) []region {
if a.opening || a.closing {
var anim animation
if a.opening {
anim = a.frames
} else {
anim = a.exitFrames
}
out := oneRegion(a.bounds().Min, anim[a.atTick])
if a.atTick < len(anim)-1 {
a.atTick += 1
} else if !a.hoverState() {
a.closing = false
}
return out
}
// Nothing doing, show a closed door
return oneRegion(a.bounds().Min, a.frames.image(0))
}
func (a *animationHover) setHoverState(value bool) {
a.atTick = 0
a.opening = value
a.closing = !value
a.hoverImpl.setHoverState(value)
}