Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"github.com/inkyblackness/hacked/ss1"
|
||||
"github.com/inkyblackness/hacked/ss1/serial"
|
||||
)
|
||||
|
||||
const (
|
||||
errInvalidClass ss1.StringError = "invalid class"
|
||||
errInvalidSubclass ss1.StringError = "invalid subclass"
|
||||
errInvalidType ss1.StringError = "invalid type"
|
||||
)
|
||||
|
||||
// PropertiesTable is a collection of class-specific properties.
|
||||
type PropertiesTable []ClassProperties
|
||||
|
||||
// ClassProperties is a collection of subclass-specific properties.
|
||||
type ClassProperties []SubclassProperties
|
||||
|
||||
// SubclassProperties is a collection of type-specific properties.
|
||||
type SubclassProperties []Properties
|
||||
|
||||
// Properties contains the object-specific properties.
|
||||
type Properties struct {
|
||||
Common CommonProperties
|
||||
Generic []byte
|
||||
Specific []byte
|
||||
}
|
||||
|
||||
// Clone returns a fresh instance with a copy of the data.
|
||||
func (prop Properties) Clone() Properties {
|
||||
cloneBytes := func(in []byte) []byte {
|
||||
out := make([]byte, len(in))
|
||||
copy(out, in)
|
||||
return out
|
||||
}
|
||||
return Properties{
|
||||
Common: prop.Common,
|
||||
Generic: cloneBytes(prop.Generic),
|
||||
Specific: cloneBytes(prop.Specific),
|
||||
}
|
||||
}
|
||||
|
||||
// NewPropertiesTable returns a new instance based on given descriptors.
|
||||
func NewPropertiesTable(desc Descriptors) PropertiesTable {
|
||||
classCount := len(desc)
|
||||
table := make([]ClassProperties, classCount)
|
||||
for class := 0; class < classCount; class++ {
|
||||
classDesc := desc[class]
|
||||
subclassCount := len(classDesc.Subclasses)
|
||||
subclassProperties := make([]SubclassProperties, subclassCount)
|
||||
table[class] = subclassProperties
|
||||
for subclass := 0; subclass < subclassCount; subclass++ {
|
||||
subclassDesc := classDesc.Subclasses[subclass]
|
||||
typeProperties := make([]Properties, subclassDesc.TypeCount)
|
||||
subclassProperties[subclass] = typeProperties
|
||||
for objType := 0; objType < subclassDesc.TypeCount; objType++ {
|
||||
prop := &typeProperties[objType]
|
||||
prop.Generic = make([]byte, classDesc.GenericDataSize)
|
||||
prop.Specific = make([]byte, subclassDesc.SpecificDataSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
// ForObject returns the object-specific properties by given triple.
|
||||
func (table PropertiesTable) ForObject(triple Triple) (*Properties, error) {
|
||||
if int(triple.Class) >= len(table) {
|
||||
return nil, errInvalidClass
|
||||
}
|
||||
classEntry := table[triple.Class]
|
||||
if int(triple.Subclass) >= len(classEntry) {
|
||||
return nil, errInvalidSubclass
|
||||
}
|
||||
subclassEntry := classEntry[triple.Subclass]
|
||||
if int(triple.Type) >= len(subclassEntry) {
|
||||
return nil, errInvalidType
|
||||
}
|
||||
return &subclassEntry[triple.Type], nil
|
||||
}
|
||||
|
||||
// Code serializes the table with given coder.
|
||||
func (table PropertiesTable) Code(coder serial.Coder) {
|
||||
version := propertiesFileVersion
|
||||
coder.Code(&version)
|
||||
for _, subclasses := range table {
|
||||
for _, types := range subclasses {
|
||||
for _, prop := range types {
|
||||
coder.Code(prop.Generic)
|
||||
}
|
||||
}
|
||||
for _, types := range subclasses {
|
||||
for _, prop := range types {
|
||||
coder.Code(prop.Specific)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, subclasses := range table {
|
||||
for _, types := range subclasses {
|
||||
for objType := 0; objType < len(types); objType++ {
|
||||
coder.Code(&types[objType].Common)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TriplesInClass returns all triples that are available in the given class.
|
||||
func (table PropertiesTable) TriplesInClass(class Class) []Triple {
|
||||
var triples []Triple
|
||||
if int(class) < len(table) {
|
||||
subclasses := table[class]
|
||||
for subclass, types := range subclasses {
|
||||
for objType := range types {
|
||||
triples = append(triples, TripleFrom(int(class), subclass, objType))
|
||||
}
|
||||
}
|
||||
}
|
||||
return triples
|
||||
}
|
||||
|
||||
// TripleIndex returns the linear index of the given index.
|
||||
func (table PropertiesTable) TripleIndex(triple Triple) int {
|
||||
if int(triple.Class) >= len(table) {
|
||||
return -1
|
||||
}
|
||||
counter := 0
|
||||
for class := Class(0); class < triple.Class; class++ {
|
||||
subclasses := table[class]
|
||||
for _, types := range subclasses {
|
||||
counter += len(types)
|
||||
}
|
||||
}
|
||||
subclasses := table[triple.Class]
|
||||
if int(triple.Subclass) >= len(subclasses) {
|
||||
return -1
|
||||
}
|
||||
for subclass := Subclass(0); subclass < triple.Subclass; subclass++ {
|
||||
counter += len(subclasses[subclass])
|
||||
}
|
||||
types := subclasses[triple.Subclass]
|
||||
if int(triple.Type) >= len(types) {
|
||||
return -1
|
||||
}
|
||||
return counter + int(triple.Type)
|
||||
}
|
||||
|
||||
// Iterate walks through all types sequentially and gives the properties to the given consumer.
|
||||
// The iteration stops when the consumer returns false or the table has been exhausted.
|
||||
func (table PropertiesTable) Iterate(consumer func(Triple, *Properties) bool) {
|
||||
for class, subclasses := range table {
|
||||
for subclass, types := range subclasses {
|
||||
for objType := 0; objType < len(types); objType++ {
|
||||
if !consumer(TripleFrom(class, subclass, objType), &types[objType]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user