Skip to content

Commit

Permalink
World creation:
Browse files Browse the repository at this point in the history
* Generate Luz and Lvl files from xml.
* Filter out cdclient for zone entries.
  • Loading branch information
Wincent01 committed Mar 7, 2020
1 parent 58f7cd5 commit f2e85df
Show file tree
Hide file tree
Showing 14 changed files with 401 additions and 17 deletions.
1 change: 1 addition & 0 deletions InfectedRose.Database/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ private static int GetKey(object key)
{
var index = key switch
{
uint keyUint => (int) keyUint,
int keyInt => keyInt,
string val => (int) Hash(val.Select(k => (byte) k).ToArray()),
FdbString keyStr => (int) Hash(keyStr.Value.Select(k => (byte) k).ToArray()),
Expand Down
13 changes: 13 additions & 0 deletions InfectedRose.Interface/InfectedRose.Interface.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\InfectedRose.Database\InfectedRose.Database.csproj" />
<ProjectReference Include="..\InfectedRose.World\InfectedRose.World.csproj" />
</ItemGroup>

</Project>
87 changes: 87 additions & 0 deletions InfectedRose.Interface/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using System.Xml.Serialization;
using InfectedRose.Database;
using InfectedRose.Database.Concepts.Tables;
using InfectedRose.World;

namespace InfectedRose.Interface
{
internal static class Program
{
private static async Task Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine($"Usage: {Path.GetFileName(Assembly.GetEntryAssembly()?.Location)} <xml-file> <fdb>");

Environment.Exit(1);

return;
}

var serializer = new XmlSerializer(typeof(Zone));

var zone = new Zone();

if (File.Exists(args[0]))
{
await using var stream = File.OpenRead(args[0]);

zone = (Zone) serializer.Deserialize(stream);
}
else
{
await using var stream = File.Create(args[0]);

serializer.Serialize(stream, zone);

Console.WriteLine("Created xml file");

Environment.Exit(1);

return;
}

await zone.SaveAsync(Path.GetDirectoryName(args[0]));

var database = await AccessDatabase.OpenAsync(args[1]);

var zones = database["ZoneTable"];

foreach (var row in zones)
{
if (Enum.IsDefined(typeof(ZoneId), (ushort) row.Key)) continue;

zones.Remove(row);
}

var entry = new ZoneTableTable(zones.Create(zone.Id));

entry.zoneName = zone.Name;
entry.zoneID = (int) zone.Id;
entry.ghostdistance = zone.GhostDistance;
entry.scriptID = -1;
entry.locStatus = 0;
entry.DisplayDescription = zone.Description;

foreach (var table in database)
{
table.Recalculate();
}

var pad = 0;

await database.SaveAsync(args[1], i =>
{
if (++pad != 10000) return;

Console.WriteLine(i);

pad = 0;
});
}
}
}
40 changes: 40 additions & 0 deletions InfectedRose.Interface/ZoneId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace InfectedRose.Interface
{
public enum ZoneId : ushort
{
VentureExplorerCinematic,
VentureExplorer = 1000,
ReturnToVentureExplorer,
AvantGardens = 1100,
AvantGardensSurvival,
SpiderQueenBattle,
BlockYard = 1150,
AvantGrove,
NimbusStation = 1200,
PetCove,
VertigoLoopRacetrack = 1203,
BattleOfNimbusStation,
NimbusRock = 1250,
NimbusIsle,
FrostBurgh = 1260,
GnarledForest = 1300,
CanyonCove = 1302,
KeelhaulCanyon,
ChanteyShantey = 1350,
ForbiddenValley = 1400,
ForbiddenValleyDragon = 1402,
DragonmawChasm,
RavenBluff = 1450,
Starbase3001 = 1600,
DeepFreeze,
RobotCity,
MoonBase,
Portabello = 1604,
LegoClub = 1700,
CruxPrime = 1800,
NexusTower = 1900,
Ninjago = 2000,
FrakjawBattle,
NimbusStationWinterRacetrack = 1261
}
}
20 changes: 10 additions & 10 deletions InfectedRose.Luz/LuzFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public class LuzFile : IConstruct

public string TerrainDescription { get; set; }

public LuzSceneTransition[] Transitions { get; set; }
public uint PathFormatVersion { get; set; }
public LuzPathData[] PathData { get; set; }
public LuzSceneTransition[] Transitions { get; set; } = new LuzSceneTransition[0];

public uint PathFormatVersion { get; set; } = 18;

public LuzPathData[] PathData { get; set; } = new LuzPathData[0];

public void Serialize(BitWriter writer)
{
Expand Down Expand Up @@ -97,7 +97,9 @@ public void Serialize(BitWriter writer)

private void WritePaths(BitWriter writer)
{
writer.BaseStream.Position += 4;
using var token = new LengthToken(writer);

token.Allocate();

writer.Write(PathFormatVersion);

Expand All @@ -119,9 +121,9 @@ private void WritePaths(BitWriter writer)

writer.Write((uint) pathData.Waypoints.Length);

foreach (var waypoint in pathData.Waypoints)
foreach (var wayPoint in pathData.Waypoints)
{
waypoint.Serialize(writer);
wayPoint.Serialize(writer);
}
}
}
Expand Down Expand Up @@ -188,8 +190,6 @@ public void Deserialize(BitReader reader)
var version = reader.Read<uint>();
var name = reader.ReadNiString(true, true);
var type = (PathType) reader.Read<uint>();

//Console.WriteLine($"[{i}:{name}] -> [{type}]");

PathData[i] = type switch
{
Expand Down
12 changes: 6 additions & 6 deletions InfectedRose.Lvl/LevelSkyConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ namespace InfectedRose.Lvl
{
public class LevelSkyConfig : ChunkBase
{
public IdStruct[] Identifiers { get; set; }
public IdStruct[] Identifiers { get; set; } = new IdStruct[0];

public string[] Skybox { get; set; } = new string[6];
public float[] UnknownFloatArray0 { get; set; }

public float[] UnknownFloatArray0 { get; set; } = new float[0];

public float[] UnknownFloatArray1 { get; set; } = new float[3];

public float[] UnknownFloatArray2 { get; set; } = new float[3];
public byte[] UnknownSectionData { get; set; }

public byte[] UnknownSectionData { get; set; } = new byte[0];

public override uint ChunkType => 2000;

Expand Down Expand Up @@ -66,7 +66,7 @@ private byte[] WriteSkySection()

for (var i = 0; i < 6; i++)
{
writer.WriteNiString(Skybox[i]);
writer.WriteNiString(Skybox[i] ?? "<invalid>");
}

return stream.ToArray();
Expand Down
8 changes: 8 additions & 0 deletions InfectedRose.Lvl/LvlFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public class LvlFile : IConstruct
public LevelEnvironmentConfig LevelEnvironmentConfig { get; set; }

private static readonly byte[] ChunkHeader = "CHNK".Select(c => (byte) c).ToArray();

private ushort _index;

public void Serialize(BitWriter writer)
{
Expand All @@ -44,6 +46,8 @@ public void Serialize(BitWriter writer)

private void SerializeNew(BitWriter writer)
{
_index = 0;

SerializeChunk(writer, LevelInfo);
SerializeChunk(writer, LevelSkyConfig);

Expand Down Expand Up @@ -75,6 +79,10 @@ private void SerializeChunk(BitWriter writer, ChunkBase chunkBase)
{
if (chunkBase == default) return;

_index++;

chunkBase.Index = _index;

using var token = new LengthToken(writer);

switch (chunkBase)
Expand Down
1 change: 0 additions & 1 deletion InfectedRose.Lvl/ParticleStruct.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Numerics;
using InfectedRose.Core;
using RakDotNet.IO;
Expand Down
13 changes: 13 additions & 0 deletions InfectedRose.World/InfectedRose.World.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\InfectedRose.Luz\InfectedRose.Luz.csproj" />
<ProjectReference Include="..\InfectedRose.Lvl\InfectedRose.Lvl.csproj" />
<ProjectReference Include="..\InfectedRose.Terrain\InfectedRose.Terrain.csproj" />
</ItemGroup>

</Project>
74 changes: 74 additions & 0 deletions InfectedRose.World/Scene.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Serialization;
using InfectedRose.Luz;
using InfectedRose.Lvl;
using RakDotNet.IO;

namespace InfectedRose.World
{
[XmlRoot]
public class Scene
{
[XmlAttribute] public string Name { get; set; }

[XmlAttribute] public uint Id { get; set; }

[XmlAttribute] public uint Layer { get; set; }

[XmlAttribute] public uint Revision { get; set; }

[XmlElement] public string SkyBox { get; set; }

[XmlElement("Object")] public List<WorldObject> Objects { get; set; }

public LuzScene LuzScene => new LuzScene
{
FileName = $"{Name.Replace(" ", "_")}.lvl",
SceneName = Name,
SceneId = Id,
LayerId = Layer
};

public async Task SaveAsync(string path)
{
var scene = LuzScene;

var file = new LvlFile
{
LvlVersion = 0x26
};

if (Objects?.Count > 0)
{
file.LevelObjects = new LevelObjects(file.LvlVersion)
{
Templates = Objects.Select(o => o.Template).ToArray()
};
}

if (!string.IsNullOrWhiteSpace(SkyBox))
{
var skyConfig = new LevelSkyConfig
{
Skybox = {[0] = SkyBox}
};

file.LevelSkyConfig = skyConfig;
}

file.LevelInfo = new LevelInfo
{
RevisionNumber = Revision
};

await using var stream = File.Create(Path.Combine(path, scene.FileName));

using var writer = new BitWriter(stream);

file.Serialize(writer);
}
}
}
14 changes: 14 additions & 0 deletions InfectedRose.World/Terrain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Xml.Serialization;

namespace InfectedRose.World
{
[XmlRoot]
public class Terrain
{
[XmlElement] public string FileName { get; set; } = "terrain.raw";

[XmlElement] public string Name { get; set; } = "terrain";

[XmlElement] public string Description { get; set; } = "terrain file";
}
}
Loading

0 comments on commit f2e85df

Please sign in to comment.