fix(codegen): Adds codegen for embedded objects and timer fields (#686)

* Adds code genning for embedded objects. See `AquariumState` as an example.
* Adds code genning for fields that are `Timer`. See `Aquarium` as an example.
* Codegens aquariums
* Fixes missing option for most primitive field types.
This commit is contained in:
Kamron Batman 2021-08-16 14:48:18 -07:00 committed by GitHub
parent 4c265562bb
commit 1323162628
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
126 changed files with 1287 additions and 1129 deletions

View file

@ -39,6 +39,7 @@ namespace SerializationGenerator
var jsonOptions = SerializableMigrationSchema.GetJsonSerializerOptions();
// List of types that _will_ become ISerializable
var serializableList = receiver.SerializableList;
var embeddedSerializableList = receiver.EmbeddedSerializableList;
foreach (var (classSymbol, (serializableAttr, fieldsList)) in receiver.ClassAndFields)
{
@ -50,9 +51,34 @@ namespace SerializationGenerator
string classSource = context.GenerateSerializationPartialClass(
classSymbol,
serializableAttr,
false,
fieldsList.ToImmutableArray(),
jsonOptions,
serializableList
serializableList,
embeddedSerializableList
);
if (classSource != null)
{
context.AddSource($"{classSymbol.ToDisplayString()}.Serialization.cs", SourceText.From(classSource, Encoding.UTF8));
}
}
foreach (var (classSymbol, (embeddedSerializableAttr, fieldsList)) in receiver.EmbeddedClassAndFields)
{
if (embeddedSerializableAttr == null)
{
continue;
}
string classSource = context.GenerateSerializationPartialClass(
classSymbol,
embeddedSerializableAttr,
true,
fieldsList.ToImmutableArray(),
jsonOptions,
serializableList,
embeddedSerializableList
);
if (classSource != null)

View file

@ -30,9 +30,11 @@ namespace SerializationGenerator
this GeneratorExecutionContext context,
INamedTypeSymbol classSymbol,
AttributeData serializableAttr,
bool embedded,
ImmutableArray<ISymbol> fieldsAndProperties,
JsonSerializerOptions jsonSerializerOptions,
ImmutableArray<INamedTypeSymbol> serializableTypes
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
)
{
var version = (int)serializableAttr.ConstructorArguments[0].Value!;
@ -47,10 +49,12 @@ namespace SerializationGenerator
classSymbol,
serializableAttr,
null, // Do not generate schema
embedded,
null,
migrations.ToImmutableArray(),
fieldsAndProperties,
serializableTypes
serializableTypes,
embeddedSerializableTypes
);
}
@ -59,9 +63,11 @@ namespace SerializationGenerator
INamedTypeSymbol classSymbol,
AttributeData serializableAttr,
string? migrationPath,
bool embedded,
JsonSerializerOptions? jsonSerializerOptions,
ImmutableArray<ISymbol> fieldsAndProperties,
ImmutableArray<INamedTypeSymbol> serializableTypes
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
)
{
var version = (int)serializableAttr.ConstructorArguments[0].Value!;
@ -77,10 +83,12 @@ namespace SerializationGenerator
classSymbol,
serializableAttr,
migrationPath,
embedded,
jsonSerializerOptions,
migrations.ToImmutableArray(),
fieldsAndProperties,
serializableTypes
serializableTypes,
embeddedSerializableTypes
);
}
@ -89,22 +97,27 @@ namespace SerializationGenerator
INamedTypeSymbol classSymbol,
AttributeData serializableAttr,
string? migrationPath,
bool embedded,
JsonSerializerOptions? jsonSerializerOptions,
ImmutableArray<SerializableMetadata> migrations,
ImmutableArray<ISymbol> fieldsAndProperties,
ImmutableArray<INamedTypeSymbol> serializableTypes
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes
)
{
var serializableFieldAttribute =
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
var serializableFieldAttrAttribute =
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTR_ATTRIBUTE);
var serializableInterface = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
var serializableInterface =
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_INTERFACE);
var parentSerializableAttribute =
compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
// If we have a parent that is or derives from ISerializable, then we are in override
var isOverride = classSymbol.BaseType.ContainsInterface(serializableInterface);
if (!isOverride && !classSymbol.ContainsInterface(serializableInterface))
if (!(embedded || isOverride || classSymbol.ContainsInterface(serializableInterface)))
{
return null;
}
@ -120,10 +133,7 @@ namespace SerializationGenerator
source.AppendLine("#pragma warning disable\n");
source.GenerateNamespaceStart(namespaceName);
source.GenerateClassStart(
className,
ImmutableArray<ITypeSymbol>.Empty
);
source.GenerateClassStart(className, ImmutableArray<ITypeSymbol>.Empty);
const string indent = " ";
@ -136,6 +146,14 @@ namespace SerializationGenerator
);
source.AppendLine();
var parentFieldOrProperty = embedded ? fieldsAndProperties.FirstOrDefault(
fieldOrPropertySymbol => fieldOrPropertySymbol.GetAttributes()
.FirstOrDefault(
attr =>
SymbolEqualityComparer.Default.Equals(attr.AttributeClass, parentSerializableAttribute)
) != null
) : null;
var serializablePropertySet = new SortedSet<SerializableProperty>(new SerializablePropertyComparer());
foreach (var fieldOrPropertySymbol in fieldsAndProperties)
@ -193,7 +211,8 @@ namespace SerializationGenerator
fieldSymbol,
getterAccessor,
setterAccessor,
virtualProperty
virtualProperty,
parentFieldOrProperty
);
source.AppendLine();
}
@ -204,6 +223,7 @@ namespace SerializationGenerator
order,
allAttributes,
serializableTypes,
embeddedSerializableTypes,
classSymbol
);
@ -213,7 +233,7 @@ namespace SerializationGenerator
var serializableProperties = serializablePropertySet.ToImmutableArray();
// If we are not inheriting ISerializable, then we need to define some stuff
if (!isOverride)
if (!(isOverride || embedded))
{
// long ISerializable.SavePosition { get; set; } = -1;
source.GenerateAutoProperty(
@ -237,9 +257,12 @@ namespace SerializationGenerator
);
}
// Serial constructor
source.GenerateSerialCtor(compilation, className, isOverride);
source.AppendLine();
if (!embedded)
{
// Serial constructor
source.GenerateSerialCtor(compilation, className, isOverride);
source.AppendLine();
}
if (version > 0)
{
@ -271,7 +294,8 @@ namespace SerializationGenerator
version,
encodedVersion,
migrations,
serializableProperties
serializableProperties,
parentFieldOrProperty
);
source.GenerateClassEnd();

View file

@ -31,7 +31,8 @@ namespace SerializationGenerator
int version,
bool encodedVersion,
ImmutableArray<SerializableMetadata> migrations,
ImmutableArray<SerializableProperty> properties
ImmutableArray<SerializableProperty> properties,
ISymbol parentFieldOrProperty
)
{
var genericReaderInterface = compilation.GetTypeByMetadataName(SymbolMetadata.GENERIC_READER_INTERFACE);
@ -74,6 +75,7 @@ namespace SerializationGenerator
if (version > 0)
{
var parent = parentFieldOrProperty?.Name ?? "this";
var nextVersion = 0;
for (var i = 0; i < migrations.Length; i++)
@ -88,7 +90,7 @@ namespace SerializationGenerator
source.AppendLine($"{indent}if (version == {migrationVersion})");
source.AppendLine($"{indent}{{");
source.AppendLine($"{indent} MigrateFrom(new V{migrationVersion}Content(reader));");
source.AppendLine($"{indent} ((Server.ISerializable)this).MarkDirty();");
source.AppendLine($"{indent} {parent}.MarkDirty();");
if (afterDeserialization != null)
{
source.AppendLine($"{indent} Timer.DelayCall({afterDeserialization.Name});");
@ -103,7 +105,7 @@ namespace SerializationGenerator
source.AppendLine($"{indent}if (version < _version)");
source.AppendLine($"{indent}{{");
source.AppendLine($"{indent} Deserialize(reader, version);");
source.AppendLine($"{indent} ((Server.ISerializable)this).MarkDirty();");
source.AppendLine($"{indent} {parent}.MarkDirty();");
if (afterDeserialization != null)
{
source.AppendLine($"{indent} Timer.DelayCall({afterDeserialization.Name});");
@ -116,11 +118,14 @@ namespace SerializationGenerator
foreach (var property in properties)
{
source.AppendLine();
SerializableMigrationRulesEngine.Rules[property.Rule].GenerateDeserializationMethod(
var rule = SerializableMigrationRulesEngine.Rules[property.Rule];
rule.GenerateDeserializationMethod(
source,
indent,
property
);
(rule as IPostDeserializeMethod)?.PostDeserializeMethod(source, indent, property, compilation, classSymbol);
}
if (afterDeserialization != null)

View file

@ -27,7 +27,8 @@ namespace SerializationGenerator
IFieldSymbol fieldSymbol,
Accessibility getter,
Accessibility? setter,
bool isVirtual
bool isVirtual,
ISymbol? parentFieldOrProperty = null
)
{
var fieldName = fieldSymbol.Name;
@ -54,16 +55,18 @@ namespace SerializationGenerator
// Getter
source.GeneratePropertyGetterReturnsField(propertyIndent, fieldSymbol, getterAccessor);
if (setter != null)
if (setter != null && setter != Accessibility.NotApplicable)
{
var setterAccessor = setter == propertyAccessor ? Accessibility.NotApplicable : setter;
var parentSymbol = parentFieldOrProperty?.Name ?? "this";
// Setter
source.GeneratePropertySetterStart(propertyIndent, false, setterAccessor.Value);
source.AppendLine($"{innerIndent}if (value != {fieldName})");
source.AppendLine($"{innerIndent}{{");
source.AppendLine($"{innerIndent} {fieldName} = value;");
source.AppendLine($"{innerIndent} ((ISerializable)this).MarkDirty();");
source.AppendLine($"{innerIndent} {parentSymbol}.MarkDirty();");
if (invalidatePropertiesAttribute != null)
{

View file

@ -0,0 +1,31 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: IPostDeserializeMethod.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System.Text;
using Microsoft.CodeAnalysis;
namespace SerializableMigration
{
public interface IPostDeserializeMethod
{
public void PostDeserializeMethod(
StringBuilder source,
string indent,
SerializableProperty property,
Compilation compilation,
INamedTypeSymbol classSymbol
);
}
}

View file

@ -28,6 +28,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
);

View file

@ -29,6 +29,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -46,6 +47,7 @@ namespace SerializableMigration
0,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
@ -60,7 +62,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(ArrayMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -91,7 +93,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(ArrayMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -0,0 +1,81 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: EmbeddedSerializableMigrationRule.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Immutable;
using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
namespace SerializableMigration
{
public class EmbeddedSerializableMigrationRule : ISerializableMigrationRule
{
public string RuleName => nameof(EmbeddedSerializableMigrationRule);
public bool GenerateRuleState(
Compilation compilation,
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
{
if (symbol is not INamedTypeSymbol namedTypeSymbol)
{
ruleArguments = null;
return false;
}
if (!embeddedSerializableTypes.Contains(namedTypeSymbol))
{
ruleArguments = null;
return false;
}
ruleArguments = new[] { "" };
return true;
}
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
var propertyName = property.Name;
source.AppendLine($"{indent}{propertyName} = new {property.Type}(this);");
source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
}
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
var propertyName = property.Name;
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
}
}
}

View file

@ -30,6 +30,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -46,7 +47,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(EnumMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -58,7 +59,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(EnumMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -31,6 +31,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -50,6 +51,7 @@ namespace SerializableMigration
0,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
@ -71,7 +73,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(HashSetMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -114,7 +116,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(HashSetMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -30,6 +30,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -49,6 +50,7 @@ namespace SerializableMigration
0,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
@ -59,6 +61,7 @@ namespace SerializableMigration
1,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
@ -80,7 +83,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(KeyValuePairMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -134,7 +137,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(KeyValuePairMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -31,6 +31,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -50,6 +51,7 @@ namespace SerializableMigration
0,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
@ -71,7 +73,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(ListMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -115,7 +117,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(ListMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -31,6 +31,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -73,7 +74,7 @@ namespace SerializableMigration
new[] { "DeltaTime" },
SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
new[] { "InternString" },
_ => Array.Empty<string>()
_ => new[] { "" }
};
return true;
@ -81,7 +82,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(PrimitiveTypeMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -124,7 +125,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(PrimitiveTypeMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -30,6 +30,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -50,7 +51,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(PrimitiveUOTypeMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -63,7 +64,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(PrimitiveUOTypeMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -30,6 +30,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -46,7 +47,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(SerializableInterfaceMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -59,7 +60,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(SerializableInterfaceMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -30,6 +30,7 @@ namespace SerializableMigration
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
@ -53,7 +54,7 @@ namespace SerializableMigration
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(SerializationMethodSignatureMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
@ -69,7 +70,7 @@ namespace SerializableMigration
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
const string expectedRule = nameof(SerializationMethodSignatureMigrationRule);
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{

View file

@ -0,0 +1,125 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: TimerMigrationRule.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using SerializationGenerator;
namespace SerializableMigration
{
public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod
{
public string RuleName => nameof(TimerMigrationRule);
public bool GenerateRuleState(
Compilation compilation,
ISymbol symbol,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol,
out string[] ruleArguments
)
{
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
{
ruleArguments = null;
return false;
}
ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
? new[] { "@TimerDrift" }
: new[] { "" };
return true;
}
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
var propertyName = property.Name;
var ruleArguments = property.RuleArguments;
var driftTimer = ruleArguments[0].Contains("@TimerDrift");
var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
source.AppendLine($"{indent}var {propertyName}Delay = {readTimer} - Core.Now;");
}
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
{
var expectedRule = RuleName;
var ruleName = property.Rule;
if (expectedRule != ruleName)
{
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
}
var propertyName = property.Name;
var ruleArguments = property.RuleArguments;
var driftTimer = ruleArguments[0].Contains("@TimerDrift");
var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
source.AppendLine($"{indent}writer.{writerMethod}({propertyName}.Next);");
}
public void PostDeserializeMethod(
StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
)
{
var deserializeTimerMethod = classSymbol
.GetMembers()
.OfType<IMethodSymbol>()
.FirstOrDefault(
m =>
{
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
{
return false;
}
return m.GetAttributes()
.FirstOrDefault(
attr =>
{
if (!SymbolEqualityComparer.Default.Equals(
attr.AttributeClass,
compilation.GetTypeByMetadataName(
SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE
)
))
{
return false;
}
var order = (int)attr.ConstructorArguments[0].Value!;
return order == property.Order;
}
) != null;
}
) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
}
}
}

View file

@ -38,6 +38,8 @@ namespace SerializableMigration
new PrimitiveUOTypeMigrationRule(),
new SerializableInterfaceMigrationRule(),
new SerializationMethodSignatureMigrationRule(),
new EmbeddedSerializableMigrationRule(),
new TimerMigrationRule()
};
foreach (var rule in rules)
@ -52,6 +54,7 @@ namespace SerializableMigration
int order,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol = default
)
{
@ -80,6 +83,7 @@ namespace SerializableMigration
order,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol
);
}
@ -91,6 +95,7 @@ namespace SerializableMigration
int order,
ImmutableArray<AttributeData> attributes,
ImmutableArray<INamedTypeSymbol> serializableTypes,
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
ISymbol? parentSymbol = default
)
{
@ -101,6 +106,7 @@ namespace SerializableMigration
propertyType,
attributes,
serializableTypes,
embeddedSerializableTypes,
parentSymbol,
out var ruleArguments
))

View file

@ -24,10 +24,13 @@ namespace SerializationGenerator
{
#pragma warning disable RS1024
public Dictionary<INamedTypeSymbol, (AttributeData?, List<ISymbol>)> ClassAndFields { get; } = new(SymbolEqualityComparer.Default);
public Dictionary<INamedTypeSymbol, (AttributeData?, List<ISymbol>)> EmbeddedClassAndFields { get; } = new(SymbolEqualityComparer.Default);
#pragma warning restore RS1024
public ImmutableArray<INamedTypeSymbol> SerializableList => ClassAndFields.Keys.ToImmutableArray();
public ImmutableArray<INamedTypeSymbol> EmbeddedSerializableList => EmbeddedClassAndFields.Keys.ToImmutableArray();
public void OnVisitSyntaxNode(SyntaxNode node, SemanticModel semanticModel)
{
var compilation = semanticModel.Compilation;
@ -39,7 +42,19 @@ namespace SerializationGenerator
return;
}
if (classSymbol.WillBeSerializable(compilation, out var attrData))
if (classSymbol.IsEmbeddedSerializable(compilation, out var attrData))
{
if (EmbeddedClassAndFields.TryGetValue(classSymbol, out var value))
{
var (_, fieldsList) = value;
EmbeddedClassAndFields[classSymbol] = (attrData, fieldsList);
}
else
{
EmbeddedClassAndFields.Add(classSymbol, (attrData, new List<ISymbol>()));
}
}
else if (classSymbol.WillBeSerializable(compilation, out attrData))
{
if (ClassAndFields.TryGetValue(classSymbol, out var value))
{
@ -64,8 +79,11 @@ namespace SerializationGenerator
AddFieldOrProperty(fieldSymbol, compilation);
}
}
return;
}
else if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
if (node is PropertyDeclarationSyntax { AttributeLists: { Count: > 0 } } propertyDeclarationSyntax)
{
if (semanticModel.GetDeclaredSymbol(propertyDeclarationSyntax) is IPropertySymbol propertySymbol)
{
@ -80,8 +98,9 @@ namespace SerializationGenerator
private void AddFieldOrProperty(ISymbol symbol, Compilation compilation)
{
var serializableFieldAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_FIELD_ATTRIBUTE);
var parentAttr = compilation.GetTypeByMetadataName(SymbolMetadata.SERIALIZABLE_PARENT_ATTRIBUTE);
if (symbol.GetAttribute(serializableFieldAttr) == null)
if (symbol.GetAttribute(serializableFieldAttr) == null && symbol.GetAttribute(parentAttr) == null)
{
return;
}
@ -94,10 +113,21 @@ namespace SerializationGenerator
return;
}
if (EmbeddedClassAndFields.TryGetValue(classSymbol, out value))
{
var (_, fieldsList) = value;
fieldsList.Add(symbol);
return;
}
if (classSymbol.WillBeSerializable(compilation, out var attrData))
{
ClassAndFields.Add(classSymbol, (attrData, new List<ISymbol> { symbol }));
}
else if (classSymbol.IsEmbeddedSerializable(compilation, out attrData))
{
EmbeddedClassAndFields.Add(classSymbol, (attrData, new List<ISymbol> { symbol }));
}
}
}
}

View file

@ -55,5 +55,11 @@ namespace SerializationGenerator
"private protected" => Accessibility.ProtectedAndInternal,
_ => Accessibility.NotApplicable
};
public static bool CanBeConstructedFrom(this ITypeSymbol? symbol, ISymbol classSymbol) =>
symbol is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.ConstructedFrom.Equals(
classSymbol,
SymbolEqualityComparer.Default
) || symbol != null && CanBeConstructedFrom(symbol.BaseType, classSymbol);
}
}

View file

@ -24,6 +24,8 @@ namespace SerializationGenerator
public const string INVALIDATEPROPERTIES_ATTRIBUTE = "Server.InvalidatePropertiesAttribute";
public const string AFTERDESERIALIZATION_ATTRIBUTE = "Server.AfterDeserializationAttribute";
public const string SERIALIZABLE_ATTRIBUTE = "Server.SerializableAttribute";
public const string EMBEDDED_SERIALIZABLE_ATTRIBUTE = "Server.EmbeddedSerializableAttribute";
public const string SERIALIZABLE_PARENT_ATTRIBUTE = "Server.SerializableParentAttribute";
public const string SERIALIZABLE_FIELD_ATTRIBUTE = "Server.SerializableFieldAttribute";
public const string SERIALIZABLE_FIELD_ATTR_ATTRIBUTE = "Server.SerializableFieldAttrAttribute";
public const string SERIALIZABLE_INTERFACE = "Server.ISerializable";
@ -39,6 +41,15 @@ namespace SerializationGenerator
public const string RECTANGLE3D_STRUCT = "Server.Rectangle3D";
public const string RACE_CLASS = "Server.Race";
public const string MAP_CLASS = "Server.Map";
public const string TIMER_CLASS = "Server.Timer";
public const string TIMER_DRIFT_ATTRIBUTE = "Server.TimerDriftAttribute";
public const string DESERIALIZE_TIMER_FIELD_ATTRIBUTE = "Server.DeserializeTimerFieldAttribute";
public static bool IsTimerDrift(this AttributeData attr, Compilation compilation) =>
attr?.IsAttribute(compilation.GetTypeByMetadataName(TIMER_DRIFT_ATTRIBUTE)) == true;
public static bool IsTimer(this ITypeSymbol symbol, Compilation compilation) =>
symbol.CanBeConstructedFrom(compilation.GetTypeByMetadataName(TIMER_CLASS));
public static bool IsEncodedInt(this AttributeData attr, Compilation compilation) =>
attr?.IsAttribute(compilation.GetTypeByMetadataName(ENCODED_INT_ATTRIBUTE)) == true;
@ -112,6 +123,29 @@ namespace SerializationGenerator
);
}
public static bool HasPublicDeserializeMethod(
this ITypeSymbol symbol,
Compilation compilation,
ImmutableArray<INamedTypeSymbol> serializableTypes
)
{
if (symbol.HasSerializableInterface(compilation, serializableTypes))
{
return true;
}
var genericReaderInterface = compilation.GetTypeByMetadataName(GENERIC_READER_INTERFACE);
return symbol.GetAllMethods("Deserialize")
.Any(
m => !m.IsStatic &&
m.ReturnsVoid &&
m.Parameters.Length == 1 &&
SymbolEqualityComparer.Default.Equals(m.Parameters[0].Type, genericReaderInterface) &&
m.DeclaredAccessibility == Accessibility.Public
);
}
public static bool IsPoint2D(this ISymbol symbol, Compilation compilation) =>
symbol.Equals(
compilation.GetTypeByMetadataName(POINT2D_STRUCT),
@ -171,5 +205,14 @@ namespace SerializationGenerator
attributeData = classSymbol.GetAttribute(serializableEntityAttribute);
return attributeData != null;
}
public static bool IsEmbeddedSerializable(this INamedTypeSymbol classSymbol, Compilation compilation, out AttributeData? attributeData)
{
var embeddedSerializableEntityAttribute =
compilation.GetTypeByMetadataName(EMBEDDED_SERIALIZABLE_ATTRIBUTE);
attributeData = classSymbol.GetAttribute(embeddedSerializableEntityAttribute);
return attributeData != null;
}
}
}

View file

@ -66,6 +66,7 @@ namespace SerializationSchemaGenerator
};
var serializableTypes = syntaxReceiver.SerializableList;
var embeddedSerializableTypes = syntaxReceiver.EmbeddedSerializableList;
foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.ClassAndFields)
{
@ -73,9 +74,25 @@ namespace SerializationSchemaGenerator
classSymbol,
attributeData,
migrationPath,
false,
jsonOptions,
fieldsList.ToImmutableArray(),
serializableTypes
serializableTypes,
embeddedSerializableTypes
);
}
foreach (var (classSymbol, (attributeData, fieldsList)) in syntaxReceiver.EmbeddedClassAndFields)
{
var source = compilation.GenerateSerializationPartialClass(
classSymbol,
attributeData,
migrationPath,
true,
jsonOptions,
fieldsList.ToImmutableArray(),
serializableTypes,
embeddedSerializableTypes
);
}
}

View file

@ -0,0 +1,34 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: DeserializeTimerField.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server
{
/// <summary>
/// Hints to the source generator that the specified serializable field, which must be a timer,
/// can be deserialized by this method. The method signature should look like this:
///
/// [DeserializeTimerField(0)]
/// private void DeserializeTimer(TimeSpan delay)
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public sealed class DeserializeTimerFieldAttribute : Attribute
{
public int Order { get; }
public DeserializeTimerFieldAttribute(int order) => Order = order;
}
}

View file

@ -0,0 +1,32 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: EmbeddedSerializableAttribute.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server
{
[AttributeUsage(AttributeTargets.Class)]
public sealed class EmbeddedSerializableAttribute : Attribute
{
public int Version { get; }
public bool EncodedVersion { get; }
public EmbeddedSerializableAttribute(int version, bool encodedVersion = true)
{
Version = version;
EncodedVersion = encodedVersion;
}
}
}

View file

@ -0,0 +1,30 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: SerializableParentAttribute.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server
{
/// <summary>
/// Hints to the source generator that this field or property indicates the ISerializable parent of this class.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public sealed class SerializableParentAttribute : Attribute
{
public SerializableParentAttribute()
{
}
}
}

View file

@ -0,0 +1,28 @@
/*************************************************************************
* ModernUO *
* Copyright 2019-2021 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: TimerDriftAttribute.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
namespace Server
{
/// <summary>
/// Hints to the source generator that this serializable timer field or property will drift
/// during deserialization.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class TimerDriftAttribute : Attribute
{
}
}

View file

@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
@ -85,6 +86,33 @@ namespace Server
entity.MarkDirty();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Stop(this ISerializable entity, Timer timer)
{
timer?.Stop();
entity.MarkDirty();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Start(this ISerializable entity, Timer timer)
{
timer?.Start();
entity.MarkDirty();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Restart(this ISerializable entity, Timer timer, TimeSpan delay, TimeSpan interval)
{
if (timer != null)
{
timer.Stop();
timer.Delay = delay;
timer.Interval = interval;
timer.Start();
entity.MarkDirty();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Add<T>(this ISerializable entity, ref List<T> list, T value)
{
@ -131,5 +159,13 @@ namespace Server
Utility.Clear(ref dict);
entity.MarkDirty();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Stop(this ISerializable entity, ref Timer timer)
{
timer?.Stop();
timer = null;
entity.MarkDirty();
}
}
}

View file

@ -1182,6 +1182,20 @@ namespace Server
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T RandomElement<T>(this IList<T> list) => list.RandomElement(default);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T TakeRandomElement<T>(this IList<T> list)
{
if (list.Count == 0)
{
return default;
}
var index = Random(list.Count);
var value = list[index];
list.RemoveAt(index);
return value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T RandomElement<T>(this IList<T> list, T valueIfZero) =>
list.Count == 0 ? valueIfZero : list[Random(list.Count)];

View file

@ -15,9 +15,9 @@ namespace Server.Items
[Constructible]
public BallotBox() : base(0x9A8)
{
Topic = Array.Empty<string>();
Yes = new List<Mobile>();
No = new List<Mobile>();
_topic = Array.Empty<string>();
_yes = new List<Mobile>();
_no = new List<Mobile>();
}
public override int LabelNumber => 1041006; // a ballot box

View file

@ -279,7 +279,7 @@ namespace Server.Items
private void Deserialize(IGenericReader reader, int version)
{
Components = reader.ReadEntityList<AddonComponent>();
_components = reader.ReadEntityList<AddonComponent>();
if (version < 1 && Weight == 0)
{

View file

@ -14,7 +14,7 @@ namespace Server.Items
{
AddonComponent.ApplyLightTo(this);
Components = new List<AddonContainerComponent>();
_components = new List<AddonContainerComponent>();
}
public override bool DisplayWeight => false;

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using Server.Commands;
using Server.Mobiles;
using Server.Network;
using Server.Spells;

View file

@ -7,7 +7,8 @@ using Server.Utilities;
namespace Server.Items
{
public class Aquarium : BaseAddonContainer
[Serializable(3, false)]
public partial class Aquarium : BaseAddonContainer
{
public static readonly TimeSpan EvaluationInterval = TimeSpan.FromDays(1);
@ -26,18 +27,41 @@ namespace Server.Items
private bool m_EvaluateDay;
// aquarium state
private AquariumState m_Food;
[SerializableField(0, setter: "private")]
private Timer _evaluateTimer;
// events
private bool m_RewardAvailable;
[DeserializeTimerField(0)]
private void DeserializeEvaluateTimer(TimeSpan delay)
{
_evaluateTimer = Timer.DelayCall(delay, EvaluationInterval, Evaluate);
}
// evaluate timer
private Timer _timer;
[SerializableField(1, setter: "private")]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private int _liveCreatures;
// vacation info
private int m_VacationLeft;
private AquariumState m_Water;
[InvalidateProperties]
[SerializableField(2, setter: "private")]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private int _vacationLeft;
[InvalidateProperties]
[SerializableField(3, setter: "private")]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private AquariumState _food;
[InvalidateProperties]
[SerializableField(4, setter: "private")]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private AquariumState _water;
[SerializableField(5, setter: "private")]
private List<int> _events;
[InvalidateProperties]
[SerializableField(6)]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private bool _rewardAvailable;
public Aquarium(int itemID) : base(itemID)
{
@ -55,30 +79,22 @@ namespace Server.Items
MaxItems = 30;
m_Food = new AquariumState();
m_Water = new AquariumState();
_food = new AquariumState(this);
_water = new AquariumState(this);
m_Food.State = (int)FoodState.Full;
m_Water.State = (int)WaterState.Strong;
_food.State = (int)FoodState.Full;
_water.State = (int)WaterState.Strong;
m_Food.Maintain = Utility.RandomMinMax(1, 2);
m_Food.Improve = m_Food.Maintain + Utility.RandomMinMax(1, 2);
_food.Maintain = Utility.RandomMinMax(1, 2);
_food.Improve = _food.Maintain + Utility.RandomMinMax(1, 2);
m_Water.Maintain = Utility.RandomMinMax(1, 3);
_water.Maintain = Utility.RandomMinMax(1, 3);
Events = new List<int>();
_events = new List<int>();
_timer = Timer.DelayCall(EvaluationInterval, EvaluationInterval, Evaluate);
_evaluateTimer = Timer.DelayCall(EvaluationInterval, EvaluationInterval, Evaluate);
}
public Aquarium(Serial serial) : base(serial)
{
}
// items info
[CommandProperty(AccessLevel.GameMaster)]
public int LiveCreatures { get; private set; }
[CommandProperty(AccessLevel.GameMaster)]
public int DeadCreatures
{
@ -108,9 +124,9 @@ namespace Server.Items
{
get
{
var state = m_Food.State == (int)FoodState.Overfed ? 1 : (int)FoodState.Full - m_Food.State;
var state = _food.State == (int)FoodState.Overfed ? 1 : (int)FoodState.Full - _food.State;
state += (int)WaterState.Strong - m_Water.State;
state += (int)WaterState.Strong - _water.State;
state = (int)Math.Pow(state, 1.75);
@ -122,78 +138,21 @@ namespace Server.Items
public bool IsFull => Items.Count >= MaxItems;
[CommandProperty(AccessLevel.GameMaster)]
public int VacationLeft
{
get => m_VacationLeft;
set
{
m_VacationLeft = value;
InvalidateProperties();
}
}
public bool OptimalState => _food.State == (int)FoodState.Full && _water.State == (int)WaterState.Strong;
[CommandProperty(AccessLevel.GameMaster)]
public AquariumState Food
{
get => m_Food;
set
{
m_Food = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public AquariumState Water
{
get => m_Water;
set
{
m_Water = value;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool OptimalState => m_Food.State == (int)FoodState.Full && m_Water.State == (int)WaterState.Strong;
public List<int> Events { get; private set; }
[CommandProperty(AccessLevel.GameMaster)]
public bool RewardAvailable
{
get => m_RewardAvailable;
set
{
m_RewardAvailable = value;
InvalidateProperties();
}
}
public override BaseAddonContainerDeed Deed
{
get
{
if (ItemID == 0x3062)
{
return new AquariumEastDeed();
}
return new AquariumNorthDeed();
}
}
public override BaseAddonContainerDeed Deed => ItemID == 0x3062 ? new AquariumEastDeed() : new AquariumNorthDeed();
public override double DefaultWeight => 10.0;
public static int[] FishHues { get; } =
private static int[] FishHues =
{
0x1C2, 0x1C3, 0x2A3, 0x47E, 0x51D
};
public override void OnDelete()
{
_timer.Stop();
_timer = null;
_evaluateTimer.Stop();
_evaluateTimer = null;
}
public override void OnDoubleClick(Mobile from)
@ -214,7 +173,7 @@ namespace Server.Items
return false;
}
if (m_VacationLeft > 0)
if (_vacationLeft > 0)
{
from.SendLocalizedMessage(1074427); // The aquarium is in vacation mode.
return false;
@ -242,17 +201,17 @@ namespace Server.Items
}
else if (dropped is VacationWafer)
{
m_VacationLeft = VacationWafer.VacationDays;
_vacationLeft = VacationWafer.VacationDays;
dropped.Delete();
from.SendLocalizedMessage(
1074428,
m_VacationLeft.ToString()
_vacationLeft.ToString()
); // The aquarium will be in vacation mode for ~1_DAYS~ days
}
else if (dropped is AquariumFood)
{
m_Food.Added += 1;
_food.Added += 1;
dropped.Delete();
from.SendLocalizedMessage(1074259, "1"); // ~1_NUM~ unit(s) of food have been added to the aquarium.
@ -265,7 +224,7 @@ namespace Server.Items
return false;
}
m_Water.Added += 1;
_water.Added += 1;
beverage.Quantity -= 1;
from.PlaySound(0x4E);
@ -337,17 +296,17 @@ namespace Server.Items
base.OnSingleClick(from);
if (m_VacationLeft > 0)
if (_vacationLeft > 0)
{
LabelTo(from, 1074430, m_VacationLeft.ToString()); // Vacation days left: ~1_DAYS
LabelTo(from, 1074430, _vacationLeft.ToString()); // Vacation days left: ~1_DAYS
}
if (Events.Count > 0)
if (_events.Count > 0)
{
LabelTo(from, 1074426, Events.Count.ToString()); // ~1_NUM~ event(s) to view!
LabelTo(from, 1074426, _events.Count.ToString()); // ~1_NUM~ event(s) to view!
}
if (m_RewardAvailable)
if (_rewardAvailable)
{
LabelTo(from, 1074362); // A reward is available!
}
@ -363,43 +322,43 @@ namespace Server.Items
if (decorations > 0)
{
LabelTo(from, 1074249, (Items.Count - LiveCreatures - DeadCreatures).ToString()); // Decorations: ~1_NUM~
LabelTo(from, 1074249, decorations.ToString()); // Decorations: ~1_NUM~
}
LabelTo(from, 1074250, $"#{FoodNumber()}"); // Food state: ~1_STATE~
LabelTo(from, 1074251, $"#{WaterNumber()}"); // Water state: ~1_STATE~
if (m_Food.State == (int)FoodState.Dead)
if (_food.State == (int)FoodState.Dead)
{
LabelTo(from, 1074577, $"{m_Food.Added}\t{m_Food.Improve}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~
LabelTo(from, 1074577, $"{_food.Added}\t{_food.Improve}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~
}
else if (m_Food.State == (int)FoodState.Overfed)
else if (_food.State == (int)FoodState.Overfed)
{
LabelTo(from, 1074577, $"{m_Food.Added}\t{m_Food.Maintain}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~
LabelTo(from, 1074577, $"{_food.Added}\t{_food.Maintain}"); // Food Added: ~1_CUR~ Needed: ~2_NEED~
}
else
{
LabelTo(
from,
1074253,
$"{m_Food.Added}\t{m_Food.Maintain}\t{m_Food.Improve}"
); // Food Added: ~1_CUR~ Feed: ~2_NEED~ Improve: ~3_GROW~
1074253, // Food Added: ~1_CUR~ Feed: ~2_NEED~ Improve: ~3_GROW~
$"{_food.Added}\t{_food.Maintain}\t{_food.Improve}"
);
}
if (m_Water.State == (int)WaterState.Dead)
if (_water.State == (int)WaterState.Dead)
{
LabelTo(from, 1074578, $"{m_Water.Added}\t{m_Water.Improve}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~
LabelTo(from, 1074578, $"{_water.Added}\t{_water.Improve}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~
}
else if (m_Water.State == (int)WaterState.Strong)
else if (_water.State == (int)WaterState.Strong)
{
LabelTo(from, 1074578, $"{m_Water.Added}\t{m_Water.Maintain}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~
LabelTo(from, 1074578, $"{_water.Added}\t{_water.Maintain}"); // Water Added: ~1_CUR~ Needed: ~2_NEED~
}
else
{
LabelTo(
from,
1074254,
$"{m_Water.Added}\t{m_Water.Maintain}\t{m_Water.Improve}"
$"{_water.Added}\t{_water.Maintain}\t{_water.Improve}"
); // Water Added: ~1_CUR~ Maintain: ~2_NEED~ Improve: ~3_GROW~
}
}
@ -408,17 +367,17 @@ namespace Server.Items
{
base.AddNameProperties(list);
if (m_VacationLeft > 0)
if (_vacationLeft > 0)
{
list.Add(1074430, m_VacationLeft.ToString()); // Vacation days left: ~1_DAYS
list.Add(1074430, _vacationLeft.ToString()); // Vacation days left: ~1_DAYS
}
if (Events.Count > 0)
if (_events.Count > 0)
{
list.Add(1074426, Events.Count.ToString()); // ~1_NUM~ event(s) to view!
list.Add(1074426, _events.Count.ToString()); // ~1_NUM~ event(s) to view!
}
if (m_RewardAvailable)
if (_rewardAvailable)
{
list.Add(1074362); // A reward is available!
}
@ -442,42 +401,42 @@ namespace Server.Items
list.Add(1074250, "#{0}", FoodNumber()); // Food state: ~1_STATE~
list.Add(1074251, "#{0}", WaterNumber()); // Water state: ~1_STATE~
if (m_Food.State == (int)FoodState.Dead)
if (_food.State == (int)FoodState.Dead)
{
list.Add(1074577, "{0}\t{1}", m_Food.Added, m_Food.Improve); // Food Added: ~1_CUR~ Needed: ~2_NEED~
list.Add(1074577, "{0}\t{1}", _food.Added, _food.Improve); // Food Added: ~1_CUR~ Needed: ~2_NEED~
}
else if (m_Food.State == (int)FoodState.Overfed)
else if (_food.State == (int)FoodState.Overfed)
{
list.Add(1074577, "{0}\t{1}", m_Food.Added, m_Food.Maintain); // Food Added: ~1_CUR~ Needed: ~2_NEED~
list.Add(1074577, "{0}\t{1}", _food.Added, _food.Maintain); // Food Added: ~1_CUR~ Needed: ~2_NEED~
}
else
{
list.Add(
1074253,
1074253, // Food Added: ~1_CUR~ Feed: ~2_NEED~ Improve: ~3_GROW~
"{0}\t{1}\t{2}",
m_Food.Added,
m_Food.Maintain,
m_Food.Improve
); // Food Added: ~1_CUR~ Feed: ~2_NEED~ Improve: ~3_GROW~
_food.Added,
_food.Maintain,
_food.Improve
);
}
if (m_Water.State == (int)WaterState.Dead)
if (_water.State == (int)WaterState.Dead)
{
list.Add(1074578, "{0}\t{1}", m_Water.Added, m_Water.Improve); // Water Added: ~1_CUR~ Needed: ~2_NEED~
list.Add(1074578, "{0}\t{1}", _water.Added, _water.Improve); // Water Added: ~1_CUR~ Needed: ~2_NEED~
}
else if (m_Water.State == (int)WaterState.Strong)
else if (_water.State == (int)WaterState.Strong)
{
list.Add(1074578, "{0}\t{1}", m_Water.Added, m_Water.Maintain); // Water Added: ~1_CUR~ Needed: ~2_NEED~
list.Add(1074578, "{0}\t{1}", _water.Added, _water.Maintain); // Water Added: ~1_CUR~ Needed: ~2_NEED~
}
else
{
list.Add(
1074254,
1074254, // Water Added: ~1_CUR~ Maintain: ~2_NEED~ Improve: ~3_GROW~
"{0}\t{1}\t{2}",
m_Water.Added,
m_Water.Maintain,
m_Water.Improve
); // Water Added: ~1_CUR~ Maintain: ~2_NEED~ Improve: ~3_GROW~
_water.Added,
_water.Maintain,
_water.Improve
);
}
}
@ -491,17 +450,17 @@ namespace Server.Items
if (HasAccess(from))
{
if (m_RewardAvailable)
if (_rewardAvailable)
{
list.Add(new CollectRewardEntry(this));
}
if (Events.Count > 0)
if (_events.Count > 0)
{
list.Add(new ViewEventEntry(this));
}
if (m_VacationLeft > 0)
if (_vacationLeft > 0)
{
list.Add(new CancelVacationMode(this));
}
@ -518,130 +477,20 @@ namespace Server.Items
}
}
public override void Serialize(IGenericWriter writer)
private void Deserialize(IGenericReader reader, int version)
{
base.Serialize(writer);
writer.Write(3); // Version
// version 1
writer.Write(_timer?.Running == true ? _timer.Next : Core.Now + EvaluationInterval);
// version 0
writer.Write(LiveCreatures);
writer.Write(m_VacationLeft);
m_Food.Serialize(writer);
m_Water.Serialize(writer);
writer.Write(Events.Count);
for (var i = 0; i < Events.Count; i++)
{
writer.Write(Events[i]);
}
writer.Write(m_RewardAvailable);
// If you are deserializing such an old version, you should validate all of the properties. RunUO had bugs.
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
public int FoodNumber() =>
_food.State switch
{
case 3:
case 2:
case 1:
{
var next = reader.ReadDateTime();
(int)FoodState.Full => 1074240,
(int)FoodState.Overfed => 1074239,
_ => 1074236 + _food.State
};
if (next < Core.Now)
{
next = Core.Now;
}
_timer = Timer.DelayCall(next - Core.Now, EvaluationInterval, Evaluate);
goto case 0;
}
case 0:
{
LiveCreatures = reader.ReadInt();
m_VacationLeft = reader.ReadInt();
m_Food = new AquariumState();
m_Water = new AquariumState();
m_Food.Deserialize(reader);
m_Water.Deserialize(reader);
Events = new List<int>();
var count = reader.ReadInt();
for (var i = 0; i < count; i++)
{
Events.Add(reader.ReadInt());
}
m_RewardAvailable = reader.ReadBool();
break;
}
}
if (version < 2)
{
Weight = DefaultWeight;
Movable = false;
}
if (version < 3)
{
ValidationQueue<Aquarium>.Add(this);
}
}
private void RecountLiveCreatures()
{
LiveCreatures = 0;
FindItemsByType<BaseFish>()
.ForEach(
fish =>
{
if (!fish.Dead)
{
++LiveCreatures;
}
}
);
}
public void Validate()
{
RecountLiveCreatures();
}
public int FoodNumber()
{
if (m_Food.State == (int)FoodState.Full)
{
return 1074240;
}
if (m_Food.State == (int)FoodState.Overfed)
{
return 1074239;
}
return 1074236 + m_Food.State;
}
public int WaterNumber() => 1074242 + m_Water.State;
public int WaterNumber() => 1074242 + _water.State;
public virtual void KillFish(int amount)
{
@ -662,73 +511,71 @@ namespace Server.Items
while (amount > 0 && toKill.Count > 0)
{
var kill = toKill.RandomElement();
var kill = toKill.TakeRandomElement();
kill.Kill();
toKill.Remove(kill);
amount -= 1;
LiveCreatures = Math.Max(LiveCreatures - 1, 0);
Events.Add(
1074366
); // An unfortunate accident has left a creature floating upside-down. It is starting to smell.
// An unfortunate accident has left a creature floating upside-down. It is starting to smell.
this.Add(_events, 1074366);
}
}
public virtual void Evaluate()
{
if (m_VacationLeft > 0)
if (_vacationLeft > 0)
{
m_VacationLeft -= 1;
_vacationLeft -= 1;
}
else if (m_EvaluateDay)
{
// reset events
Events = new List<int>();
this.Clear(_events);
// food events
if (
m_Food.Added < m_Food.Maintain && m_Food.State != (int)FoodState.Overfed &&
m_Food.State != (int)FoodState.Dead ||
m_Food.Added >= m_Food.Improve && m_Food.State == (int)FoodState.Full)
_food.Added < _food.Maintain && _food.State != (int)FoodState.Overfed &&
_food.State != (int)FoodState.Dead ||
_food.Added >= _food.Improve && _food.State == (int)FoodState.Full)
{
Events.Add(1074368); // The tank looks worse than it did yesterday.
this.Add(_events, 1074368); // The tank looks worse than it did yesterday.
}
if (
m_Food.Added >= m_Food.Improve && m_Food.State != (int)FoodState.Full &&
m_Food.State != (int)FoodState.Overfed ||
m_Food.Added < m_Food.Maintain && m_Food.State == (int)FoodState.Overfed)
_food.Added >= _food.Improve && _food.State != (int)FoodState.Full &&
_food.State != (int)FoodState.Overfed ||
_food.Added < _food.Maintain && _food.State == (int)FoodState.Overfed)
{
Events.Add(1074367); // The tank looks healthier today.
this.Add(_events, 1074367); // The tank looks healthier today.
}
// water events
if (m_Water.Added < m_Water.Maintain && m_Water.State != (int)WaterState.Dead)
if (_water.Added < _water.Maintain && _water.State != (int)WaterState.Dead)
{
Events.Add(1074370); // This tank can use more water.
this.Add(_events, 1074370); // This tank can use more water.
}
if (m_Water.Added >= m_Water.Improve && m_Water.State != (int)WaterState.Strong)
if (_water.Added >= _water.Improve && _water.State != (int)WaterState.Strong)
{
Events.Add(1074369); // The water looks clearer today.
this.Add(_events, 1074369); // The water looks clearer today.
}
UpdateFoodState();
UpdateWaterState();
// reward
if (LiveCreatures > 0)
if (_liveCreatures > 0)
{
m_RewardAvailable = true;
RewardAvailable = true;
}
}
else
{
// new fish
if (OptimalState && LiveCreatures < MaxLiveCreatures)
if (OptimalState && _liveCreatures < MaxLiveCreatures)
{
if (Utility.RandomDouble() < 0.005 * LiveCreatures)
if (Utility.RandomDouble() < 0.005 * _liveCreatures)
{
BaseFish fish;
int message;
@ -784,7 +631,7 @@ namespace Server.Items
if (AddFish(fish))
{
Events.Add(message);
this.Add(_events, message);
}
else
{
@ -794,7 +641,7 @@ namespace Server.Items
}
// kill fish *grins*
if (LiveCreatures < MaxLiveCreatures)
if (_liveCreatures < MaxLiveCreatures)
{
if (Utility.RandomDouble() < 0.01)
{
@ -803,7 +650,7 @@ namespace Server.Items
}
else
{
KillFish(LiveCreatures - MaxLiveCreatures);
KillFish(_liveCreatures - MaxLiveCreatures);
}
}
@ -813,12 +660,12 @@ namespace Server.Items
public virtual void GiveReward(Mobile to)
{
if (!m_RewardAvailable)
if (!_rewardAvailable)
{
return;
}
var max = (int)((double)LiveCreatures / 30 * m_Decorations.Length);
var max = (int)((double)_liveCreatures / 30 * m_Decorations.Length);
var random = max <= 0 ? 0 : Utility.Random(max);
@ -853,59 +700,59 @@ namespace Server.Items
to.SendLocalizedMessage(1074360, $"#{item.LabelNumber}"); // You receive a reward: ~1_REWARD~
to.PlaySound(0x5A3);
m_RewardAvailable = false;
RewardAvailable = false;
InvalidateProperties();
}
public virtual void UpdateFoodState()
{
if (m_Food.Added < m_Food.Maintain)
if (_food.Added < _food.Maintain)
{
m_Food.State = m_Food.State <= 0 ? 0 : m_Food.State - 1;
_food.State = _food.State <= 0 ? 0 : _food.State - 1;
}
else if (m_Food.Added >= m_Food.Improve)
else if (_food.Added >= _food.Improve)
{
m_Food.State = m_Food.State >= (int)FoodState.Overfed ? (int)FoodState.Overfed : m_Food.State + 1;
_food.State = _food.State >= (int)FoodState.Overfed ? (int)FoodState.Overfed : _food.State + 1;
}
m_Food.Maintain = Utility.Random((int)FoodState.Overfed + 1 - m_Food.State, 2);
_food.Maintain = Utility.Random((int)FoodState.Overfed + 1 - _food.State, 2);
if (m_Food.State == (int)FoodState.Overfed)
if (_food.State == (int)FoodState.Overfed)
{
m_Food.Improve = 0;
_food.Improve = 0;
}
else
{
m_Food.Improve = m_Food.Maintain + 2;
_food.Improve = _food.Maintain + 2;
}
m_Food.Added = 0;
_food.Added = 0;
}
public virtual void UpdateWaterState()
{
if (m_Water.Added < m_Water.Maintain)
if (_water.Added < _water.Maintain)
{
m_Water.State = m_Water.State <= 0 ? 0 : m_Water.State - 1;
_water.State = _water.State <= 0 ? 0 : _water.State - 1;
}
else if (m_Water.Added >= m_Water.Improve)
else if (_water.Added >= _water.Improve)
{
m_Water.State = m_Water.State >= (int)WaterState.Strong ? (int)WaterState.Strong : m_Water.State + 1;
_water.State = _water.State >= (int)WaterState.Strong ? (int)WaterState.Strong : _water.State + 1;
}
m_Water.Maintain = Utility.Random((int)WaterState.Strong + 2 - m_Water.State, 2);
_water.Maintain = Utility.Random((int)WaterState.Strong + 2 - _water.State, 2);
if (m_Water.State == (int)WaterState.Strong)
if (_water.State == (int)WaterState.Strong)
{
m_Water.Improve = 0;
_water.Improve = 0;
}
else
{
m_Water.Improve = m_Water.Maintain + 2;
_water.Improve = _water.Maintain + 2;
}
m_Water.Added = 0;
_water.Added = 0;
}
public virtual bool RemoveItem(Mobile from, int at)
@ -987,7 +834,7 @@ namespace Server.Items
return false;
}
if (IsFull || LiveCreatures >= MaxLiveCreatures || fish.Dead)
if (IsFull || _liveCreatures >= MaxLiveCreatures || fish.Dead)
{
from?.SendLocalizedMessage(1073633); // The aquarium can not hold the creature.
@ -1117,7 +964,7 @@ namespace Server.Items
public override void OnClick()
{
if (m_Aquarium.Deleted || !m_Aquarium.HasAccess(Owner.From) || m_Aquarium.Events.Count == 0)
if (m_Aquarium.Deleted || !m_Aquarium.HasAccess(Owner.From) || m_Aquarium._events.Count == 0)
{
return;
}
@ -1129,7 +976,7 @@ namespace Server.Items
Owner.From.PlaySound(0x5A2);
}
m_Aquarium.Events.RemoveAt(0);
m_Aquarium.RemoveAt(m_Aquarium._events, 0);
m_Aquarium.InvalidateProperties();
}
}
@ -1160,9 +1007,7 @@ namespace Server.Items
{
private readonly Aquarium m_Aquarium;
public GMAddFood(Aquarium aquarium) : base(6231) // GM Add Food
=>
m_Aquarium = aquarium;
public GMAddFood(Aquarium aquarium) : base(6231) => m_Aquarium = aquarium;
public override void OnClick()
{
@ -1180,9 +1025,7 @@ namespace Server.Items
{
private readonly Aquarium m_Aquarium;
public GMAddWater(Aquarium aquarium) : base(6232) // GM Add Water
=>
m_Aquarium = aquarium;
public GMAddWater(Aquarium aquarium) : base(6232) => m_Aquarium = aquarium;
public override void OnClick()
{
@ -1200,9 +1043,7 @@ namespace Server.Items
{
private readonly Aquarium m_Aquarium;
public GMForceEvaluate(Aquarium aquarium) : base(6233) // GM Force Evaluate
=>
m_Aquarium = aquarium;
public GMForceEvaluate(Aquarium aquarium) : base(6233) => m_Aquarium = aquarium;
public override void OnClick()
{
@ -1219,9 +1060,7 @@ namespace Server.Items
{
private readonly Aquarium m_Aquarium;
public GMOpen(Aquarium aquarium) : base(6234) // GM Open Container
=>
m_Aquarium = aquarium;
public GMOpen(Aquarium aquarium) : base(6234) => m_Aquarium = aquarium;
public override void OnClick()
{
@ -1238,9 +1077,7 @@ namespace Server.Items
{
private readonly Aquarium m_Aquarium;
public GMFill(Aquarium aquarium) : base(6236) // GM Fill Food and Water
=>
m_Aquarium = aquarium;
public GMFill(Aquarium aquarium) : base(6236) => m_Aquarium = aquarium;
public override void OnClick()
{
@ -1256,61 +1093,27 @@ namespace Server.Items
}
}
public class AquariumEastDeed : BaseAddonContainerDeed
[Serializable(0, false)]
public partial class AquariumEastDeed : BaseAddonContainerDeed
{
[Constructible]
public AquariumEastDeed()
{
}
public AquariumEastDeed(Serial serial) : base(serial)
{
}
public override BaseAddonContainer Addon => new Aquarium(0x3062);
public override int LabelNumber => 1074501; // Large Aquarium (east)
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // Version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
public class AquariumNorthDeed : BaseAddonContainerDeed
[Serializable(0, false)]
public partial class AquariumNorthDeed : BaseAddonContainerDeed
{
[Constructible]
public AquariumNorthDeed()
{
}
public AquariumNorthDeed(Serial serial) : base(serial)
{
}
public override BaseAddonContainer Addon => new Aquarium(0x3060);
public override int LabelNumber => 1074497; // Large Aquarium (north)
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // Version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -21,46 +21,43 @@ namespace Server.Items
}
[PropertyObject]
public class AquariumState
[EmbeddedSerializable(0, false)]
public partial class AquariumState
{
private int m_State;
[SerializableParent]
private Aquarium _aquarium;
private int _state;
public AquariumState(Aquarium parent) => _aquarium = parent;
[SerializableField(0)]
[CommandProperty(AccessLevel.GameMaster)]
public int State
{
get => m_State;
set => m_State = Math.Clamp(value, 0, 4);
get => _state;
set
{
if (_state != value)
{
_state = Math.Clamp(value, 0, 4);
_aquarium.MarkDirty();
}
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int Maintain { get; set; }
[SerializableField(1)]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private int _maintain;
[CommandProperty(AccessLevel.GameMaster)]
public int Improve { get; set; }
[SerializableField(2)]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private int _improve;
[CommandProperty(AccessLevel.GameMaster)]
public int Added { get; set; }
[SerializableField(3)]
[SerializableFieldAttr("[CommandProperty(AccessLevel.GameMaster)]")]
private int _added;
public override string ToString() => "...";
public virtual void Serialize(IGenericWriter writer)
{
writer.Write(0); // version
writer.Write(m_State);
writer.Write(Maintain);
writer.Write(Improve);
writer.Write(Added);
}
public virtual void Deserialize(IGenericReader reader)
{
var version = reader.ReadInt();
m_State = reader.ReadInt();
Maintain = reader.ReadInt();
Improve = reader.ReadInt();
Added = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class AlbinoCourtesanFish : BaseFish
[Serializable(0, false)]
public partial class AlbinoCourtesanFish : BaseFish
{
[Constructible]
public AlbinoCourtesanFish() : base(0x3B04)
{
}
public AlbinoCourtesanFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074592; // Albino Courtesan Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,11 @@
namespace Server.Items
{
public class AlbinoFrog : BaseFish
[Serializable(0, false)]
public partial class AlbinoFrog : BaseFish
{
[Constructible]
public AlbinoFrog() : base(0x3B0D) => Hue = 0x47E;
public AlbinoFrog(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073824; // An Albino Frog
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class BritainCrownFish : BaseFish
[Serializable(0, false)]
public partial class BritainCrownFish : BaseFish
{
[Constructible]
public BritainCrownFish() : base(0x3AFF)
{
}
public BritainCrownFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074589; // Britain Crown Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class FandancerFish : BaseFish
[Serializable(0, false)]
public partial class FandancerFish : BaseFish
{
[Constructible]
public FandancerFish() : base(0x3B02)
{
}
public FandancerFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074591; // Fandancer Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class GoldenBroadtail : BaseFish
[Serializable(0, false)]
public partial class GoldenBroadtail : BaseFish
{
[Constructible]
public GoldenBroadtail() : base(0x3B03)
{
}
public GoldenBroadtail(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073828; // A Golden Broadtail
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class Jellyfish : BaseFish
[Serializable(0, false)]
public partial class Jellyfish : BaseFish
{
[Constructible]
public Jellyfish() : base(0x3B0E)
{
}
public Jellyfish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074593; // Jellyfish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class KillerFrog : BaseFish
[Serializable(0, false)]
public partial class KillerFrog : BaseFish
{
[Constructible]
public KillerFrog() : base(0x3B0D)
{
}
public KillerFrog(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073825; // A Killer Frog
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,11 @@
namespace Server.Items
{
public class LongClawCrab : BaseFish
[Serializable(0, false)]
public partial class LongClawCrab : BaseFish
{
[Constructible]
public LongClawCrab() : base(0x3AFC) => Hue = 0x527;
public LongClawCrab(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073827; // A Long Claw Crab
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class MakotoCourtesanFish : BaseFish
[Serializable(0, false)]
public partial class MakotoCourtesanFish : BaseFish
{
[Constructible]
public MakotoCourtesanFish() : base(0x3AFD)
{
}
public MakotoCourtesanFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073835; // A Makoto Courtesan Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class MinocBlueFish : BaseFish
[Serializable(0, false)]
public partial class MinocBlueFish : BaseFish
{
[Constructible]
public MinocBlueFish() : base(0x3AFE)
{
}
public MinocBlueFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073829; // A Minoc Blue Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class NujelmHoneyFish : BaseFish
[Serializable(0, false)]
public partial class NujelmHoneyFish : BaseFish
{
[Constructible]
public NujelmHoneyFish() : base(0x3B06)
{
}
public NujelmHoneyFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073830; // A Nujel'm Honey Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,28 +1,11 @@
namespace Server.Items
{
public class PurpleFrog : BaseFish
[Serializable(0, false)]
public partial class PurpleFrog : BaseFish
{
[Constructible]
public PurpleFrog() : base(0x3B0D) => Hue = 0x4FA;
public PurpleFrog(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073823; // A Purple Frog
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class RedDartFish : BaseFish
[Serializable(0, false)]
public partial class RedDartFish : BaseFish
{
[Constructible]
public RedDartFish() : base(0x3B00)
{
}
public RedDartFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073834; // A Red Dart Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class Shrimp : BaseFish
[Serializable(0, false)]
public partial class Shrimp : BaseFish
{
[Constructible]
public Shrimp() : base(0x3B14)
{
}
public Shrimp(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074596; // Shrimp
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class SmallMouthSuckerFin : BaseFish
[Serializable(0, false)]
public partial class SmallMouthSuckerFin : BaseFish
{
[Constructible]
public SmallMouthSuckerFin() : base(0x3B01)
{
}
public SmallMouthSuckerFin(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074590; // Small Mouth Sucker Fin
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class SpeckledCrab : BaseFish
[Serializable(0, false)]
public partial class SpeckledCrab : BaseFish
{
[Constructible]
public SpeckledCrab() : base(0x3AFC)
{
}
public SpeckledCrab(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073826; // A Speckled Crab
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class SpinedScratcherFish : BaseFish
[Serializable(0, false)]
public partial class SpinedScratcherFish : BaseFish
{
[Constructible]
public SpinedScratcherFish() : base(0x3B05)
{
}
public SpinedScratcherFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073832; // A Spined Scratcher Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class SpottedBuccaneer : BaseFish
[Serializable(0, false)]
public partial class SpottedBuccaneer : BaseFish
{
[Constructible]
public SpottedBuccaneer() : base(0x3B09)
{
}
public SpottedBuccaneer(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073833; // A Spotted Buccaneer
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class VesperReefTiger : BaseFish
[Serializable(0, false)]
public partial class VesperReefTiger : BaseFish
{
[Constructible]
public VesperReefTiger() : base(0x3B08)
{
}
public VesperReefTiger(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073836; // A Vesper Reef Tiger
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class YellowFinBluebelly : BaseFish
[Serializable(0, false)]
public partial class YellowFinBluebelly : BaseFish
{
[Constructible]
public YellowFinBluebelly() : base(0x3B07)
{
}
public YellowFinBluebelly(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073831; // A Yellow Fin Bluebelly
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class BrineShrimp : BaseFish
[Serializable(0, false)]
public partial class BrineShrimp : BaseFish
{
[Constructible]
public BrineShrimp() : base(0x3B11)
{
}
public BrineShrimp(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074415; // Brine shrimp
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class Coral : BaseFish
[Serializable(0, false)]
public partial class Coral : BaseFish
{
[Constructible]
public Coral() : base(Utility.RandomList(0x3AF9, 0x3AFA, 0x3AFB))
{
}
public Coral(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074588; // Coral
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class FullMoonFish : BaseFish
[Serializable(0, false)]
public partial class FullMoonFish : BaseFish
{
[Constructible]
public FullMoonFish() : base(0x3B15)
{
}
public FullMoonFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074597; // A Full Moon Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class SeaHorseFish : BaseFish
[Serializable(0, false)]
public partial class SeaHorseFish : BaseFish
{
[Constructible]
public SeaHorseFish() : base(0x3B10)
{
}
public SeaHorseFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074414; // A sea horse
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class StrippedFlakeFish : BaseFish
[Serializable(0, false)]
public partial class StrippedFlakeFish : BaseFish
{
[Constructible]
public StrippedFlakeFish() : base(0x3B0A)
{
}
public StrippedFlakeFish(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074595; // Stripped Flake Fish
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,30 +1,13 @@
namespace Server.Items
{
public class StrippedSosarianSwill : BaseFish
[Serializable(0, false)]
public partial class StrippedSosarianSwill : BaseFish
{
[Constructible]
public StrippedSosarianSwill() : base(0x3B0A)
{
}
public StrippedSosarianSwill(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074594; // Stripped Sosarian Swill
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,16 +1,13 @@
namespace Server.Items
{
public class AquariumMessage : MessageInABottle
[Serializable(0, false)]
public partial class AquariumMessage : MessageInABottle
{
[Constructible]
public AquariumMessage()
{
}
public AquariumMessage(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1073894; // Message in a Bottle
public override void AddNameProperties(ObjectPropertyList list)
@ -19,19 +16,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,16 +1,13 @@
namespace Server.Items
{
public class CaptainBlackheartsFishingPole : FishingPole
[Serializable(0, false)]
public partial class CaptainBlackheartsFishingPole : FishingPole
{
[Constructible]
public CaptainBlackheartsFishingPole()
{
}
public CaptainBlackheartsFishingPole(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074571; // Captain Blackheart's Fishing Pole
public override void AddNameProperties(ObjectPropertyList list)
@ -19,19 +16,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,16 +1,13 @@
namespace Server.Items
{
public class CraftysFishingHat : BaseHat
[Serializable(0, false)]
public partial class CraftysFishingHat : BaseHat
{
[Constructible]
public CraftysFishingHat() : base(0x1713)
{
}
public CraftysFishingHat(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074572; // Crafty's Fishing Hat
public override int BasePhysicalResistance => 0;
@ -28,19 +25,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,16 +1,13 @@
namespace Server.Items
{
public class FishBones : Item
[Serializable(0, false)]
public partial class FishBones : Item
{
[Constructible]
public FishBones() : base(0x3B0C)
{
}
public FishBones(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074601; // Fish bones
public override double DefaultWeight => 1.0;
@ -20,19 +17,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,16 +1,13 @@
namespace Server.Items
{
public class IslandStatue : Item
[Serializable(0, false)]
public partial class IslandStatue : Item
{
[Constructible]
public IslandStatue() : base(0x3B0F)
{
}
public IslandStatue(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074600; // An island statue
public override double DefaultWeight => 1.0;
@ -20,19 +17,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,13 +1,10 @@
namespace Server.Items
{
public class Shell : Item
[Serializable(0, false)]
public partial class Shell : Item
{
[Constructible]
public Shell() : base(Utility.RandomList(0x3B12, 0x3B13))
{
}
public Shell(Serial serial) : base(serial)
public Shell() : base(Utility.Random(0x3B12, 2))
{
}
@ -20,19 +17,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,17 +1,14 @@
namespace Server.Items
{
[Serializable(0, false)]
[Flippable(0x14F3, 0x14F4)]
public class ToyBoat : Item
public partial class ToyBoat : Item
{
[Constructible]
public ToyBoat() : base(0x14F4)
{
}
public ToyBoat(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074363; // A toy boat
public override double DefaultWeight => 1.0;
@ -21,19 +18,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -1,6 +1,7 @@
namespace Server.Items
{
public class WaterloggedBoots : BaseShoes
[Serializable(0, false)]
public partial class WaterloggedBoots : BaseShoes
{
[Constructible]
public WaterloggedBoots() : base(0x1711)
@ -19,10 +20,6 @@ namespace Server.Items
}
}
public WaterloggedBoots(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1074364; // Waterlogged boots
public override void AddNameProperties(ObjectPropertyList list)
@ -31,19 +28,5 @@ namespace Server.Items
list.Add(1073634); // An aquarium decoration
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}

View file

@ -6,7 +6,9 @@
"name": "Username",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "PasswordAlgorithm",
@ -18,7 +20,9 @@
"name": "Password",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "AccessLevel",
@ -30,31 +34,41 @@
"name": "Flags",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "Created",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "LastLogin",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "TotalGold",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "TotalPlat",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "Mobiles",
@ -102,7 +116,8 @@
"rule": "ArrayMigrationRule",
"ruleArguments": [
"string",
"PrimitiveTypeMigrationRule"
"PrimitiveTypeMigrationRule",
""
]
},
{
@ -115,7 +130,9 @@
"name": "Email",
"type": "string",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -6,13 +6,17 @@
"name": "AmountMax",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "RequireExceptional",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.AlbinoCourtesanFish",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.AlbinoFrog",
"properties": []
}

View file

@ -0,0 +1,65 @@
{
"version": 3,
"type": "Server.Items.Aquarium",
"properties": [
{
"name": "EvaluateTimer",
"type": "Server.Timer",
"rule": "TimerMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "LiveCreatures",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "VacationLeft",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Food",
"type": "Server.Items.AquariumState",
"rule": "EmbeddedSerializableMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Water",
"type": "Server.Items.AquariumState",
"rule": "EmbeddedSerializableMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Events",
"type": "System.Collections.Generic.List\u003Cint\u003E",
"rule": "ListMigrationRule",
"ruleArguments": [
"",
"int",
"PrimitiveTypeMigrationRule",
""
]
},
{
"name": "RewardAvailable",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.AquariumEastDeed",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.AquariumMessage",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.AquariumNorthDeed",
"properties": []
}

View file

@ -0,0 +1,38 @@
{
"version": 0,
"type": "Server.Items.AquariumState",
"properties": [
{
"name": "State",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Maintain",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Improve",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Added",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -6,25 +6,33 @@
"name": "MinSkill",
"type": "double",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "MaxSkill",
"type": "double",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "Arrows",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "Bolts",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -8,7 +8,8 @@
"rule": "ArrayMigrationRule",
"ruleArguments": [
"string",
"PrimitiveTypeMigrationRule"
"PrimitiveTypeMigrationRule",
""
]
},
{

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.BrineShrimp",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.BritainCrownFish",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.CaptainBlackheartsFishingPole",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.Coral",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.CraftysFishingHat",
"properties": []
}

View file

@ -12,13 +12,17 @@
"name": "Redyable",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
},
{
"name": "DyedHue",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.FandancerFish",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.FishBones",
"properties": []
}

View file

@ -6,7 +6,9 @@
"name": "CurFlour",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.FullMoonFish",
"properties": []
}

View file

@ -6,7 +6,9 @@
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.GoldenBroadtail",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.IslandStatue",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.Jellyfish",
"properties": []
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.KillerFrog",
"properties": []
}

View file

@ -6,7 +6,9 @@
"name": "IsRewardItem",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -6,7 +6,9 @@
"name": "Number",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -6,7 +6,9 @@
"name": "Number",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,5 @@
{
"version": 0,
"type": "Server.Items.LongClawCrab",
"properties": []
}

View file

@ -6,7 +6,9 @@
"name": "Phase",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

View file

@ -6,7 +6,9 @@
"name": "Phase",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": []
"ruleArguments": [
""
]
}
]
}

Some files were not shown because too many files have changed in this diff Show more