Adding modding folder with a hacked build.

This commit is contained in:
ml
2026-09-26 08:53:08 +02:00
parent cdb960dc71
commit c91080aba7
755 changed files with 50424 additions and 0 deletions
@@ -0,0 +1,7 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseAnimation = interpreters.New()
@@ -0,0 +1,122 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseBigStuff = interpreters.New()
var multiAnimation = interpreters.New().
With("LoopType", 0, 2).As(interpreters.Bitfield(map[uint32]string{0x01: "Forward/Backward", 0x02: "Backward"})).
With("Alternation", 2, 2).As(interpreters.SpecialValue("MultiAnimation")).
With("Picture", 4, 2).As(interpreters.SpecialValue("PictureSource")).
With("Alternate", 6, 2).As(interpreters.SpecialValue("PictureSource"))
var displayScenery = baseBigStuff.
With("FrameCount", 0, 2).As(interpreters.RangedValue(0, 8)).
Refining("", 2, 8, multiAnimation, interpreters.Always)
var displayControlPedestal = baseBigStuff.
With("FrameCount", 0, 2).As(interpreters.RangedValue(0, 8)).
With("TriggerObjectID1", 2, 2).As(interpreters.ObjectID()).
With("TriggerObjectID2", 4, 2).As(interpreters.ObjectID()).
Refining("", 2, 8, multiAnimation, interpreters.Always)
var cabinetFurniture = baseBigStuff.
With("Object1ID", 2, 2).As(interpreters.ObjectID()).
With("Object2ID", 4, 2).As(interpreters.ObjectID())
var texturableFurniture = baseBigStuff.
With("Texture", 6, 2).As(interpreters.SpecialValue("PictureSource"))
var wordScenery = baseBigStuff.
With("TextIndex", 0, 2).As(interpreters.RangedValue(0, 511)).
With("Font", 2, 1).As(interpreters.Bitfield(map[uint32]string{
0x0F: "Face",
0xF0: "Size"})).
With("Color", 4, 1).As(interpreters.RangedValue(0, 255))
var textureMapScenery = baseBigStuff.
With("TextureIndex", 6, 2).As(interpreters.SpecialValue("LevelTexture"))
var buttonControlPedestal = baseBigStuff.
With("TriggerObjectID1", 2, 2).As(interpreters.ObjectID()).
With("TriggerObjectID2", 4, 2).As(interpreters.ObjectID())
var surgicalMachine = baseBigStuff.
With("BrokenState", 2, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "OK", 0xE7: "Broken"})).
With("BrokenMessageIndex", 5, 1)
var securityCamera = baseBigStuff.
With("PanningSwitch", 2, 1).As(interpreters.EnumValue(map[uint32]string{0: "Stationary", 1: "Panning"}))
var solidBridge = baseBigStuff.
With("Size", 2, 1).As(interpreters.Bitfield(map[uint32]string{0x0F: "X", 0xF0: "Y"})).
With("Height", 3, 1).As(interpreters.SpecialValue("ObjectHeight")).
With("TopBottomTexture", 4, 1).As(interpreters.SpecialValue("MaterialOrLevelTexture")).
With("SideTexture", 5, 1).As(interpreters.SpecialValue("MaterialOrLevelTexture"))
var forceBridge = baseBigStuff.
With("Size", 2, 1).As(interpreters.Bitfield(map[uint32]string{0x0F: "X", 0xF0: "Y"})).
With("Height", 3, 1).As(interpreters.SpecialValue("ObjectHeight")).
With("Color", 6, 1).As(interpreters.FormattedRangedValue(0, 255,
func(value int) (result string) {
return forceColors[value]
}))
func initBigStuff() interpreterRetriever {
displays := newInterpreterLeaf(displayScenery)
textureable := newInterpreterLeaf(texturableFurniture)
electronics := newInterpreterEntry(baseBigStuff)
electronics.set(6, displays)
electronics.set(7, displays)
furniture := newInterpreterEntry(baseBigStuff)
furniture.set(2, newInterpreterLeaf(cabinetFurniture))
furniture.set(5, textureable)
furniture.set(7, textureable)
furniture.set(8, textureable)
surfaces := newInterpreterEntry(baseBigStuff)
surfaces.set(3, newInterpreterLeaf(wordScenery))
surfaces.set(6, displays)
surfaces.set(7, newInterpreterLeaf(textureMapScenery))
surfaces.set(8, displays)
surfaces.set(9, displays)
lighting := newInterpreterEntry(baseBigStuff)
medicalEquipment := newInterpreterEntry(baseBigStuff)
medicalEquipment.set(0, newInterpreterLeaf(buttonControlPedestal))
medicalEquipment.set(3, newInterpreterLeaf(surgicalMachine))
medicalEquipment.set(5, textureable)
scienceSecurityEquipment := newInterpreterEntry(baseBigStuff)
scienceSecurityEquipment.set(4, newInterpreterLeaf(securityCamera))
scienceSecurityEquipment.set(5, newInterpreterLeaf(buttonControlPedestal))
scienceSecurityEquipment.set(6, newInterpreterLeaf(displayControlPedestal))
gardenScenery := newInterpreterEntry(baseBigStuff)
bridges := newInterpreterEntry(baseBigStuff)
solidBridges := newInterpreterLeaf(solidBridge)
forceBridges := newInterpreterLeaf(forceBridge)
bridges.set(0, solidBridges)
bridges.set(1, solidBridges)
bridges.set(7, forceBridges)
bridges.set(8, forceBridges)
bridges.set(9, forceBridges)
class := newInterpreterEntry(baseBigStuff)
class.set(0, electronics)
class.set(1, furniture)
class.set(2, surfaces)
class.set(3, lighting)
class.set(4, medicalEquipment)
class.set(5, scienceSecurityEquipment)
class.set(6, gardenScenery)
class.set(7, bridges)
return class
}
@@ -0,0 +1,36 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseContainer = interpreters.New()
var standardContainer = baseContainer.
With("ObjectID1", 0, 2).As(interpreters.ObjectID()).
With("ObjectID2", 2, 2).As(interpreters.ObjectID()).
With("ObjectID3", 4, 2).As(interpreters.ObjectID()).
With("ObjectID4", 6, 2).As(interpreters.ObjectID())
var crate = standardContainer.
With("Width", 8, 1).
With("Depth", 9, 1).
With("Height", 10, 1).
With("TopBottomTexture", 11, 1).
With("SideTexture", 12, 1)
func initContainers() interpreterRetriever {
standardContainers := newInterpreterLeaf(standardContainer)
crates := newInterpreterLeaf(crate)
class := newInterpreterEntry(baseContainer)
class.set(0, crates)
class.set(1, standardContainers)
class.set(2, standardContainers)
class.set(3, standardContainers)
class.set(4, standardContainers)
class.set(5, standardContainers)
class.set(6, standardContainers)
return class
}
@@ -0,0 +1,40 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseCritter = interpreters.New().
With("PendingZRotation", 0, 4).
With("ForwardVelocityFraction", 4, 2).
With("ForwardVelocity", 6, 2).
With("Hastiness", 0x0A, 2).
With("StateTimeout", 0x0C, 2).As(interpreters.RangedValue(0, 300)).
With("Unknown000E", 0x0E, 2).As(interpreters.SpecialValue("Unknown")).
With("Unknown0010", 0x10, 2).As(interpreters.SpecialValue("Unknown")).
With("RoamingState", 0x14, 1).
With("PrimaryState", 0x15, 1).As(interpreters.EnumValue(map[uint32]string{
0: "docile",
1: "cautious",
2: "hostile",
3: "cautious (?)",
4: "attacking",
5: "sleeping",
6: "tranquilized",
7: "confused"})).
With("SecondaryState", 0x16, 1).
With("TertiaryState", 0x17, 1).
With("AICoordinates0018", 0x18, 2).As(interpreters.SpecialValue("Unknown")).
With("AICoordinates001A", 0x1A, 2).As(interpreters.SpecialValue("Unknown")).
With("AICoordinates001C", 0x1C, 2).As(interpreters.SpecialValue("Unknown")).
With("Always255", 0x1E, 1).As(interpreters.RangedValue(0, 255)).
With("AICoordinates001F", 0x1F, 1).As(interpreters.SpecialValue("Unknown")).
With("LootObjectID1", 0x20, 2).As(interpreters.ObjectID()).
With("LootObjectID2", 0x22, 2).As(interpreters.ObjectID()).
With("Unknown0026", 0x26, 2).As(interpreters.SpecialValue("Unknown"))
func initCritters() interpreterRetriever {
class := newInterpreterEntry(baseCritter)
return class
}
@@ -0,0 +1,38 @@
package lvlobj
import (
"fmt"
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseDoor = interpreters.New().
With("LockVariableIndex", 0, 2).As(interpreters.SpecialValue("LockVariable")).
With("LockMessageIndex", 2, 1).As(interpreters.FormattedRangedValue(0, 255,
func(value int) (result string) {
return fmt.Sprintf("%d", value+7)
})).
With("ForceDoorColor", 3, 1).As(interpreters.FormattedRangedValue(0, 255,
func(value int) (result string) {
return forceColors[value]
})).
With("RequiredAccessLevel", 4, 1).As(interpreters.FormattedRangedValue(0, 255,
func(value int) (result string) {
if value == 255 {
result = "SHODAN"
} else if accessLevel, known := accessLevelMasks[1<<uint32(value)]; known {
result = accessLevel
} else {
result = "Unknown"
}
return
})).
With("AutoCloseTime", 5, 1).As(interpreters.FormattedRangedValue(0, 255,
func(value int) string {
return fmt.Sprintf("%.2f sec", float64(value)*0.5)
})).
With("OtherObjectID", 6, 2).As(interpreters.ObjectID())
func initDoors() interpreterRetriever {
return newInterpreterLeaf(baseDoor)
}
@@ -0,0 +1,217 @@
package lvlobj
import (
"fmt"
"github.com/inkyblackness/hacked/ss1/content/archive/level/lvlobj/actions"
"github.com/inkyblackness/hacked/ss1/content/archive/level/lvlobj/conditions"
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseFixture = interpreters.New()
var gameVariablePanel = baseFixture.
Refining("Condition", 2, 4, conditions.GameVariable(), interpreters.Always)
var buttonPanel = gameVariablePanel.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always).
With("AccessMask", 22, 2)
var recepticlePanel = baseFixture
var standardRecepticle = recepticlePanel.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always).
Refining("TypeCondition", 2, 3, conditions.ObjectType(), interpreters.Always).
With("FailMessage", 5, 1).As(interpreters.RangedValue(0, 255))
var antennaRelayPanel = recepticlePanel.
With("TriggerObjectID1", 6, 2).As(interpreters.ObjectID()).
With("TriggerObjectID2", 10, 2).As(interpreters.ObjectID()).
With("DestroyObjectID", 14, 2).As(interpreters.ObjectID())
var retinalIDScanner = recepticlePanel.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always).
With("Head", 2, 3).As(interpreters.FormattedRangedValue(0, 21,
func(value int) (result string) {
if value < 11 {
return fmt.Sprintf("(8/2/13 frame: %d)", value)
} else {
return fmt.Sprintf("(8/2/14 frame: %d)", value-11)
}
}))
var cyberspaceTerminal = gameVariablePanel.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always)
var energyChargeStation = gameVariablePanel.
With("EnergyDelta", 6, 4).As(interpreters.RangedValue(0, 255)).
With("RechargeTime", 10, 4).As(interpreters.FormattedRangedValue(0, 3600,
func(value int) string {
return fmt.Sprintf("%d sec", value)
})).
With("TriggerObjectID", 14, 4).As(interpreters.ObjectID()).
With("RechargedTimestamp", 18, 4)
var vendingMachine = baseFixture.
Refining("TypeCondition", 2, 3, conditions.ObjectType(), interpreters.Always).
With("FailMessage", 5, 1).As(interpreters.RangedValue(0, 255))
var inputPanel = gameVariablePanel
var wirePuzzleStateDescription = interpreters.Bitfield(map[uint32]string{
0x00000007: "Wire 1 Left",
0x00000038: "Wire 1 Right",
0x000001C0: "Wire 2 Left",
0x00000E00: "Wire 2 Right",
0x00007000: "Wire 3 Left",
0x00038000: "Wire 3 Right",
0x001C0000: "Wire 4 Left",
0x00E00000: "Wire 4 Right",
0x07000000: "Wire 5 Left",
0x38000000: "Wire 5 Right"})
var wirePuzzleData = interpreters.New().
With("TargetObjectID", 0, 4).As(interpreters.ObjectID()).
With("Layout", 4, 1).As(interpreters.Bitfield(map[uint32]string{0x0F: "Wires", 0xF0: "Connectors"})).
With("TargetPowerLevel", 5, 1).
With("WireProperties", 6, 1).As(interpreters.Bitfield(map[uint32]string{0x01: "Colored", 0xF0: "Solved"})).
With("TargetState", 8, 4).As(wirePuzzleStateDescription).
With("CurrentState", 12, 4).As(wirePuzzleStateDescription)
var blockPuzzleData = interpreters.New().
With("TargetObjectID", 0, 4).As(interpreters.ObjectID()).
With("StateStoreObjectID", 4, 2).As(interpreters.ObjectID()).
With("Layout", 8, 4).As(interpreters.Bitfield(map[uint32]string{
0x00000001: "PuzzleSolved",
0x00000070: "SourceCoordinate",
0x00000180: "SourceLocation",
0x00007000: "DestCoordinate",
0x00018000: "DestLocation",
0x00700000: "Width",
0x07000000: "Height",
0x70000000: "SideEffectType"}))
var puzzleSpecificData = interpreters.New().
With("Type", 7, 1).As(interpreters.EnumValue(map[uint32]string{0: "WirePuzzle", 0x10: "BlockPuzzle"})).
Refining("Wire", 0, 18, wirePuzzleData, func(inst *interpreters.Instance) bool {
return inst.Get("Type") == 0
}).
Refining("Block", 0, 18, blockPuzzleData, func(inst *interpreters.Instance) bool {
return inst.Get("Type") == 0x10
})
var puzzlePanel = inputPanel.
Refining("Puzzle", 6, 18, puzzleSpecificData, interpreters.Always)
var elevatorPanel = inputPanel.
With("DestinationObjectIndex2", 6, 2).As(interpreters.RangedValue(0, 871)).
With("DestinationObjectIndex1", 8, 2).As(interpreters.RangedValue(0, 871)).
With("DestinationObjectIndex4", 10, 2).As(interpreters.RangedValue(0, 871)).
With("DestinationObjectIndex3", 12, 2).As(interpreters.RangedValue(0, 871)).
With("DestinationObjectIndex6", 14, 2).As(interpreters.RangedValue(0, 871)).
With("DestinationObjectIndex5", 16, 2).As(interpreters.RangedValue(0, 871)).
With("AccessibleBitmask", 18, 2).As(interpreters.Bitfield(map[uint32]string{
0x0001: "Level 0",
0x0002: "Level 1",
0x0004: "Level 2",
0x0008: "Level 3",
0x0010: "Level 4",
0x0020: "Level 5",
0x0040: "Level 6",
0x0080: "Level 7",
0x0100: "Level 8",
0x0200: "Level 9",
0x0400: "Level 10",
0x0800: "Level 11",
0x1000: "Level 12",
0x2000: "Level 13",
0x4000: "Level 14",
0x8000: "Level 15"})).
With("ElevatorShaftBitmask", 20, 2).As(interpreters.Bitfield(map[uint32]string{
0x0001: "Level 0",
0x0002: "Level 1",
0x0004: "Level 2",
0x0008: "Level 3",
0x0010: "Level 4",
0x0020: "Level 5",
0x0040: "Level 6",
0x0080: "Level 7",
0x0100: "Level 8",
0x0200: "Level 9",
0x0400: "Level 10",
0x0800: "Level 11",
0x1000: "Level 12",
0x2000: "Level 13",
0x4000: "Level 14",
0x8000: "Level 15"}))
var numberPad = inputPanel.
With("Combination1", 6, 2).As(interpreters.SpecialValue("BinaryCodedDecimal")).
With("TriggerObjectID1", 8, 2).As(interpreters.ObjectID()).
With("Combination2", 10, 2).As(interpreters.SpecialValue("BinaryCodedDecimal")).
With("TriggerObjectID2", 12, 2).As(interpreters.ObjectID()).
With("Combination3", 14, 2).As(interpreters.SpecialValue("BinaryCodedDecimal")).
With("TriggerObjectID3", 16, 2).As(interpreters.ObjectID()).
With("FailObjectID", 18, 2).As(interpreters.ObjectID())
var inactiveCyberspaceSwitch = gameVariablePanel.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always)
func initFixtures() interpreterRetriever {
standardRecepticles := newInterpreterLeaf(standardRecepticle)
antennaRelays := newInterpreterLeaf(antennaRelayPanel)
recepticles := newInterpreterEntry(recepticlePanel)
recepticles.set(0, standardRecepticles)
recepticles.set(1, standardRecepticles)
recepticles.set(2, standardRecepticles)
recepticles.set(3, antennaRelays) // standard panel
recepticles.set(4, antennaRelays) // plastiqued
recepticles.set(6, newInterpreterLeaf(retinalIDScanner))
stations := newInterpreterEntry(baseFixture)
stations.set(0, newInterpreterLeaf(cyberspaceTerminal))
stations.set(1, newInterpreterLeaf(energyChargeStation))
vendingMachines := newInterpreterEntry(vendingMachine)
puzzles := newInterpreterLeaf(puzzlePanel)
elevatorPanels := newInterpreterLeaf(elevatorPanel)
numberPads := newInterpreterLeaf(numberPad)
inputPanels := newInterpreterEntry(inputPanel)
inputPanels.set(0, puzzles)
inputPanels.set(1, puzzles)
inputPanels.set(2, puzzles)
inputPanels.set(3, puzzles)
inputPanels.set(4, elevatorPanels)
inputPanels.set(5, elevatorPanels)
inputPanels.set(6, elevatorPanels)
inputPanels.set(7, numberPads)
inputPanels.set(8, numberPads)
inputPanels.set(9, puzzles)
inputPanels.set(10, puzzles)
cyberspaceSwitches := newInterpreterEntry(baseFixture)
cyberspaceSwitches.set(0, newInterpreterLeaf(inactiveCyberspaceSwitch))
class := newInterpreterEntry(baseFixture)
class.set(0, newInterpreterLeaf(buttonPanel))
class.set(1, recepticles)
class.set(2, stations)
class.set(3, inputPanels)
class.set(4, vendingMachines)
class.set(5, cyberspaceSwitches)
return class
}
func initCyberspaceFixtures() interpreterRetriever {
cyberspaceSwitches := newInterpreterEntry(baseFixture)
cyberspaceSwitches.set(0, newInterpreterLeaf(inactiveCyberspaceSwitch))
class := newInterpreterEntry(baseFixture)
class.set(5, cyberspaceSwitches)
return class
}
@@ -0,0 +1,18 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
"github.com/inkyblackness/hacked/ss1/content/object"
)
// ForCyberspace returns an interpreter instance that handles the level class
// data of the specified object - in cyberspace.
func ForCyberspace(triple object.Triple, data []byte) *interpreters.Instance {
return cyberspaceEntries.specialize(int(triple.Class)).specialize(int(triple.Subclass)).specialize(int(triple.Type)).instance(data)
}
// CyberspaceExtra returns an interpreter instance that handles the level object extra
// data of the specified object - in cybperspace.
func CyberspaceExtra(triple object.Triple, data []byte) *interpreters.Instance {
return cyberspaceExtras.specialize(int(triple.Class)).specialize(int(triple.Subclass)).specialize(int(triple.Type)).instance(data)
}
@@ -0,0 +1,18 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
"github.com/inkyblackness/hacked/ss1/content/object"
)
// ForRealWorld returns an interpreter instance that handles the level class
// data of the specified object - in real world.
func ForRealWorld(triple object.Triple, data []byte) *interpreters.Instance {
return realWorldEntries.specialize(int(triple.Class)).specialize(int(triple.Subclass)).specialize(int(triple.Type)).instance(data)
}
// RealWorldExtra returns an interpreter instance that handles the level object extra
// data of the specified object - in real world.
func RealWorldExtra(triple object.Triple, data []byte) *interpreters.Instance {
return realWorldExtras.specialize(int(triple.Class)).specialize(int(triple.Subclass)).specialize(int(triple.Type)).instance(data)
}
@@ -0,0 +1,17 @@
package lvlobj
var forceColors = map[int]string{
0: "Default (red)",
247: "Gray, medium",
248: "Gray, light",
249: "Red, light",
250: "Green, light",
251: "Blue, light",
252: "Invisible",
253: "Blue, medium",
254: "Green, medium",
255: "Red, medium"}
@@ -0,0 +1,21 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseGrenade = interpreters.New().
With("Unknown0000", 0, 2).
With("State", 2, 2).As(interpreters.EnumValue(map[uint32]string{0: "Inert", 1: "Thrown Live", 5: "Landed Live"})).
With("TimerTime", 4, 2).As(interpreters.RangedValue(0, 32767))
func initGrenades() interpreterRetriever {
timedExplosives := newInterpreterEntry(baseGrenade)
timedExplosives.set(2, newInterpreterLeaf(interpreters.New())) // Object explosion - not encountered
class := newInterpreterEntry(baseGrenade)
class.set(1, timedExplosives)
return class
}
@@ -0,0 +1,44 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
const (
// EnergyWeaponMaxTemperature is the maximum value possible for heat.
EnergyWeaponMaxTemperature = 100
// EnergyWeaponMaxEnergy is the maximum value for energy.
// The original source does not explicitly state this value, it has been determined by looking at
// a savegame with the energy set to max. A closely related number in the source is
// in the macro "mfd_charge_units_per_pixel", which scales to 69.
EnergyWeaponMaxEnergy = 59
)
var baseGun = interpreters.New()
var energyWeapon = baseGun.
With("Charge", 0, 1).As(interpreters.Bitfield(
map[uint32]string{
0x80: "Overload",
0x7F: "Energy",
})).
With("Temperature", 1, 1).As(interpreters.RangedValue(0, EnergyWeaponMaxTemperature))
var projectileWeapon = baseGun.
With("AmmoType", 0, 1).As(interpreters.EnumValue(map[uint32]string{0: "Standard", 1: "Special"})).
With("AmmoCount", 1, 1).As(interpreters.RangedValue(0, 255))
func initGuns() interpreterRetriever {
projectileWeapons := newInterpreterLeaf(projectileWeapon)
energyWeapons := newInterpreterLeaf(energyWeapon)
class := newInterpreterEntry(baseGun)
class.set(0, projectileWeapons)
class.set(1, projectileWeapons)
class.set(2, projectileWeapons)
class.set(4, energyWeapons)
class.set(5, energyWeapons)
return class
}
@@ -0,0 +1,8 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseHardware = interpreters.New().
With("Version", 0, 1).As(interpreters.RangedValue(0, 4))
@@ -0,0 +1,9 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
"github.com/inkyblackness/hacked/ss1/content/object"
)
// InterpreterFactory returns an interpreter instance according to a specific object triple.
type InterpreterFactory func(object.Triple, []byte) *interpreters.Instance
@@ -0,0 +1,53 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
type interpreterRetriever interface {
specialize(key int) interpreterRetriever
instance(data []byte) *interpreters.Instance
}
type interpreterLeaf struct {
desc *interpreters.Description
}
func newInterpreterLeaf(desc *interpreters.Description) *interpreterLeaf {
return &interpreterLeaf{desc: desc}
}
func (node *interpreterLeaf) specialize(key int) interpreterRetriever {
return node
}
func (node *interpreterLeaf) instance(data []byte) *interpreters.Instance {
return node.desc.For(data)
}
type interpreterEntry struct {
defaultLeaf *interpreterLeaf
subEntries map[int]interpreterRetriever
}
func newInterpreterEntry(defaultDesc *interpreters.Description) *interpreterEntry {
return &interpreterEntry{
defaultLeaf: newInterpreterLeaf(defaultDesc),
subEntries: make(map[int]interpreterRetriever)}
}
func (node *interpreterEntry) set(key int, sub interpreterRetriever) {
node.subEntries[key] = sub
}
func (node *interpreterEntry) specialize(key int) (retriever interpreterRetriever) {
retriever = node.subEntries[key]
if retriever == nil {
retriever = node.defaultLeaf
}
return
}
func (node *interpreterEntry) instance(data []byte) *interpreters.Instance {
return node.defaultLeaf.instance(data)
}
@@ -0,0 +1,7 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var basePhysics = interpreters.New()
@@ -0,0 +1,128 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseItem = interpreters.New()
var paperItem = baseItem.
With("PaperId", 2, 1)
var briefcaseItem = baseItem.
With("ObjectID1", 2, 2).As(interpreters.ObjectID()).
With("ObjectID2", 4, 2).As(interpreters.ObjectID()).
With("ObjectID3", 6, 2).As(interpreters.ObjectID()).
With("ObjectID4", 8, 2).As(interpreters.ObjectID())
var corpseItem = baseItem.
With("Unknown0000", 0, 2).As(interpreters.SpecialValue("Unknown")).
With("ObjectID1", 2, 2).As(interpreters.ObjectID()).
With("ObjectID2", 4, 2).As(interpreters.ObjectID()).
With("ObjectID3", 6, 2).As(interpreters.ObjectID()).
With("ObjectID4", 8, 2).As(interpreters.ObjectID())
var severedHeadItem = baseItem.
With("ImageIndex", 2, 1)
var accessLevelMasks = map[uint32]string{
0x00000001: "None",
0x00000002: "Generic1",
0x00000004: "Generic2",
0x00000008: "Generic3",
0x00000010: "Generic4",
0x00000020: "Generic5",
0x00000040: "Generic6",
0x00000080: "Generic7",
0x00000100: "Group1",
0x00000200: "Group2",
0x00000400: "Group3",
0x00000800: "Group4",
0x00001000: "Group5",
0x00002000: "Group6",
0x00004000: "Group7",
0x00008000: "Group8",
0x00010000: "Group9",
0x00020000: "Group10",
0x00040000: "Group11",
0x00080000: "Group12",
0x00100000: "Group13",
0x00200000: "Group14",
0x00400000: "Group15",
0x00800000: "Group16",
0x01000000: "Personal1",
0x02000000: "Personal2",
0x04000000: "Personal3",
0x08000000: "Personal4",
0x10000000: "Personal5",
0x20000000: "Personal6",
0x40000000: "Personal7"}
var accessMaskDescription = interpreters.Bitfield(accessLevelMasks)
var accessCardItem = baseItem.
With("Ignored0000", 0, 2).As(interpreters.SpecialValue("Ignored")).
With("AccessMask", 2, 4).As(accessMaskDescription)
var securityIDModuleItem = baseItem.
With("AccessMask", 2, 4).As(accessMaskDescription)
var cyberInfoNodeItem = baseItem.
With("TextIndex", 2, 1)
var cyberRestorative = baseItem.
With("RestorationAmount", 2, 1)
var cyberDefenseMine = baseItem.
With("DamageAmount", 2, 1)
var cyberBarricade = baseItem.
With("Size", 2, 1).
With("Height", 3, 1).
With("Color", 6, 1)
func initSmallStuff() interpreterRetriever {
junk := newInterpreterEntry(baseItem)
junk.set(2, newInterpreterLeaf(paperItem))
junk.set(7, newInterpreterLeaf(briefcaseItem))
dead := newInterpreterEntry(baseItem)
corpses := newInterpreterLeaf(corpseItem)
severedHeads := newInterpreterLeaf(severedHeadItem)
dead.set(0, corpses)
dead.set(1, corpses)
dead.set(2, corpses)
dead.set(3, corpses)
dead.set(4, corpses)
dead.set(5, corpses)
dead.set(6, corpses)
dead.set(7, corpses)
dead.set(13, severedHeads)
dead.set(14, severedHeads)
class := newInterpreterEntry(baseItem)
class.set(0, junk)
class.set(2, dead)
class.set(4, newInterpreterLeaf(accessCardItem))
return class
}
func initCyberspaceSmallStuff() interpreterRetriever {
cyberspaceItems := newInterpreterEntry(baseItem)
infoNodes := newInterpreterLeaf(cyberInfoNodeItem)
cyberspaceItems.set(1, newInterpreterLeaf(cyberRestorative))
cyberspaceItems.set(2, newInterpreterLeaf(cyberDefenseMine))
cyberspaceItems.set(3, newInterpreterLeaf(securityIDModuleItem))
cyberspaceItems.set(6, infoNodes)
cyberspaceItems.set(8, infoNodes)
cyberspaceItems.set(9, newInterpreterLeaf(cyberBarricade))
class := newInterpreterEntry(baseItem)
class.set(5, cyberspaceItems)
return class
}
@@ -0,0 +1,73 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseSoftware = interpreters.New()
var multimediaFile = baseSoftware.
With("ID", 1, 1).As(interpreters.Bitfield(map[uint32]string{0x0F: "Index", 0xF0: "Level"})).
With("Type", 2, 1).As(interpreters.EnumValue(map[uint32]string{0: "E-Mail", 1: "Log", 2: "Data"}))
var cyberspaceProgram = baseSoftware.
With("Version", 0, 1).As(interpreters.RangedValue(1, 9))
var funPack = baseSoftware.
With("GameMask", 0, 1).As(interpreters.EnumValue(map[uint32]string{
0x01: "Ping",
0x02: "Eel Zapper",
0x04: "Road",
0x08: "Botbounce",
0x10: "15",
0x20: "TriopToe",
0x80: "Wing 0"}))
var baseCyberspaceScenery = interpreters.New()
var scenerySoftware = baseCyberspaceScenery.
Refining("FunPack", 0, 2, funPack,
func(inst *interpreters.Instance) bool {
return (inst.Get("Subclass") == 3) && (inst.Get("Type") == 0)
}).
Refining("Program", 0, 2, cyberspaceProgram,
func(inst *interpreters.Instance) bool {
return (inst.Get("Subclass") == 0) || (inst.Get("Subclass") == 1)
}).
With("Subclass", 2, 4).As(interpreters.RangedValue(0, 7)).
With("Type", 6, 4).As(interpreters.RangedValue(0, 16))
func initSoftware() interpreterRetriever {
cyberspacePrograms := newInterpreterLeaf(cyberspaceProgram)
realWorldTools := newInterpreterEntry(baseSoftware)
realWorldTools.set(0, newInterpreterLeaf(funPack))
multimediaSoftware := newInterpreterEntry(baseSoftware)
multimediaSoftware.set(0, newInterpreterLeaf(multimediaFile)) // text
multimediaSoftware.set(1, newInterpreterLeaf(multimediaFile)) // email
class := newInterpreterEntry(baseSoftware)
class.set(0, cyberspacePrograms) // aggressive programs
class.set(1, cyberspacePrograms) // defensive programs
class.set(3, realWorldTools)
class.set(4, multimediaSoftware)
return class
}
func initCyberspaceBigStuff() interpreterRetriever {
cyberspaceScenery := newInterpreterEntry(scenerySoftware)
cyberspaceScenerySubclass2 := newInterpreterEntry(baseCyberspaceScenery)
cyberspaceScenerySubclass2.set(0, cyberspaceScenery) // "SIGN"
cyberspaceScenerySubclass3 := newInterpreterEntry(baseCyberspaceScenery)
cyberspaceScenerySubclass3.set(2, cyberspaceScenery) // "GLOW BULB"
class := newInterpreterEntry(scenerySoftware)
class.set(2, cyberspaceScenerySubclass2)
class.set(3, cyberspaceScenerySubclass3)
return class
}
@@ -0,0 +1,82 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/archive/level/lvlobj/actions"
"github.com/inkyblackness/hacked/ss1/content/archive/level/lvlobj/conditions"
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var baseTraps = interpreters.New()
var repulsor = baseTraps.
With("Ignored0000", 0, 1).As(interpreters.SpecialValue("Ignored")).
With("StartHeightFraction", 10, 2).As(interpreters.RangedValue(0, 65536)).
With("StartHeight", 12, 2).As(interpreters.RangedValue(0, 31)).
With("EndHeightFraction", 14, 2).As(interpreters.RangedValue(0, 65536)).
With("EndHeight", 16, 2).As(interpreters.RangedValue(0, 32)).
With("Flags", 18, 4).As(interpreters.Bitfield(map[uint32]string{0x00000001: "Disabled", 0x00000008: "Strong"}))
var aiHint = baseTraps.
With("Ignored0000", 0, 1).As(interpreters.SpecialValue("Ignored")).
With("NextObjectID", 6, 2).As(interpreters.ObjectID()).
With("TriggerObjectFlag", 18, 2).As(interpreters.EnumValue(map[uint32]string{0: "Off", 1: "On"})).
With("TriggerObjectID", 20, 2).As(interpreters.ObjectID())
var baseTrigger = baseTraps.
Refining("Action", 0, 22, actions.Unconditional(), interpreters.Always)
var gameVariableTrigger = baseTrigger.
Refining("Condition", 2, 4, conditions.GameVariable(), interpreters.Always)
var puzzleData = interpreters.New()
var nullTrigger = baseTraps.
Refining("Action", 0, 22, actions.Unconditional().
Refining("PuzzleData", 6, 16, puzzleData, func(inst *interpreters.Instance) bool { return inst.Get("Type") == 0 }),
interpreters.Always).
Refining("Condition", 2, 4, conditions.GameVariable(), interpreters.Always)
var deathWatchTrigger = baseTrigger.
With("ConditionType", 5, 1).As(interpreters.EnumValue(map[uint32]string{0: "Object Type", 1: "Object ID"})).
Refining("TypeCondition", 2, 4, conditions.ObjectType(), func(inst *interpreters.Instance) bool {
return inst.Get("ConditionType") == 0
}).
Refining("IndexCondition", 2, 4, conditions.ObjectID(), func(inst *interpreters.Instance) bool {
return inst.Get("ConditionType") == 1
})
var ecologyTrigger = baseTrigger.
Refining("TypeCondition", 2, 4, conditions.ObjectType(), interpreters.Always).
With("ConditionLimit", 5, 1)
var mapNote = baseTraps.
With("EntryOffset", 18, 4)
var musicVoodoo = baseTraps.
With("MusicFlavour", 6, 1).As(interpreters.RangedValue(0, 4))
func initTraps() interpreterRetriever {
gameVariableTriggers := newInterpreterLeaf(gameVariableTrigger)
trigger := newInterpreterEntry(baseTraps)
trigger.set(0, gameVariableTriggers) // tile entry trigger
trigger.set(1, newInterpreterLeaf(nullTrigger))
trigger.set(2, gameVariableTriggers) // floor trigger
trigger.set(3, gameVariableTriggers) // player death trigger
trigger.set(4, newInterpreterLeaf(deathWatchTrigger))
trigger.set(7, newInterpreterLeaf(aiHint))
trigger.set(8, gameVariableTriggers) // level entry trigger
trigger.set(10, newInterpreterLeaf(repulsor))
trigger.set(11, newInterpreterLeaf(ecologyTrigger))
trigger.set(12, gameVariableTriggers) // shodan trigger
mapMarker := newInterpreterEntry(baseTraps)
mapMarker.set(3, newInterpreterLeaf(mapNote))
mapMarker.set(4, newInterpreterLeaf(musicVoodoo))
class := newInterpreterEntry(baseTraps)
class.set(0, trigger)
class.set(2, mapMarker)
return class
}
@@ -0,0 +1,358 @@
package actions
import (
"fmt"
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
func forType(typeID int) func(*interpreters.Instance) bool {
return func(inst *interpreters.Instance) bool {
return inst.Get("Type") == uint32(typeID)
}
}
var transportHackerDetails = interpreters.New().
With("TargetX", 0, 4).As(interpreters.RangedValue(1, 63)).
With("TargetY", 4, 4).As(interpreters.RangedValue(1, 63)).
With("TargetZ", 8, 1).As(interpreters.RangedValue(0, 255)).
With("PreserveHeight", 9, 1).As(interpreters.EnumValue(map[uint32]string{0: "No", 0x40: "Yes"})).
With("CrossLevelTransportDestination", 12, 1).As(interpreters.RangedValue(0, 15)).
With("CrossLevelTransportFlag", 13, 1).As(interpreters.EnumValue(map[uint32]string{
0x00: "Cross-Level", 0x10: "Same-Level (0x10)", 0x20: "Same-Level (0x20)", 0x22: "Same-Level (0x22)"}))
var changeHealthDetails = interpreters.New().
With("HealthDelta", 4, 1).
With("HealthChangeFlag", 6, 2).As(interpreters.EnumValue(map[uint32]string{0: "Remove Delta", 1: "Add Delta"})).
With("PowerDelta", 8, 1).
With("PowerChangeFlag", 10, 2).As(interpreters.EnumValue(map[uint32]string{0: "Remove Delta", 1: "Add Delta"})).
With("FatigueDelta", 12, 2).As(interpreters.RangedValue(0, 255)).
With("FatigueChangeFlag", 14, 2).As(interpreters.EnumValue(map[uint32]string{0: "Add Delta", 1: "Remove Delta"}))
var cloneMoveObjectDetails = interpreters.New().
With("ObjectID", 0, 2).As(interpreters.ObjectID()).
With("MoveFlag", 2, 2).As(interpreters.EnumValue(map[uint32]string{
0x0000: "Clone Object",
0x0001: "Move Object (0x0001)",
0x0002: "Move Object (0x0002)",
0x0FFF: "Move Object (0x0FFF)",
0xAAAA: "Move Object (0xAAAA)",
0xFFFF: "Move Object (0xFFFF)"})).
With("TargetX", 4, 4).As(interpreters.RangedValue(1, 63)).
With("TargetY", 8, 4).As(interpreters.RangedValue(1, 63)).
With("TargetHeight", 12, 1).As(interpreters.SpecialValue("ObjectHeight")).
With("KeepSourceHeight", 13, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "Set height", 0x40: "Keep height"}))
var setGameVariableDetails = interpreters.New().
With("VariableKey", 0, 4).As(interpreters.SpecialValue("VariableKey")).
With("Value", 4, 2).
With("Operation", 6, 2).As(interpreters.EnumValue(map[uint32]string{0: "Set", 1: "Add", 2: "Subtract", 3: "Multiply", 4: "Divide", 5: "Modulo"})).
With("Message1", 8, 4).As(interpreters.RangedValue(0, 511)).
With("Message2", 12, 4).As(interpreters.RangedValue(0, 511))
var showCutsceneDetails = interpreters.New().
With("CutsceneIndex", 0, 4).As(interpreters.EnumValue(map[uint32]string{0: "Death", 1: "Intro", 2: "Ending"})).
With("EndGameFlag", 4, 4).As(interpreters.EnumValue(map[uint32]string{0: "No (not working)", 1: "Yes"}))
func pointOneSecond(value int) string {
return fmt.Sprintf("%.1f sec", float64(value)*0.1)
}
var triggerOtherObjectsDetails = interpreters.New().
With("Object1ID", 0, 2).As(interpreters.ObjectID()).
With("Object1Delay", 2, 2).As(interpreters.FormattedRangedValue(0, 6000, pointOneSecond)).
With("Object2ID", 4, 2).As(interpreters.ObjectID()).
With("Object2Delay", 6, 2).As(interpreters.FormattedRangedValue(0, 6000, pointOneSecond)).
With("Object3ID", 8, 2).As(interpreters.ObjectID()).
With("Object3Delay", 10, 2).As(interpreters.FormattedRangedValue(0, 6000, pointOneSecond)).
With("Object4ID", 12, 2).As(interpreters.ObjectID()).
With("Object4Delay", 14, 2).As(interpreters.FormattedRangedValue(0, 6000, pointOneSecond))
var changeLightingDetails = interpreters.New().
Refining("ObjectExtent", 0, 2, interpreters.New().With("Index", 0, 2).As(interpreters.ObjectID()), func(inst *interpreters.Instance) bool {
var lightType = inst.Get("LightType")
return (lightType == 0x00) || (lightType == 0x01)
}).
Refining("RadiusExtent", 0, 2, interpreters.New().With("Tiles", 0, 2).As(interpreters.RangedValue(0, 31)), func(inst *interpreters.Instance) bool {
return inst.Get("LightType") == 0x03
}).
With("ReferenceObjectID", 2, 2).As(interpreters.ObjectID()).
With("TransitionType", 4, 2).As(interpreters.EnumValue(map[uint32]string{0x0000: "immediate", 0x0001: "fade", 0x0100: "flicker"})).
With("LightModification", 7, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "light on", 0x10: "light off"})).
With("LightType", 8, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "rectangular", 0x03: "circular gradient"})).
With("LightSurface", 10, 2).As(interpreters.EnumValue(map[uint32]string{0: "floor", 1: "ceiling", 2: "floor and ceiling"})).
Refining("Rectangular", 12, 2, interpreters.New().
With("Off light value", 0, 1).As(interpreters.RangedValue(0, 15)).
With("On light value", 1, 1).As(interpreters.RangedValue(0, 15)), func(inst *interpreters.Instance) bool {
return inst.Get("LightType") == 0x00
}).
Refining("Gradient", 12, 4, interpreters.New().
With("Off light begin intensity", 0, 1).As(interpreters.RangedValue(0, 127)).
With("Off light end intensity", 1, 1).As(interpreters.RangedValue(0, 127)).
With("On light begin intensity", 2, 1).As(interpreters.RangedValue(0, 127)).
With("On light end intensity", 3, 1).As(interpreters.RangedValue(0, 127)), func(inst *interpreters.Instance) bool {
var lightType = inst.Get("LightType")
return (lightType == 0x01) || (lightType == 0x03)
})
var effectDetails = interpreters.New().
With("SoundIndex", 0, 2).As(interpreters.RangedValue(0, 512)).
With("SoundPlayCount", 2, 2).As(interpreters.RangedValue(0, 100)).
With("VisualEffect", 4, 2).As(interpreters.EnumValue(map[uint32]string{
0: "none",
1: "power on",
2: "quake",
3: "escape pod",
4: "red static",
5: "interference"})).
With("AdditionalVisualEffect", 8, 2).As(interpreters.EnumValue(map[uint32]string{
0: "none",
1: "white flash",
2: "pink flash",
3: "gray static",
4: "vertical panning"})).
With("AdditionalEffectTime", 12, 2).As(interpreters.RangedValue(0, 1000))
var changeTileHeightsDetails = interpreters.New().
With("TileX", 0, 4).As(interpreters.RangedValue(1, 63)).
With("TileY", 4, 4).As(interpreters.RangedValue(1, 63)).
With("TargetFloorHeight", 8, 2).As(interpreters.SpecialValue("MoveTileHeight")).
With("TargetCeilingHeight", 10, 2).As(interpreters.SpecialValue("MoveTileHeight")).
With("FloorSound", 14, 2).As(interpreters.EnumValue(map[uint32]string{0x0000: "Audible", 0x0001: "Silent"}))
var changeTerrainDetails = interpreters.New().
With("TileX", 0, 4).As(interpreters.RangedValue(1, 63)).
With("TileY", 4, 4).As(interpreters.RangedValue(1, 63)).
With("Type", 8, 1).As(interpreters.SpecialValue("TileType")).
With("TypeControl", 9, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "Set type", 0x40: "Keep type"})).
With("SlopeHeight", 12, 1).As(interpreters.SpecialValue("TileHeight")).
With("SlopeControl", 13, 1).As(interpreters.EnumValue(map[uint32]string{0x00: "Set height", 0x40: "Keep height"}))
var scheduledTrapDetails = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("TimeInterval", 4, 4).As(interpreters.FormattedRangedValue(0, 6000, pointOneSecond)).
With("ActivationValue", 8, 4).As(interpreters.EnumValue(map[uint32]string{0: "Off",
0xFFFF: "On (0xFFFF)", 0x10000: "On (0x10000)", 0x11111: "On (0x11111)"})).
With("Variance", 12, 2).As(interpreters.RangedValue(0, 512))
var cycleObjectsDetails = interpreters.New().
With("ObjectID1", 0, 4).As(interpreters.ObjectID()).
With("ObjectID2", 4, 4).As(interpreters.ObjectID()).
With("ObjectID3", 8, 4).As(interpreters.ObjectID()).
With("NextObject", 12, 4).As(interpreters.RangedValue(0, 2))
var deleteObjectsDetails = interpreters.New().
With("ObjectID1", 0, 2).As(interpreters.ObjectID()).
With("ObjectID2", 4, 2).As(interpreters.ObjectID()).
With("ObjectID3", 8, 2).As(interpreters.ObjectID()).
With("MessageIndex", 12, 2).As(interpreters.RangedValue(0, 511))
var receiveEmailDetails = interpreters.New().
With("EmailIndex", 0, 2).As(interpreters.RangedValue(0, 1000)).
With("DelaySec", 4, 2).As(interpreters.RangedValue(0, 600))
var exposeDetails = interpreters.New().
With("DeltaValue", 0, 2).As(interpreters.RangedValue(0, 1000)).
With("EffectChangeFlag", 2, 2).As(interpreters.EnumValue(map[uint32]string{0: "Add Delta", 1: "Remove Delta"})).
With("EffectType", 4, 4).As(interpreters.EnumValue(map[uint32]string{4: "Radiation poisoning", 8: "Bio contamination"}))
var setObjectParameterDetails = interpreters.New().
With("ObjectID1", 0, 2).As(interpreters.ObjectID()).
With("ObjectID2", 2, 2).As(interpreters.ObjectID()).
With("Value1", 4, 4).
With("Value2", 8, 4).
With("Value3", 12, 4)
var setScreenPictureDetails = interpreters.New().
With("ScreenObjectID1", 0, 2).As(interpreters.ObjectID()).
With("ScreenObjectID2", 2, 2).As(interpreters.ObjectID()).
With("SingleSequenceSource", 4, 4).
With("LoopSequenceSource", 8, 4)
var setCritterStateDetails = interpreters.New().
With("ReferenceObjectID1", 4, 2).As(interpreters.ObjectID()).
With("ReferenceObjectID2", 6, 2).As(interpreters.ObjectID()).
With("NewState", 8, 1).As(interpreters.EnumValue(map[uint32]string{
0: "docile",
1: "cautious",
2: "hostile",
3: "cautious (?)",
4: "attacking",
5: "sleeping",
6: "tranquilized",
7: "confused"}))
var trapMessageDetails = interpreters.New().
With("BackgroundImageIndex", 0, 4).As(interpreters.RangedValue(-2, 500)).
With("MessageIndex", 4, 4).As(interpreters.RangedValue(0, 511)).
With("TextColor", 8, 4).As(interpreters.RangedValue(0, 255)).
With("MfdSuppressionFlag", 12, 4).As(interpreters.EnumValue(map[uint32]string{0: "Show in MFD", 1: "Show only in HUD"}))
var spawnObjectsDetails = interpreters.New().
With("ObjectType", 0, 4).As(interpreters.SpecialValue("ObjectTriple")).
With("ReferenceObject1ID", 4, 2).As(interpreters.ObjectID()).
With("ReferenceObject2ID", 6, 2).As(interpreters.ObjectID()).
With("NumberOfObjects", 8, 4).As(interpreters.RangedValue(0, 100)).
With("Flags", 12, 1).As(interpreters.Bitfield(map[uint32]string{
0x00000001: "Avoid spawn within 7 tiles",
0x00000002: "Avoid spawn in close view",
0x00000004: "Avoid spawn in elevator music",
0x00000008: "Force spawn in occupied/close tiles"}))
var changeObjectTypeDetails = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("NewType", 4, 2).As(interpreters.RangedValue(0, 16)).
With("ResetMask", 6, 2).As(interpreters.RangedValue(0, 15))
// Change state block
var toggleRepulsorChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("OffTextureIndex", 4, 1).As(interpreters.SpecialValue("LevelTexture")).
With("OnTextureIndex", 5, 1).As(interpreters.SpecialValue("LevelTexture")).
With("ToggleType", 8, 1).As(interpreters.EnumValue(map[uint32]string{0: "Toggle On/Off", 1: "Toggle On, Stay On", 2: "Toggle Off, Stay Off"}))
var showGameCodeDigitChange = interpreters.New().
With("ScreenObjectID", 0, 4).As(interpreters.ObjectID()).
With("DigitNumber", 4, 4).As(interpreters.RangedValue(1, 6))
var setParameterFromVariableChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("ParameterNumber", 4, 4).As(interpreters.RangedValue(0, 16)).
With("VariableIndex", 8, 4).As(interpreters.SpecialValue("VariableKey"))
var setFrameStateChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("NewState", 4, 4).As(interpreters.EnumValue(map[uint32]string{0: "Off", 1: "On"}))
var doorControlChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("ControlValue", 4, 4).As(interpreters.EnumValue(map[uint32]string{1: "open door", 2: "close door", 3: "toggle door", 4: "disable auto-close"}))
var rotateObjectChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("Amount", 4, 1).As(interpreters.RangedValue(0, 255)).
With("RotationType", 5, 1).As(interpreters.EnumValue(map[uint32]string{0: "Endless", 1: "Back and forth"})).
With("Direction", 6, 1).As(interpreters.EnumValue(map[uint32]string{0: "Forward", 1: "Backward"})).
With("Axis", 7, 1).As(interpreters.EnumValue(map[uint32]string{0: "Z (Yaw)", 1: "X (Pitch)", 2: "Y (Roll)"})).
With("ForwardLimit", 8, 1).As(interpreters.RangedValue(0, 255)).
With("BackwardLimit", 9, 1).As(interpreters.RangedValue(0, 255))
var removeObjectsChange = interpreters.New().
With("ObjectType", 0, 4).As(interpreters.SpecialValue("ObjectTriple")).
With("Radius", 4, 1).As(interpreters.RangedValue(0, 255))
var setConditionChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("Condition", 4, 4)
var makeItemRadioactiveChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID()).
With("WatchedObjectID", 4, 2).As(interpreters.ObjectID()).
With("WatchedObjectTriggerState", 6, 2)
var orientedTriggerObjectChange = interpreters.New().
With("HorizontalDirection", 0, 2).As(interpreters.RangedValue(0, 0xFFFF)).
With("ObjectID", 4, 2).As(interpreters.ObjectID())
var closeDataMfdChange = interpreters.New().
With("ObjectID", 0, 4).As(interpreters.ObjectID())
var changeObjectTypeGlobalChange = interpreters.New().
With("ObjectType", 0, 4).As(interpreters.SpecialValue("ObjectTriple")).
With("NewType", 4, 1).As(interpreters.RangedValue(0, 16))
var hackDetails = interpreters.New().
With("Type", 0, 4).As(interpreters.EnumValue(map[uint32]string{
1: "Toggle Repulsor",
2: "Show Game Code Digit",
3: "Set Parameter from Variable",
4: "Set Button State",
5: "Door Control",
6: "Return to Menu",
7: "Rotate Objects",
8: "Remove Objects",
9: "SHODAN Pixelation",
10: "Set Condition",
11: "Show System Analyzer",
12: "Make Item Radioactive",
13: "Oriented Trigger Object",
14: "Close Data MFD",
15: "Earth Destruction by Laser",
16: "Change Objects Type (Level)"})).
Refining("ToggleRepulsor", 4, 12, toggleRepulsorChange, forType(1)).
Refining("ShowGameCodeDigit", 4, 12, showGameCodeDigitChange, forType(2)).
Refining("SetParameterFromVariable", 4, 12, setParameterFromVariableChange, forType(3)).
Refining("SetFrameState", 4, 12, setFrameStateChange, forType(4)).
Refining("DoorControl", 4, 12, doorControlChange, forType(5)).
Refining("ReturnToMenu", 4, 12, interpreters.New(), forType(6)).
Refining("RotateObject", 4, 12, rotateObjectChange, forType(7)).
Refining("RemoveObjects", 4, 12, removeObjectsChange, forType(8)).
Refining("ShodanPixelation", 4, 12, interpreters.New(), forType(9)).
Refining("SetCondition", 4, 12, setConditionChange, forType(10)).
Refining("ShowSystemAnalyzer", 4, 12, interpreters.New(), forType(11)).
Refining("MakeItemRadioactive", 4, 12, makeItemRadioactiveChange, forType(12)).
Refining("OrientedTriggerObject", 4, 12, orientedTriggerObjectChange, forType(13)).
Refining("CloseDataMfd", 4, 12, closeDataMfdChange, forType(14)).
Refining("EarthDestructionByLaser", 4, 12, interpreters.New(), forType(15)).
Refining("ChangeObjectsType", 4, 12, changeObjectTypeGlobalChange, forType(16))
var unconditionalAction = interpreters.New().
With("Type", 0, 1).As(interpreters.EnumValue(map[uint32]string{
0: "Nothing",
1: "Transport Hacker",
2: "Change Health",
3: "Clone/Move Object",
4: "Set Game Variable",
5: "Show Cutscene",
6: "Trigger Other Objects",
7: "Change Lighting",
8: "Effect",
9: "Change Tile Heights",
10: "Change Terrain",
11: "Random Timer",
12: "Cycle Objects",
13: "Delete Objects",
14: "Unknown (14)",
15: "Receive E-Mail",
16: "Change Effect",
17: "Set Object Parameter",
18: "Set Screen Picture",
19: "Change State",
20: "Unknown (20)",
21: "Set Critter State",
22: "Trap Message",
23: "Spawn Objects",
24: "Change Object Type"})).
With("UsageQuota", 1, 1).
Refining("TransportHacker", 6, 16, transportHackerDetails, forType(1)).
Refining("ChangeHealth", 6, 16, changeHealthDetails, forType(2)).
Refining("CloneMoveObject", 6, 16, cloneMoveObjectDetails, forType(3)).
Refining("SetGameVariable", 6, 16, setGameVariableDetails, forType(4)).
Refining("ShowCutscene", 6, 16, showCutsceneDetails, forType(5)).
Refining("TriggerOtherObjects", 6, 16, triggerOtherObjectsDetails, forType(6)).
Refining("ChangeLighting", 6, 16, changeLightingDetails, forType(7)).
Refining("Effect", 6, 16, effectDetails, forType(8)).
Refining("ChangeTileHeights", 6, 16, changeTileHeightsDetails, forType(9)).
Refining("ChangeTerrain", 6, 16, changeTerrainDetails, forType(10)).
Refining("ScheduledTrap", 6, 16, scheduledTrapDetails, forType(11)).
Refining("CycleObjects", 6, 16, cycleObjectsDetails, forType(12)).
Refining("DeleteObjects", 6, 16, deleteObjectsDetails, forType(13)).
// 14 unused
Refining("ReceiveEmail", 6, 16, receiveEmailDetails, forType(15)).
Refining("Expose", 6, 16, exposeDetails, forType(16)).
Refining("SetObjectParameter", 6, 16, setObjectParameterDetails, forType(17)).
Refining("SetScreenPicture", 6, 16, setScreenPictureDetails, forType(18)).
Refining("Hack", 6, 16, hackDetails, forType(19)).
// 20 unknown
Refining("SetCritterState", 6, 16, setCritterStateDetails, forType(21)).
Refining("TrapMessage", 6, 16, trapMessageDetails, forType(22)).
Refining("SpawnObjects", 6, 16, spawnObjectsDetails, forType(23)).
Refining("ChangeObjectType", 6, 16, changeObjectTypeDetails, forType(24))
// Unconditional returns the description of actions without a condition.
func Unconditional() *interpreters.Description {
return unconditionalAction
}
@@ -0,0 +1,15 @@
package conditions
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var gameVariable = interpreters.New().
With("VariableKey", 0, 2).As(interpreters.SpecialValue("VariableCondition")).
With("Value", 2, 1).
With("MessageIndex", 3, 1)
// GameVariable returns the description for a game variable condition.
func GameVariable() *interpreters.Description {
return gameVariable
}
@@ -0,0 +1,21 @@
package conditions
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
)
var objectType = interpreters.New().
With("ObjectType", 0, 3).As(interpreters.SpecialValue("ObjectTriple"))
var objectID = interpreters.New().
With("ObjectID", 0, 2).As(interpreters.ObjectID())
// ObjectType returns a condition description for object types.
func ObjectType() *interpreters.Description {
return objectType
}
// ObjectID returns a condition description for object indices.
func ObjectID() *interpreters.Description {
return objectID
}
@@ -0,0 +1,77 @@
package lvlobj
import (
"github.com/inkyblackness/hacked/ss1/content/interpreters"
"github.com/inkyblackness/hacked/ss1/content/object"
)
var realWorldEntries *interpreterEntry
var cyberspaceEntries *interpreterEntry
var realWorldExtras *interpreterEntry
var cyberspaceExtras *interpreterEntry
var extraDefault = interpreters.New().
With("CurrentFrame", 1, 1).
With("TimeRemainder", 2, 1)
var extraIced = interpreters.New().
With("ICE-presence", 1, 1).
With("ICE-level", 3, 1)
var extraIcedFixtures = interpreters.New().
With("PanelName", 0, 1).
With("ICE-presence", 1, 1).
With("ICE-level", 3, 1)
var extraFixtures = interpreters.New().
With("PanelName", 0, 1)
var extraSurfaces = interpreters.New().
With("Index", 1, 1)
func init() {
software := initSoftware()
traps := initTraps()
critters := initCritters()
realWorldEntries = newInterpreterEntry(interpreters.New())
realWorldEntries.set(int(object.ClassGun), initGuns())
realWorldEntries.set(int(object.ClassAmmo), newInterpreterEntry(interpreters.New())) // have no data
realWorldEntries.set(int(object.ClassPhysics), newInterpreterEntry(basePhysics))
realWorldEntries.set(int(object.ClassGrenade), initGrenades())
realWorldEntries.set(int(object.ClassDrug), newInterpreterEntry(interpreters.New())) // have no data
realWorldEntries.set(int(object.ClassHardware), newInterpreterEntry(baseHardware))
realWorldEntries.set(int(object.ClassSoftware), software)
realWorldEntries.set(int(object.ClassBigStuff), initBigStuff())
realWorldEntries.set(int(object.ClassSmallStuff), initSmallStuff())
realWorldEntries.set(int(object.ClassFixture), initFixtures())
realWorldEntries.set(int(object.ClassDoor), initDoors())
realWorldEntries.set(int(object.ClassAnimating), newInterpreterEntry(baseAnimation))
realWorldEntries.set(int(object.ClassTrap), traps)
realWorldEntries.set(int(object.ClassContainer), initContainers())
realWorldEntries.set(int(object.ClassCritter), critters)
cyberspaceEntries = newInterpreterEntry(interpreters.New())
cyberspaceEntries.set(int(object.ClassSoftware), software)
cyberspaceEntries.set(int(object.ClassBigStuff), initCyberspaceBigStuff())
cyberspaceEntries.set(int(object.ClassSmallStuff), initCyberspaceSmallStuff())
cyberspaceEntries.set(int(object.ClassFixture), initCyberspaceFixtures())
cyberspaceEntries.set(int(object.ClassTrap), traps)
cyberspaceEntries.set(int(object.ClassCritter), critters)
realWorldExtras = newInterpreterEntry(extraDefault)
realWorldExtras.set(int(object.ClassFixture), newInterpreterLeaf(extraFixtures))
extraBigStuff := newInterpreterEntry(extraDefault)
simpleSurfaces := newInterpreterLeaf(extraSurfaces)
surfaces := newInterpreterEntry(extraDefault)
surfaces.set(1, simpleSurfaces)
surfaces.set(4, simpleSurfaces)
extraBigStuff.set(2, surfaces)
realWorldExtras.set(int(object.ClassBigStuff), extraBigStuff)
cyberspaceExtras = newInterpreterEntry(interpreters.New())
cyberspaceExtras.set(int(object.ClassSoftware), newInterpreterLeaf(extraIced))
cyberspaceExtras.set(int(object.ClassBigStuff), newInterpreterLeaf(extraIced))
cyberspaceExtras.set(int(object.ClassSmallStuff), newInterpreterLeaf(extraIced))
cyberspaceExtras.set(int(object.ClassFixture), newInterpreterLeaf(extraIcedFixtures))
}