Files
questshock/modding/hacked/ss1/content/interpreters/Simplifier.go
T

194 lines
5.9 KiB
Go

package interpreters
import (
"math"
)
// RawValueFormatter provides the format function for given value.
// If nothing special is to be displayed, an empty string should be returned.
// The handler is responsible for adding the number value representation.
type RawValueFormatter func(value int) string
// RawValueHandler is for a simple value range.
type RawValueHandler func(minValue, maxValue int64, formatter RawValueFormatter)
// EnumValueHandler is for enumerated (mapped) values.
type EnumValueHandler func(values map[uint32]string)
// BitfieldHandler is for bitfields.
type BitfieldHandler func(values map[uint32]string)
// ObjectIDHandler is for object identifier in a level.
type ObjectIDHandler func()
// SpecialHandler is for rare occasions.
type SpecialHandler func()
// RotationHandler is for circular values.
type RotationHandler func(minValue, maxValue int64)
func basicToString(value int) string {
return ""
}
// RangedValue creates a field range for specific minimum and maximum values.
func RangedValue(minValue, maxValue int64) FieldRange {
return FormattedRangedValue(minValue, maxValue, basicToString)
}
// FormattedRangedValue is similar to RangedValue, and adds a formatting function.
func FormattedRangedValue(minValue, maxValue int64, formatter RawValueFormatter) FieldRange {
return func(simpl *Simplifier) bool {
return simpl.rangedValue(minValue, maxValue, formatter)
}
}
// EnumValue creates a field range describing enumerated values.
func EnumValue(values map[uint32]string) FieldRange {
return func(simpl *Simplifier) bool {
return simpl.enumValue(values)
}
}
// Bitfield creates a field range describing bitfield values.
func Bitfield(values map[uint32]string) FieldRange {
return func(simpl *Simplifier) bool {
return simpl.bitfield(values)
}
}
// ObjectID creates a field range describing object identifier.
func ObjectID() FieldRange {
return func(simpl *Simplifier) bool {
return simpl.objectIndex()
}
}
// RotationValue creates a field range for a rotational property.
func RotationValue(minValue, maxValue int64) FieldRange {
return func(simpl *Simplifier) bool {
return simpl.rotation(minValue, maxValue)
}
}
// SpecialValue creates a field range for special fields.
// Currently known special values:
// * BinaryCodedDecimal - for keypads storing their number as BCD
// * LevelTexture - index value into level texture list
// * MaterialOrLevelTexture - index value into level texture list, or material (bit 7 toggles)
// * VariableKey - for actions
// * VariableCondition - for action conditions
// * ObjectTriple - for 0x00CCSSTT selection
// * ObjectHeight - for level height value 0..255
// * MoveTileHeight - for change tile height action
// * TileHeight - tile heights
// * TileType - tile types
// * Unknown - It is unclear whether this field would have any effect, none identified so far
// * Ignored - Although values have been found in this field, they don't appear to have any effect
// * Mistake - It is assumed that these values should have been placed somewhere else. Typical example: Container content
// * Internal - Fields that are handled mainly by the engine and shouldn't be modified.
func SpecialValue(specialType string) FieldRange {
return func(simpl *Simplifier) bool {
return simpl.specialValue(specialType)
}
}
// Simplifier forwards descriptions in a way the requester can use.
type Simplifier struct {
rawValueHandler RawValueHandler
enumValueHandler EnumValueHandler
bitfieldHandler BitfieldHandler
objectIDHandler ObjectIDHandler
rotationHandler RotationHandler
specialHandler map[string]SpecialHandler
}
// NewSimplifier returns a new instance of a simplifier, with the minimal
// handler set.
func NewSimplifier(rawValueHandler RawValueHandler) *Simplifier {
return &Simplifier{
rawValueHandler: rawValueHandler,
specialHandler: make(map[string]SpecialHandler)}
}
func (simpl *Simplifier) rawValue(e *entry) {
max := int64(math.Pow(2, float64(e.count*8)))
if max == 256 {
simpl.rawValueHandler(0, 255, basicToString)
} else {
half := max / 2
simpl.rawValueHandler(-1, half-1, basicToString)
}
}
func (simpl *Simplifier) rangedValue(minValue, maxValue int64, formatter RawValueFormatter) bool {
simpl.rawValueHandler(minValue, maxValue, formatter)
return true
}
// SetEnumValueHandler registers the handler for enumerations.
func (simpl *Simplifier) SetEnumValueHandler(handler EnumValueHandler) {
simpl.enumValueHandler = handler
}
func (simpl *Simplifier) enumValue(values map[uint32]string) (result bool) {
if simpl.enumValueHandler != nil {
simpl.enumValueHandler(values)
result = true
}
return
}
// SetBitfieldHandler registers the handler for bitfields.
func (simpl *Simplifier) SetBitfieldHandler(handler BitfieldHandler) {
simpl.bitfieldHandler = handler
}
func (simpl *Simplifier) bitfield(values map[uint32]string) (result bool) {
if simpl.bitfieldHandler != nil {
simpl.bitfieldHandler(values)
result = true
}
return
}
// SetObjectIDHandler registers the handler for object indices.
func (simpl *Simplifier) SetObjectIDHandler(handler ObjectIDHandler) {
simpl.objectIDHandler = handler
}
func (simpl *Simplifier) objectIndex() (result bool) {
if simpl.objectIDHandler != nil {
simpl.objectIDHandler()
result = true
}
return
}
// SetSpecialHandler registers the handler for special values.
func (simpl *Simplifier) SetSpecialHandler(specialType string, handler SpecialHandler) {
simpl.specialHandler[specialType] = handler
}
func (simpl *Simplifier) specialValue(specialType string) (result bool) {
handler, existing := simpl.specialHandler[specialType]
if existing && (handler != nil) {
handler()
result = true
}
return
}
// SetRotationHandler registers the handler for rotation values.
func (simpl *Simplifier) SetRotationHandler(handler RotationHandler) {
simpl.rotationHandler = handler
}
func (simpl *Simplifier) rotation(minValue, maxValue int64) (result bool) {
if simpl.rotationHandler != nil {
simpl.rotationHandler(minValue, maxValue)
result = true
}
return
}