mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2026-05-14 17:05:10 +08:00
Merge remote changes with local
This commit is contained in:
@@ -1165,6 +1165,41 @@ namespace CodeWalker.GameFiles
|
||||
if (change) physicsDictionaries = physDict.ToArray();
|
||||
}
|
||||
|
||||
public void InitYmapEntityArchetypes(GameFileCache gfc)
|
||||
{
|
||||
if (AllEntities != null)
|
||||
{
|
||||
for (int i = 0; i < AllEntities.Length; i++)
|
||||
{
|
||||
var ent = AllEntities[i];
|
||||
var arch = gfc.GetArchetype(ent.CEntityDef.archetypeName);
|
||||
ent.SetArchetype(arch);
|
||||
if (ent.IsMlo) ent.MloInstance.InitYmapEntityArchetypes(gfc);
|
||||
}
|
||||
}
|
||||
if (GrassInstanceBatches != null)
|
||||
{
|
||||
for (int i = 0; i < GrassInstanceBatches.Length; i++)
|
||||
{
|
||||
var batch = GrassInstanceBatches[i];
|
||||
batch.Archetype = gfc.GetArchetype(batch.Batch.archetypeName);
|
||||
}
|
||||
}
|
||||
|
||||
if (TimeCycleModifiers != null)
|
||||
{
|
||||
for (int i = 0; i < TimeCycleModifiers.Length; i++)
|
||||
{
|
||||
var tcm = TimeCycleModifiers[i];
|
||||
World.TimecycleMod wtcm;
|
||||
if (gfc.TimeCycleModsDict.TryGetValue(tcm.CTimeCycleModifier.name.Hash, out wtcm))
|
||||
{
|
||||
tcm.TimeCycleModData = wtcm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static uint SetBit(uint value, int bit)
|
||||
{
|
||||
@@ -1194,7 +1229,7 @@ namespace CodeWalker.GameFiles
|
||||
public bool IsMlo { get; set; }
|
||||
public MloInstanceData MloInstance { get; set; }
|
||||
public YmapEntityDef MloParent { get; set; }
|
||||
public MCMloEntitySet MloEntitySet { get; set; }
|
||||
public MloInstanceEntitySet MloEntitySet { get; set; }
|
||||
public Vector3 MloRefPosition { get; set; }
|
||||
public Quaternion MloRefOrientation { get; set; }
|
||||
public MetaWrapper[] Extensions { get; set; }
|
||||
@@ -1297,56 +1332,57 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
MloInstance = new MloInstanceData();
|
||||
}
|
||||
MloInstance.CreateYmapEntities(this, mloa);
|
||||
if (mloa != null)
|
||||
{
|
||||
if (!IsMlo)
|
||||
{
|
||||
IsMlo = true;
|
||||
MloInstance._Instance = new CMloInstanceDef { CEntityDef = _CEntityDef };
|
||||
|
||||
List<YmapEntityDef> mloEntities = Ymap.MloEntities?.ToList() ?? new List<YmapEntityDef>();
|
||||
mloEntities.Add(this);
|
||||
Ymap.MloEntities = mloEntities.ToArray();
|
||||
}
|
||||
|
||||
MloInstance.CreateYmapEntities(this, mloa);
|
||||
}
|
||||
|
||||
if (BSRadius == 0.0f)
|
||||
{
|
||||
BSRadius = CEntityDef.lodDist;//need something so it doesn't get culled...
|
||||
}
|
||||
}
|
||||
else if (IsMlo) // archetype is no longer an mlo
|
||||
{
|
||||
IsMlo = false;
|
||||
MloInstance = null;
|
||||
|
||||
if (Ymap.MloEntities != null)
|
||||
{
|
||||
List<YmapEntityDef> mloEntities = Ymap.MloEntities.ToList();
|
||||
if (mloEntities.Remove(this))
|
||||
{
|
||||
Ymap.MloEntities = mloEntities.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 pos)
|
||||
{
|
||||
Position = pos;
|
||||
if (MloParent != null)
|
||||
{
|
||||
//TODO: SetPosition for interior entities!
|
||||
Position = pos;
|
||||
var inst = MloParent.MloInstance;
|
||||
if (inst != null)
|
||||
{
|
||||
//transform world position into mlo space
|
||||
//MloRefPosition = ...
|
||||
//MloRefOrientation = ...
|
||||
}
|
||||
_CEntityDef.position = Quaternion.Normalize(Quaternion.Invert(MloParent.Orientation)).Multiply(pos - MloParent.Position);
|
||||
MloRefPosition = _CEntityDef.position;
|
||||
UpdateBB();
|
||||
UpdateMloArchetype();
|
||||
}
|
||||
else
|
||||
{
|
||||
Position = pos;
|
||||
_CEntityDef.position = pos;
|
||||
|
||||
if (Archetype != null)
|
||||
{
|
||||
BSCenter = Orientation.Multiply(Archetype.BSCenter) * Scale;
|
||||
}
|
||||
if ((Archetype != null) && (Orientation == Quaternion.Identity))
|
||||
{
|
||||
BBMin = (Archetype.BBMin * Scale) + Position;
|
||||
BBMax = (Archetype.BBMax * Scale) + Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
BBMin = Position - (BSRadius);
|
||||
BBMax = Position + (BSRadius);
|
||||
////not ideal: should transform all 8 corners!
|
||||
}
|
||||
|
||||
|
||||
|
||||
UpdateWidgetPosition();
|
||||
UpdateBB();
|
||||
}
|
||||
|
||||
|
||||
@@ -1356,40 +1392,51 @@ namespace CodeWalker.GameFiles
|
||||
MloInstance.UpdateEntities();
|
||||
}
|
||||
|
||||
UpdateWidgetPosition();
|
||||
}
|
||||
|
||||
public void SetOrientation(Quaternion ori)
|
||||
private void UpdateBB()
|
||||
{
|
||||
Quaternion inv = Quaternion.Normalize(Quaternion.Invert(ori));
|
||||
Orientation = ori;
|
||||
_CEntityDef.rotation = new Vector4(inv.X, inv.Y, inv.Z, inv.W);
|
||||
|
||||
if (MloInstance != null)
|
||||
{
|
||||
MloInstance.SetOrientation(ori);
|
||||
}
|
||||
|
||||
|
||||
if (Archetype != null)
|
||||
{
|
||||
BSCenter = Orientation.Multiply(Archetype.BSCenter) * Scale;
|
||||
}
|
||||
|
||||
UpdateWidgetPosition();
|
||||
UpdateWidgetOrientation();
|
||||
if ((Archetype != null) && (Orientation == Quaternion.Identity))
|
||||
{
|
||||
BBMin = (Archetype.BBMin * Scale) + Position;
|
||||
BBMax = (Archetype.BBMax * Scale) + Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
BBMin = Position - (BSRadius);
|
||||
BBMax = Position + (BSRadius);
|
||||
////not ideal: should transform all 8 corners!
|
||||
}
|
||||
}
|
||||
public void SetOrientationInv(Quaternion inv)
|
||||
|
||||
public void SetOrientation(Quaternion ori, bool inverse = false)
|
||||
{
|
||||
Quaternion ori = Quaternion.Normalize(Quaternion.Invert(inv));
|
||||
Orientation = ori;
|
||||
_CEntityDef.rotation = new Vector4(inv.X, inv.Y, inv.Z, inv.W);
|
||||
if (MloParent != null)
|
||||
{
|
||||
var mloInv = Quaternion.Normalize(Quaternion.Invert(MloParent.Orientation));
|
||||
Quaternion rel = Quaternion.Normalize(Quaternion.Multiply(mloInv, ori));
|
||||
Quaternion inv = Quaternion.Normalize(Quaternion.Invert(rel));
|
||||
Orientation = ori;
|
||||
_CEntityDef.rotation = inv.ToVector4();
|
||||
}
|
||||
else
|
||||
{
|
||||
Quaternion inv = inverse ? ori : Quaternion.Normalize(Quaternion.Invert(ori));
|
||||
ori = inverse ? Quaternion.Normalize(Quaternion.Invert(ori)) : ori;
|
||||
Orientation = ori;
|
||||
_CEntityDef.rotation = inv.ToVector4();
|
||||
}
|
||||
|
||||
if (MloInstance != null)
|
||||
{
|
||||
MloInstance.SetOrientation(ori);
|
||||
}
|
||||
|
||||
|
||||
if (Archetype != null)
|
||||
{
|
||||
BSCenter = Orientation.Multiply(Archetype.BSCenter) * Scale;
|
||||
@@ -1404,14 +1451,35 @@ namespace CodeWalker.GameFiles
|
||||
Scale = new Vector3(s.X, s.X, s.Z);
|
||||
_CEntityDef.scaleXY = s.X;
|
||||
_CEntityDef.scaleZ = s.Z;
|
||||
|
||||
MloInstanceData mloInstance = MloParent?.MloInstance;
|
||||
if (mloInstance != null)
|
||||
{
|
||||
var mcEntity = mloInstance.TryGetArchetypeEntity(this);
|
||||
if (mcEntity != null)
|
||||
{
|
||||
mcEntity._Data.scaleXY = s.X;
|
||||
mcEntity._Data.scaleZ = s.Z;
|
||||
}
|
||||
}
|
||||
if (Archetype != null)
|
||||
{
|
||||
float smax = Math.Max(Scale.X, Scale.Z);
|
||||
BSRadius = Archetype.BSRadius * smax;
|
||||
}
|
||||
|
||||
SetPosition(Position);//update the BB
|
||||
}
|
||||
|
||||
private void UpdateMloArchetype()
|
||||
{
|
||||
if (!(MloParent.Archetype is MloArchetype mloArchetype)) return;
|
||||
if (Index >= mloArchetype.entities.Length) return;
|
||||
|
||||
MCEntityDef entity = mloArchetype.entities[Index];
|
||||
entity._Data.position = _CEntityDef.position;
|
||||
entity._Data.rotation = _CEntityDef.rotation;
|
||||
}
|
||||
|
||||
|
||||
public void SetPivotPosition(Vector3 pos)
|
||||
@@ -1787,7 +1855,7 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
|
||||
private List<rage__fwGrassInstanceListDef__InstanceData>[] SplitGrass(
|
||||
IReadOnlyList<rage__fwGrassInstanceListDef__InstanceData> points,
|
||||
IReadOnlyList<rage__fwGrassInstanceListDef__InstanceData> points,
|
||||
BoundingBox batchAABB)
|
||||
{
|
||||
var pointGroup = new List<rage__fwGrassInstanceListDef__InstanceData>[2];
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace CodeWalker.GameFiles
|
||||
public uint NameHash { get; set; }
|
||||
public string[] Strings { get; set; }
|
||||
|
||||
|
||||
public CMapTypes CMapTypes { get; set; }
|
||||
public CMapTypes _CMapTypes;
|
||||
public CMapTypes CMapTypes { get { return _CMapTypes; } set { _CMapTypes = value; } }
|
||||
|
||||
public Archetype[] AllArchetypes { get; set; }
|
||||
|
||||
@@ -50,6 +50,111 @@ namespace CodeWalker.GameFiles
|
||||
return (RpfFileEntry != null) ? RpfFileEntry.Name : string.Empty;
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
{
|
||||
MetaBuilder mb = new MetaBuilder();
|
||||
|
||||
var mdb = mb.EnsureBlock(MetaName.CMapTypes);
|
||||
|
||||
CMapTypes mapTypes = _CMapTypes;
|
||||
|
||||
if (Extensions == null || Extensions.Length <= 0)
|
||||
mapTypes.extensions = new Array_StructurePointer();
|
||||
else
|
||||
mapTypes.extensions = mb.AddWrapperArrayPtr(Extensions);
|
||||
|
||||
if ((AllArchetypes != null) && (AllArchetypes.Length > 0))
|
||||
{
|
||||
for (int i = 0; i < AllArchetypes.Length; i++)
|
||||
{
|
||||
var arch = AllArchetypes[i]; //save the extensions first..
|
||||
if (arch._BaseArchetypeDef.extensions.Count1 > 0)
|
||||
{
|
||||
arch._BaseArchetypeDef.extensions = mb.AddWrapperArrayPtr(arch.Extensions);
|
||||
}
|
||||
}
|
||||
|
||||
MetaPOINTER[] ptrs = new MetaPOINTER[AllArchetypes.Length];
|
||||
for (int i = 0; i < AllArchetypes.Length; i++)
|
||||
{
|
||||
var arch = AllArchetypes[i];
|
||||
switch (arch)
|
||||
{
|
||||
case TimeArchetype t:
|
||||
ptrs[i] = mb.AddItemPtr(MetaName.CTimeArchetypeDef, t._TimeArchetypeDef);
|
||||
break;
|
||||
case MloArchetype m:
|
||||
try
|
||||
{
|
||||
m._MloArchetypeDef._MloArchetypeDef.entities = mb.AddWrapperArrayPtr(m.entities);
|
||||
m._MloArchetypeDef._MloArchetypeDef.rooms = mb.AddWrapperArray(m.rooms);
|
||||
m._MloArchetypeDef._MloArchetypeDef.portals = mb.AddWrapperArray(m.portals);
|
||||
m._MloArchetypeDef._MloArchetypeDef.entitySets = mb.AddWrapperArray(m.entitySets);
|
||||
m._MloArchetypeDef._MloArchetypeDef.timeCycleModifiers = mb.AddItemArrayPtr(MetaName.CTimeCycleModifier, m.timeCycleModifiers);
|
||||
}
|
||||
catch/* (Exception e)*/
|
||||
{
|
||||
//todo: log save error.
|
||||
}
|
||||
ptrs[i] = mb.AddItemPtr(MetaName.CMloArchetypeDef, m._MloArchetypeDef);
|
||||
break;
|
||||
case Archetype a:
|
||||
ptrs[i] = mb.AddItemPtr(MetaName.CBaseArchetypeDef, a._BaseArchetypeDef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mapTypes.archetypes = mb.AddPointerArray(ptrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapTypes.archetypes = new Array_StructurePointer();
|
||||
}
|
||||
|
||||
if (CompositeEntityTypes != null && CompositeEntityTypes.Length > 0)
|
||||
{
|
||||
var cptrs = new MetaPOINTER[CompositeEntityTypes.Length];
|
||||
|
||||
for (int i = 0; i < cptrs.Length; i++)
|
||||
{
|
||||
var cet = CompositeEntityTypes[i];
|
||||
cptrs[i] = mb.AddItemPtr(MetaName.CCompositeEntityType, cet);
|
||||
}
|
||||
mapTypes.compositeEntityTypes = mb.AddItemArrayPtr(MetaName.CCompositeEntityType, cptrs);
|
||||
}
|
||||
|
||||
mapTypes.name = NameHash;
|
||||
mapTypes.dependencies = new Array_uint(); // is this never used? possibly a todo?
|
||||
|
||||
mb.AddStructureInfo(MetaName.CMapTypes);
|
||||
mb.AddStructureInfo(MetaName.CBaseArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CMloArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CTimeArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CCompositeEntityType);
|
||||
mb.AddStructureInfo(MetaName.CMloRoomDef);
|
||||
mb.AddStructureInfo(MetaName.CMloPortalDef);
|
||||
mb.AddStructureInfo(MetaName.CMloEntitySet);
|
||||
|
||||
if ((AllArchetypes != null && AllArchetypes.Length > 0))
|
||||
{
|
||||
mb.AddEnumInfo((MetaName)1991964615); // ASSET_TYPE_
|
||||
}
|
||||
|
||||
if ((AllArchetypes != null) && (AllArchetypes.Any(x => x is MloArchetype m && m.entities.Length > 0)))
|
||||
{
|
||||
mb.AddStructureInfo(MetaName.CEntityDef);
|
||||
mb.AddEnumInfo((MetaName)1264241711); //LODTYPES_
|
||||
mb.AddEnumInfo((MetaName)648413703); //PRI_
|
||||
}
|
||||
|
||||
mb.AddItem(MetaName.CMapTypes, mapTypes);
|
||||
|
||||
Meta meta = mb.GetMeta();
|
||||
byte[] data = ResourceBuilder.Build(meta, 2);
|
||||
|
||||
HasChanged = false;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Load(byte[] data)
|
||||
{
|
||||
@@ -94,12 +199,12 @@ namespace CodeWalker.GameFiles
|
||||
Meta = rd.ReadBlock<Meta>();
|
||||
|
||||
|
||||
CMapTypes = MetaTypes.GetTypedData<CMapTypes>(Meta, MetaName.CMapTypes);
|
||||
_CMapTypes = MetaTypes.GetTypedData<CMapTypes>(Meta, MetaName.CMapTypes);
|
||||
|
||||
|
||||
List<Archetype> allarchs = new List<Archetype>();
|
||||
|
||||
var ptrs = MetaTypes.GetPointerArray(Meta, CMapTypes.archetypes);
|
||||
var ptrs = MetaTypes.GetPointerArray(Meta, _CMapTypes.archetypes);
|
||||
if (ptrs != null)
|
||||
{
|
||||
for (int i = 0; i < ptrs.Length; i++)
|
||||
@@ -151,7 +256,8 @@ namespace CodeWalker.GameFiles
|
||||
AllArchetypes = allarchs.ToArray();
|
||||
|
||||
|
||||
Extensions = MetaTypes.GetExtensions(Meta, CMapTypes.extensions);
|
||||
Extensions = MetaTypes.GetExtensions(Meta, _CMapTypes.extensions);
|
||||
|
||||
if (Extensions != null)
|
||||
{ }
|
||||
|
||||
@@ -163,11 +269,11 @@ namespace CodeWalker.GameFiles
|
||||
//CEntityDefs = MetaTypes.GetTypedDataArray<CEntityDef>(Meta, MetaName.CEntityDef);
|
||||
|
||||
|
||||
CompositeEntityTypes = MetaTypes.ConvertDataArray<CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, CMapTypes.compositeEntityTypes);
|
||||
CompositeEntityTypes = MetaTypes.ConvertDataArray<CCompositeEntityType>(Meta, MetaName.CCompositeEntityType, _CMapTypes.compositeEntityTypes);
|
||||
if (CompositeEntityTypes != null)
|
||||
{ }
|
||||
|
||||
NameHash = CMapTypes.name;
|
||||
NameHash = _CMapTypes.name;
|
||||
if (NameHash == 0)
|
||||
{
|
||||
int ind = entry.NameLower.LastIndexOf('.');
|
||||
@@ -241,122 +347,39 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
}
|
||||
|
||||
public void AddArchetype(Archetype arch)
|
||||
|
||||
public void AddArchetype(Archetype archetype)
|
||||
{
|
||||
List<Archetype> allArchs = new List<Archetype>();
|
||||
if (AllArchetypes == null)
|
||||
AllArchetypes = new Archetype[0];
|
||||
|
||||
if (AllArchetypes != null)
|
||||
allArchs.AddRange(AllArchetypes);
|
||||
|
||||
allArchs.Add(arch);
|
||||
|
||||
AllArchetypes = allArchs.ToArray();
|
||||
List<Archetype> archetypes = AllArchetypes.ToList();
|
||||
archetype.Ytyp = this;
|
||||
archetypes.Add(archetype);
|
||||
AllArchetypes = archetypes.ToArray();
|
||||
}
|
||||
|
||||
public void RemoveArchetype(Archetype arch)
|
||||
public Archetype AddArchetype()
|
||||
{
|
||||
List<Archetype> allArchs = new List<Archetype>();
|
||||
|
||||
if (AllArchetypes != null)
|
||||
allArchs.AddRange(AllArchetypes);
|
||||
|
||||
if (allArchs.Contains(arch))
|
||||
allArchs.Remove(arch);
|
||||
|
||||
AllArchetypes = allArchs.ToArray();
|
||||
var a = new Archetype();
|
||||
a._BaseArchetypeDef.assetType = Unk_1991964615.ASSET_TYPE_DRAWABLE;
|
||||
a._BaseArchetypeDef.lodDist = 60;
|
||||
a._BaseArchetypeDef.hdTextureDist = 15;
|
||||
a.Ytyp = this;
|
||||
AddArchetype(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
public byte[] Save()
|
||||
public bool RemoveArchetype(Archetype archetype)
|
||||
{
|
||||
MetaBuilder mb = new MetaBuilder();
|
||||
|
||||
var mdb = mb.EnsureBlock(MetaName.CMapTypes);
|
||||
|
||||
CMapTypes mapTypes = CMapTypes;
|
||||
|
||||
if((AllArchetypes != null) && (AllArchetypes.Length > 0))
|
||||
List<Archetype> archetypes = AllArchetypes.ToList();
|
||||
if (archetypes.Remove(archetype))
|
||||
{
|
||||
MetaPOINTER[] archPtrs = new MetaPOINTER[AllArchetypes.Length];
|
||||
|
||||
for(int i=0; i<AllArchetypes.Length; i++)
|
||||
{
|
||||
var arch = AllArchetypes[i];
|
||||
arch._BaseArchetypeDef.extensions = mb.AddWrapperArrayPtr(arch.Extensions);
|
||||
}
|
||||
|
||||
for (int i = 0; i < archPtrs.Length; i++)
|
||||
{
|
||||
var arch = AllArchetypes[i];
|
||||
|
||||
if (arch is MloArchetype)
|
||||
{
|
||||
var mloArch = arch as MloArchetype;
|
||||
|
||||
mloArch._BaseMloArchetypeDef._MloArchetypeDef.entities = mb.AddWrapperArrayPtr(mloArch.entities);
|
||||
mloArch._BaseMloArchetypeDef._MloArchetypeDef.rooms = mb.AddWrapperArray(mloArch.rooms);
|
||||
mloArch._BaseMloArchetypeDef._MloArchetypeDef.portals = mb.AddWrapperArray(mloArch.portals);
|
||||
mloArch._BaseMloArchetypeDef._MloArchetypeDef.entitySets = mb.AddWrapperArray(mloArch.entitySets);
|
||||
mloArch._BaseMloArchetypeDef._MloArchetypeDef.timeCycleModifiers = mb.AddItemArrayPtr(MetaName.CTimeCycleModifier, mloArch.timeCycleModifiers);
|
||||
|
||||
archPtrs[i] = mb.AddItemPtr(MetaName.CMloArchetypeDef, mloArch.BaseMloArchetypeDef);
|
||||
|
||||
}
|
||||
else if (arch is TimeArchetype)
|
||||
{
|
||||
var timeArch = arch as TimeArchetype;
|
||||
archPtrs[i] = mb.AddItemPtr(MetaName.CTimeArchetypeDef, timeArch.TimeArchetypeDef);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
archPtrs[i] = mb.AddItemPtr(MetaName.CBaseArchetypeDef, arch.BaseArchetypeDef);
|
||||
}
|
||||
}
|
||||
|
||||
mapTypes.archetypes = mb.AddPointerArray(archPtrs);
|
||||
AllArchetypes = archetypes.ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if((CompositeEntityTypes != null) && (CompositeEntityTypes.Length > 0))
|
||||
{
|
||||
MetaPOINTER[] cetPtrs = new MetaPOINTER[CompositeEntityTypes.Length] ;
|
||||
|
||||
for (int i = 0; i < cetPtrs.Length; i++)
|
||||
{
|
||||
var cet = CompositeEntityTypes[i];
|
||||
cetPtrs[i] = mb.AddItemPtr(MetaName.CCompositeEntityType, cet);
|
||||
}
|
||||
|
||||
mapTypes.compositeEntityTypes = mb.AddItemArrayPtr(MetaName.CCompositeEntityType, cetPtrs);
|
||||
}
|
||||
|
||||
mb.AddItem(MetaName.CMapTypes, mapTypes);
|
||||
|
||||
mb.AddStructureInfo(MetaName.CMapTypes);
|
||||
mb.AddStructureInfo(MetaName.CBaseArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CMloArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CTimeArchetypeDef);
|
||||
mb.AddStructureInfo(MetaName.CMloRoomDef);
|
||||
mb.AddStructureInfo(MetaName.CMloPortalDef);
|
||||
mb.AddStructureInfo(MetaName.CMloEntitySet);
|
||||
mb.AddStructureInfo(MetaName.CCompositeEntityType);
|
||||
|
||||
mb.AddEnumInfo((MetaName)1991964615);
|
||||
mb.AddEnumInfo((MetaName)1294270217);
|
||||
mb.AddEnumInfo((MetaName)1264241711);
|
||||
mb.AddEnumInfo((MetaName)648413703);
|
||||
mb.AddEnumInfo((MetaName)3573596290);
|
||||
mb.AddEnumInfo((MetaName)700327466);
|
||||
mb.AddEnumInfo((MetaName)193194928);
|
||||
mb.AddEnumInfo((MetaName)2266515059);
|
||||
|
||||
Meta = mb.GetMeta();
|
||||
|
||||
byte[] data = ResourceBuilder.Build(Meta, 2); //ymap is version 2...
|
||||
|
||||
return data;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1804,116 +1804,6 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
|
||||
|
||||
public void InitYmapEntityArchetypes(YmapFile file)
|
||||
{
|
||||
if (file == null) return;
|
||||
if (file.AllEntities != null)
|
||||
{
|
||||
for (int i = 0; i < file.AllEntities.Length; i++)
|
||||
{
|
||||
var ent = file.AllEntities[i];
|
||||
var arch = GetArchetype(ent.CEntityDef.archetypeName);
|
||||
ent.SetArchetype(arch);
|
||||
|
||||
if (ent.MloInstance != null)
|
||||
{
|
||||
var entities = ent.MloInstance.Entities;
|
||||
if (entities != null)
|
||||
{
|
||||
for (int j = 0; j < entities.Length; j++)
|
||||
{
|
||||
var ient = entities[j];
|
||||
var iarch = GetArchetype(ient.CEntityDef.archetypeName);
|
||||
ient.SetArchetype(iarch);
|
||||
if (iarch == null)
|
||||
{ } //can't find archetype - des stuff eg {des_prologue_door}
|
||||
}
|
||||
|
||||
|
||||
//update archetype room AABB's.. bad to have this here? where else to put it?
|
||||
var mloa = arch as MloArchetype;
|
||||
if (mloa != null)
|
||||
{
|
||||
Vector3 mlobbmin = Vector3.Zero;
|
||||
Vector3 mlobbmax = Vector3.Zero;
|
||||
Vector3[] c = new Vector3[8];
|
||||
var rooms = mloa.rooms;
|
||||
if (rooms != null)
|
||||
{
|
||||
for (int j = 0; j < rooms.Length; j++)
|
||||
{
|
||||
var room = rooms[j];
|
||||
if ((room.AttachedObjects == null) || (room.AttachedObjects.Length == 0)) continue;
|
||||
Vector3 min = new Vector3(float.MaxValue);
|
||||
Vector3 max = new Vector3(float.MinValue);
|
||||
for (int k = 0; k < room.AttachedObjects.Length; k++)
|
||||
{
|
||||
var objid = room.AttachedObjects[k];
|
||||
if (objid < entities.Length)
|
||||
{
|
||||
var rooment = entities[objid];
|
||||
if ((rooment != null) && (rooment.Archetype != null))
|
||||
{
|
||||
var earch = rooment.Archetype;
|
||||
var pos = rooment._CEntityDef.position;
|
||||
var ori = rooment.Orientation;
|
||||
Vector3 abmin = earch.BBMin * rooment.Scale; //entity box
|
||||
Vector3 abmax = earch.BBMax * rooment.Scale;
|
||||
c[0] = abmin;
|
||||
c[1] = new Vector3(abmin.X, abmin.Y, abmax.Z);
|
||||
c[2] = new Vector3(abmin.X, abmax.Y, abmin.Z);
|
||||
c[3] = new Vector3(abmin.X, abmax.Y, abmax.Z);
|
||||
c[4] = new Vector3(abmax.X, abmin.Y, abmin.Z);
|
||||
c[5] = new Vector3(abmax.X, abmin.Y, abmax.Z);
|
||||
c[6] = new Vector3(abmax.X, abmax.Y, abmin.Z);
|
||||
c[7] = abmax;
|
||||
for (int n = 0; n < 8; n++)
|
||||
{
|
||||
Vector3 corn = ori.Multiply(c[n]) + pos;
|
||||
min = Vector3.Min(min, corn);
|
||||
max = Vector3.Max(max, corn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
room.BBMin_CW = min;
|
||||
room.BBMax_CW = max;
|
||||
mlobbmin = Vector3.Min(mlobbmin, min);
|
||||
mlobbmax = Vector3.Max(mlobbmax, max);
|
||||
}
|
||||
}
|
||||
mloa.BBMin = mlobbmin;
|
||||
mloa.BBMax = mlobbmax;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
if (file.GrassInstanceBatches != null)
|
||||
{
|
||||
for (int i = 0; i < file.GrassInstanceBatches.Length; i++)
|
||||
{
|
||||
var batch = file.GrassInstanceBatches[i];
|
||||
batch.Archetype = GetArchetype(batch.Batch.archetypeName);
|
||||
}
|
||||
}
|
||||
|
||||
if (file.TimeCycleModifiers != null)
|
||||
{
|
||||
for (int i = 0; i < file.TimeCycleModifiers.Length; i++)
|
||||
{
|
||||
var tcm = file.TimeCycleModifiers[i];
|
||||
World.TimecycleMod wtcm;
|
||||
if (TimeCycleModsDict.TryGetValue(tcm.CTimeCycleModifier.name.Hash, out wtcm))
|
||||
{
|
||||
tcm.TimeCycleModData = wtcm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1955,8 +1845,9 @@ namespace CodeWalker.GameFiles
|
||||
if (req.Loaded) AddTextureLookups(req as YtdFile);
|
||||
break;
|
||||
case GameFileType.Ymap:
|
||||
req.Loaded = LoadFile(req as YmapFile);
|
||||
if (req.Loaded) InitYmapEntityArchetypes(req as YmapFile);
|
||||
YmapFile y = req as YmapFile;
|
||||
req.Loaded = LoadFile(y);
|
||||
if (req.Loaded) y.InitYmapEntityArchetypes(this);
|
||||
break;
|
||||
case GameFileType.Yft:
|
||||
req.Loaded = LoadFile(req as YftFile);
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace CodeWalker.GameFiles
|
||||
public virtual MetaName Type => MetaName.CBaseArchetypeDef;
|
||||
|
||||
public CBaseArchetypeDef _BaseArchetypeDef;
|
||||
public CBaseArchetypeDef BaseArchetypeDef { get { return _BaseArchetypeDef; } set { _BaseArchetypeDef = value; } }
|
||||
public CBaseArchetypeDef BaseArchetypeDef => _BaseArchetypeDef; // for browsing.
|
||||
|
||||
public MetaHash Hash { get; set; }
|
||||
public YtypFile Ytyp { get; set; }
|
||||
@@ -31,16 +31,16 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
|
||||
|
||||
public string Name
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
return _BaseArchetypeDef.name.ToString();
|
||||
}
|
||||
}
|
||||
public string AssetName
|
||||
public string AssetName
|
||||
{
|
||||
get
|
||||
get
|
||||
{
|
||||
return _BaseArchetypeDef.assetName.ToString();
|
||||
}
|
||||
@@ -49,7 +49,7 @@ namespace CodeWalker.GameFiles
|
||||
|
||||
protected void InitVars(ref CBaseArchetypeDef arch)
|
||||
{
|
||||
BaseArchetypeDef = arch;
|
||||
_BaseArchetypeDef = arch;
|
||||
Hash = arch.assetName;
|
||||
if (Hash.Hash == 0) Hash = arch.name;
|
||||
DrawableDict = arch.drawableDictionary;
|
||||
@@ -83,10 +83,8 @@ namespace CodeWalker.GameFiles
|
||||
public class TimeArchetype : Archetype
|
||||
{
|
||||
public override MetaName Type => MetaName.CTimeArchetypeDef;
|
||||
|
||||
public CTimeArchetypeDefData _TimeArchetypeDef;
|
||||
public CTimeArchetypeDefData TimeArchetypeDef { get { return _TimeArchetypeDef; } set { _TimeArchetypeDef = value; } }
|
||||
|
||||
public CTimeArchetypeDef _TimeArchetypeDef;
|
||||
public CTimeArchetypeDef TimeArchetypeDef => _TimeArchetypeDef; // for browsing.
|
||||
|
||||
public uint TimeFlags { get; set; }
|
||||
public bool[] ActiveHours { get; set; }
|
||||
@@ -98,9 +96,9 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
Ytyp = ytyp;
|
||||
InitVars(ref arch._BaseArchetypeDef);
|
||||
TimeArchetypeDef = arch.TimeArchetypeDef;
|
||||
_TimeArchetypeDef = arch;
|
||||
|
||||
TimeFlags = _TimeArchetypeDef.timeFlags;
|
||||
TimeFlags = arch.TimeArchetypeDef.timeFlags;
|
||||
ActiveHours = new bool[24];
|
||||
ActiveHoursText = new string[24];
|
||||
for (int i = 0; i < 24; i++)
|
||||
@@ -128,11 +126,10 @@ namespace CodeWalker.GameFiles
|
||||
{
|
||||
public override MetaName Type => MetaName.CMloArchetypeDef;
|
||||
|
||||
public CMloArchetypeDef _BaseMloArchetypeDef;
|
||||
public CMloArchetypeDef BaseMloArchetypeDef { get { return _BaseMloArchetypeDef; } set { _BaseMloArchetypeDef = value; } }
|
||||
|
||||
public CMloArchetypeDefData _MloArchetypeDef;
|
||||
public CMloArchetypeDefData MloArchetypeDef { get { return _MloArchetypeDef; } set { _MloArchetypeDef = value; } }
|
||||
public CMloArchetypeDef MloArchetypeDef => _MloArchetypeDef; // for browsing.
|
||||
public CMloArchetypeDef _MloArchetypeDef;
|
||||
public CMloArchetypeDefData _MloArchetypeDefData;
|
||||
|
||||
public MCEntityDef[] entities { get; set; }
|
||||
public MCMloRoomDef[] rooms { get; set; }
|
||||
@@ -140,37 +137,147 @@ namespace CodeWalker.GameFiles
|
||||
public MCMloEntitySet[] entitySets { get; set; }
|
||||
public CMloTimeCycleModifier[] timeCycleModifiers { get; set; }
|
||||
|
||||
|
||||
public void Init(YtypFile ytyp, ref CMloArchetypeDef arch)
|
||||
{
|
||||
Ytyp = ytyp;
|
||||
InitVars(ref arch._BaseArchetypeDef);
|
||||
BaseMloArchetypeDef = arch;
|
||||
MloArchetypeDef = arch.MloArchetypeDef;
|
||||
_MloArchetypeDef = arch;
|
||||
_MloArchetypeDefData = arch.MloArchetypeDef;
|
||||
}
|
||||
|
||||
public bool AddEntity(YmapEntityDef ent, int roomIndex)
|
||||
{
|
||||
if (ent == null) return false;
|
||||
|
||||
// entity already exists in our array. so we'll just add
|
||||
// it to the instanced entities list and continue.
|
||||
MloInstanceData mloInstance = ent.MloParent?.MloInstance;
|
||||
MCEntityDef ymcent = mloInstance?.TryGetArchetypeEntity(ent);
|
||||
if (ymcent != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (roomIndex > rooms.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"Room index {roomIndex} exceeds the amount of rooms in {Name}.");
|
||||
}
|
||||
|
||||
var mcEntityDef = new MCEntityDef(ref ent._CEntityDef, this);
|
||||
|
||||
// Add the new entity def to the entities list.
|
||||
AddEntity(ent, mcEntityDef);
|
||||
|
||||
// Update the attached objects in the room index specified.
|
||||
AttachEntityToRoom(ent, roomIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
// attaches the specified ymap entity index to the room at roomIndex.
|
||||
private void AttachEntityToRoom(YmapEntityDef ent, int roomIndex)
|
||||
{
|
||||
if (roomIndex > rooms.Length)
|
||||
{
|
||||
return; // the room index is bigger than the rooms we have...
|
||||
}
|
||||
var attachedObjs = rooms[roomIndex].AttachedObjects?.ToList() ?? new List<uint>();
|
||||
attachedObjs.Add((uint)ent.Index);
|
||||
rooms[roomIndex].AttachedObjects = attachedObjs.ToArray();
|
||||
}
|
||||
|
||||
// Adds an entity to the entities array and then set's the index of the
|
||||
// ymap entity to the index of the new MCEntityDef.
|
||||
private void AddEntity(YmapEntityDef ent, MCEntityDef mcEntityDef)
|
||||
{
|
||||
if (ent == null || mcEntityDef == null) return; // no entity?...
|
||||
// initialize the array.
|
||||
if (entities == null) entities = new MCEntityDef[0];
|
||||
|
||||
List<MCEntityDef> entList = entities.ToList();
|
||||
entList.Add(mcEntityDef);
|
||||
ent.Index = entList.IndexOf(mcEntityDef);
|
||||
entities = entList.ToArray();
|
||||
}
|
||||
|
||||
public bool RemoveEntity(YmapEntityDef ent)
|
||||
{
|
||||
if (ent.Index >= entities.Length) return false;
|
||||
|
||||
MCEntityDef delent = entities[ent.Index];
|
||||
MloInstanceData inst = ent.MloParent?.MloInstance;
|
||||
if (inst == null) return false;
|
||||
|
||||
if (delent != null)
|
||||
{
|
||||
MCEntityDef[] newentities = new MCEntityDef[entities.Length - 1];
|
||||
bool didDel = false;
|
||||
int index = 0;
|
||||
int delIndex = 0;
|
||||
for (int i = 0; i < entities.Length; i++)
|
||||
{
|
||||
if (entities[i] == delent)
|
||||
{
|
||||
delIndex = i;
|
||||
didDel = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
newentities[index] = entities[i];
|
||||
YmapEntityDef ymapEntityDef = inst.TryGetYmapEntity(newentities[index]);
|
||||
if (ymapEntityDef != null) ymapEntityDef.Index = index;
|
||||
index++;
|
||||
}
|
||||
entities = newentities;
|
||||
|
||||
if (didDel) FixRoomIndexes(delIndex);
|
||||
return didDel;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void FixRoomIndexes(int deletedIndex)
|
||||
{
|
||||
foreach (var room in rooms)
|
||||
{
|
||||
List<uint> newAttachedObjects = new List<uint>();
|
||||
if (room.AttachedObjects == null)
|
||||
continue;
|
||||
foreach (var objIndex in room.AttachedObjects)
|
||||
{
|
||||
if (objIndex == deletedIndex) continue;
|
||||
if (objIndex > deletedIndex)
|
||||
newAttachedObjects.Add(objIndex - 1); // move the index back so it matches the index in the entitiy array.
|
||||
else newAttachedObjects.Add(objIndex); // else just add the index to the attached objects.
|
||||
}
|
||||
room.AttachedObjects = newAttachedObjects.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadChildren(Meta meta)
|
||||
{
|
||||
var centities = MetaTypes.ConvertDataArray<CEntityDef>(meta, MetaName.CEntityDef, _MloArchetypeDef.entities);
|
||||
var centities = MetaTypes.ConvertDataArray<CEntityDef>(meta, MetaName.CEntityDef, _MloArchetypeDefData.entities);
|
||||
if (centities != null)
|
||||
{
|
||||
entities = new MCEntityDef[centities.Length];
|
||||
for (int i = 0; i < centities.Length; i++)
|
||||
{
|
||||
entities[i] = new MCEntityDef(meta, centities[i]);
|
||||
entities[i] = new MCEntityDef(meta, ref centities[i]) { Archetype = this };
|
||||
}
|
||||
}
|
||||
|
||||
var crooms = MetaTypes.ConvertDataArray<CMloRoomDef>(meta, MetaName.CMloRoomDef, _MloArchetypeDef.rooms);
|
||||
var crooms = MetaTypes.ConvertDataArray<CMloRoomDef>(meta, MetaName.CMloRoomDef, _MloArchetypeDefData.rooms);
|
||||
if (crooms != null)
|
||||
{
|
||||
rooms = new MCMloRoomDef[crooms.Length];
|
||||
for (int i = 0; i < crooms.Length; i++)
|
||||
{
|
||||
rooms[i] = new MCMloRoomDef(meta, crooms[i]);
|
||||
rooms[i] = new MCMloRoomDef(meta, crooms[i]) { Archetype = this, Index = i };
|
||||
}
|
||||
}
|
||||
|
||||
var cportals = MetaTypes.ConvertDataArray<CMloPortalDef>(meta, MetaName.CMloPortalDef, _MloArchetypeDef.portals);
|
||||
var cportals = MetaTypes.ConvertDataArray<CMloPortalDef>(meta, MetaName.CMloPortalDef, _MloArchetypeDefData.portals);
|
||||
if (cportals != null)
|
||||
{
|
||||
portals = new MCMloPortalDef[cportals.Length];
|
||||
@@ -180,7 +287,7 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
}
|
||||
|
||||
var centitySets = MetaTypes.ConvertDataArray<CMloEntitySet>(meta, MetaName.CMloEntitySet, _MloArchetypeDef.entitySets);
|
||||
var centitySets = MetaTypes.ConvertDataArray<CMloEntitySet>(meta, MetaName.CMloEntitySet, _MloArchetypeDefData.entitySets);
|
||||
if (centitySets != null)
|
||||
{
|
||||
entitySets = new MCMloEntitySet[centitySets.Length];
|
||||
@@ -191,14 +298,44 @@ namespace CodeWalker.GameFiles
|
||||
}
|
||||
|
||||
|
||||
timeCycleModifiers = MetaTypes.ConvertDataArray<CMloTimeCycleModifier>(meta, MetaName.CMloTimeCycleModifier, _MloArchetypeDef.timeCycleModifiers);
|
||||
timeCycleModifiers = MetaTypes.ConvertDataArray<CMloTimeCycleModifier>(meta, MetaName.CMloTimeCycleModifier, _MloArchetypeDefData.timeCycleModifiers);
|
||||
|
||||
}
|
||||
|
||||
public MCMloRoomDef GetEntityRoom(MCEntityDef ent)
|
||||
{
|
||||
int objectIndex = -1;
|
||||
for (int i = 0; i < entities.Length; i++)
|
||||
{
|
||||
MCEntityDef e = entities[i];
|
||||
if (e == ent)
|
||||
{
|
||||
objectIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (objectIndex == -1) return null;
|
||||
|
||||
MCMloRoomDef room = null;
|
||||
for (int i = 0; i < rooms.Length; i++)
|
||||
{
|
||||
MCMloRoomDef r = rooms[i];
|
||||
for (int j = 0; j < r.AttachedObjects.Length; j++)
|
||||
{
|
||||
uint ind = r.AttachedObjects[j];
|
||||
if (ind == objectIndex)
|
||||
{
|
||||
room = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (room != null) break;
|
||||
}
|
||||
|
||||
return room;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public class MloInstanceData
|
||||
{
|
||||
@@ -208,7 +345,12 @@ namespace CodeWalker.GameFiles
|
||||
public uint[] defaultEntitySets { get; set; }
|
||||
|
||||
public YmapEntityDef[] Entities { get; set; }
|
||||
public Dictionary<MetaHash, MloInstanceEntitySet> EntitySets { get; set; }
|
||||
|
||||
public MloInstanceData()
|
||||
{
|
||||
EntitySets = new Dictionary<MetaHash, MloInstanceEntitySet>();
|
||||
}
|
||||
|
||||
public void CreateYmapEntities(YmapEntityDef owner, MloArchetype mloa)
|
||||
{
|
||||
@@ -234,27 +376,182 @@ namespace CodeWalker.GameFiles
|
||||
var entitySet = entitySets[i];
|
||||
if (entitySet.Entities != null)
|
||||
{
|
||||
EntitySets[entitySet._Data.name] = new MloInstanceEntitySet(entitySet, this);
|
||||
MloInstanceEntitySet instset = EntitySets[entitySet._Data.name];
|
||||
for (int j = 0; j < entitySet.Entities.Length; j++)
|
||||
{
|
||||
YmapEntityDef e = CreateYmapEntity(owner, entitySet.Entities[j], lasti);
|
||||
e.MloEntitySet = entitySet;
|
||||
entlist.Add(e);
|
||||
EntitySets[entitySet._Data.name].Entities.Add(e);
|
||||
e.MloEntitySet = instset;
|
||||
lasti++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultEntitySets != null)
|
||||
if ((defaultEntitySets != null) && (entitySets != null))
|
||||
{
|
||||
for (var i = 0; i < defaultEntitySets.Length; i++)
|
||||
{
|
||||
uint index = defaultEntitySets[i];
|
||||
if (index >= entitySets.Length) continue;
|
||||
MCMloEntitySet set = entitySets[index];
|
||||
MloInstanceEntitySet instset = EntitySets[set._Data.name];
|
||||
instset.Visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
Entities = entlist.ToArray();
|
||||
}
|
||||
|
||||
private YmapEntityDef CreateYmapEntity(YmapEntityDef owner, MCEntityDef ment, int i)
|
||||
public void InitYmapEntityArchetypes(GameFileCache gfc)
|
||||
{
|
||||
YmapEntityDef e = new YmapEntityDef(null, i, ref ment._Data);
|
||||
if (Owner == null) return;
|
||||
var arch = Owner.Archetype;
|
||||
|
||||
if (Entities != null)
|
||||
{
|
||||
for (int j = 0; j < Entities.Length; j++)
|
||||
{
|
||||
var ient = Entities[j];
|
||||
var iarch = gfc.GetArchetype(ient.CEntityDef.archetypeName);
|
||||
ient.SetArchetype(iarch);
|
||||
|
||||
if (iarch == null)
|
||||
{ } //can't find archetype - des stuff eg {des_prologue_door}
|
||||
}
|
||||
|
||||
UpdateBBs(arch);
|
||||
}
|
||||
|
||||
if (EntitySets != null)
|
||||
{
|
||||
foreach (var entitySet in EntitySets)
|
||||
{
|
||||
var entities = entitySet.Value.Entities;
|
||||
if (entities == null) continue;
|
||||
|
||||
for (int i = 0; i < entities.Count; i++)
|
||||
{
|
||||
var ient = entities[i];
|
||||
var iarch = gfc.GetArchetype(ient.CEntityDef.archetypeName);
|
||||
ient.SetArchetype(iarch);
|
||||
|
||||
if (iarch == null)
|
||||
{ } //can't find archetype - des stuff eg {des_prologue_door}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateBBs(Archetype arch)
|
||||
{
|
||||
//update archetype room AABB's.. bad to have this here? where else to put it?
|
||||
var mloa = arch as MloArchetype;
|
||||
if (mloa != null)
|
||||
{
|
||||
Vector3 mlobbmin = Vector3.Zero;
|
||||
Vector3 mlobbmax = Vector3.Zero;
|
||||
Vector3[] c = new Vector3[8];
|
||||
var rooms = mloa.rooms;
|
||||
if (rooms != null)
|
||||
{
|
||||
for (int j = 0; j < rooms.Length; j++)
|
||||
{
|
||||
var room = rooms[j];
|
||||
if ((room.AttachedObjects == null) || (room.AttachedObjects.Length == 0)) continue;
|
||||
Vector3 min = new Vector3(float.MaxValue);
|
||||
Vector3 max = new Vector3(float.MinValue);
|
||||
for (int k = 0; k < room.AttachedObjects.Length; k++)
|
||||
{
|
||||
var objid = room.AttachedObjects[k];
|
||||
if (objid < Entities.Length)
|
||||
{
|
||||
var rooment = Entities[objid];
|
||||
if ((rooment != null) && (rooment.Archetype != null))
|
||||
{
|
||||
var earch = rooment.Archetype;
|
||||
var pos = rooment._CEntityDef.position;
|
||||
var ori = rooment.Orientation;
|
||||
Vector3 abmin = earch.BBMin * rooment.Scale; //entity box
|
||||
Vector3 abmax = earch.BBMax * rooment.Scale;
|
||||
c[0] = abmin;
|
||||
c[1] = new Vector3(abmin.X, abmin.Y, abmax.Z);
|
||||
c[2] = new Vector3(abmin.X, abmax.Y, abmin.Z);
|
||||
c[3] = new Vector3(abmin.X, abmax.Y, abmax.Z);
|
||||
c[4] = new Vector3(abmax.X, abmin.Y, abmin.Z);
|
||||
c[5] = new Vector3(abmax.X, abmin.Y, abmax.Z);
|
||||
c[6] = new Vector3(abmax.X, abmax.Y, abmin.Z);
|
||||
c[7] = abmax;
|
||||
for (int n = 0; n < 8; n++)
|
||||
{
|
||||
Vector3 corn = ori.Multiply(c[n]) + pos;
|
||||
min = Vector3.Min(min, corn);
|
||||
max = Vector3.Max(max, corn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
room.BBMin_CW = min;
|
||||
room.BBMax_CW = max;
|
||||
mlobbmin = Vector3.Min(mlobbmin, min);
|
||||
mlobbmax = Vector3.Max(mlobbmax, max);
|
||||
}
|
||||
}
|
||||
mloa.BBMin = mlobbmin;
|
||||
mloa.BBMax = mlobbmax;
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteEntity(YmapEntityDef ent)
|
||||
{
|
||||
if (Entities == null)
|
||||
{
|
||||
throw new NullReferenceException("The Entities list returned null in our MloInstanceData. This could be an issue with initialization. The MloInstance probably doesn't exist.");
|
||||
}
|
||||
|
||||
if (ent.Index >= Entities.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("The index of the entity was greater than the amount of entities that exist in this MloInstance. Likely an issue with initializion.");
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
YmapEntityDef[] newentities = new YmapEntityDef[Entities.Length - 1];
|
||||
YmapEntityDef delentity = Entities[ent.Index];
|
||||
bool del = false;
|
||||
|
||||
for (int i = 0; i < Entities.Length; i++)
|
||||
{
|
||||
if (Entities[i] == delentity)
|
||||
{
|
||||
del = true;
|
||||
continue;
|
||||
}
|
||||
newentities[index] = Entities[i];
|
||||
newentities[index].Index = index;
|
||||
index++;
|
||||
}
|
||||
if (!del)
|
||||
throw new ArgumentException("The entity specified was not found in this MloInstance. It cannot be deleted.");
|
||||
|
||||
if (Owner.Archetype is MloArchetype arch)
|
||||
{
|
||||
if (arch.RemoveEntity(ent))
|
||||
{
|
||||
if (ent.MloEntitySet != null)
|
||||
if (!ent.MloEntitySet.Entities.Remove(ent))
|
||||
return false;
|
||||
// Delete was successful...
|
||||
Entities = newentities;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw new InvalidCastException("The owner of this archetype's archetype definition is not an MloArchetype.");
|
||||
}
|
||||
|
||||
public YmapEntityDef CreateYmapEntity(YmapEntityDef owner, MCEntityDef ment, int index)
|
||||
{
|
||||
YmapEntityDef e = new YmapEntityDef(null, index, ref ment._Data);
|
||||
e.Extensions = ment.Extensions;
|
||||
e.MloRefPosition = e.Position;
|
||||
e.MloRefOrientation = e.Orientation;
|
||||
@@ -263,9 +560,31 @@ namespace CodeWalker.GameFiles
|
||||
e.Orientation = Quaternion.Multiply(owner.Orientation, e.MloRefOrientation);
|
||||
e.UpdateWidgetPosition();
|
||||
e.UpdateWidgetOrientation();
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public MCEntityDef TryGetArchetypeEntity(YmapEntityDef ymapEntity)
|
||||
{
|
||||
if (ymapEntity == null) return null;
|
||||
if (Owner?.Archetype == null) return null;
|
||||
if (!(Owner.Archetype is MloArchetype mloa)) return null;
|
||||
if (ymapEntity.Index >= mloa.entities.Length) return null;
|
||||
|
||||
var entity = mloa.entities[ymapEntity.Index];
|
||||
return entity;
|
||||
}
|
||||
|
||||
public YmapEntityDef TryGetYmapEntity(MCEntityDef mcEntity)
|
||||
{
|
||||
if (mcEntity == null) return null;
|
||||
if (Owner?.Archetype == null) return null;
|
||||
if (!(Owner.Archetype is MloArchetype mloa)) return null;
|
||||
|
||||
var index = Array.FindIndex(mloa.entities, x => x == mcEntity);
|
||||
if (index == -1 || index >= Entities.Length) return null;
|
||||
return Entities[index];
|
||||
}
|
||||
|
||||
public void SetPosition(Vector3 pos)
|
||||
{
|
||||
@@ -289,17 +608,52 @@ namespace CodeWalker.GameFiles
|
||||
for (int i = 0; i < Entities.Length; i++)
|
||||
{
|
||||
YmapEntityDef e = Entities[i];
|
||||
e.Position = Owner.Position + Owner.Orientation.Multiply(e.MloRefPosition);
|
||||
e.Orientation = Quaternion.Multiply(Owner.Orientation, e.MloRefOrientation);
|
||||
e.UpdateWidgetPosition();
|
||||
e.UpdateWidgetOrientation();
|
||||
UpdateEntity(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UpdateEntity(YmapEntityDef e)
|
||||
{
|
||||
e.Position = Owner.Position + Owner.Orientation.Multiply(e.MloRefPosition);
|
||||
e.Orientation = Quaternion.Multiply(Owner.Orientation, e.MloRefOrientation);
|
||||
e.UpdateWidgetPosition();
|
||||
e.UpdateWidgetOrientation();
|
||||
}
|
||||
|
||||
public void AddEntity(YmapEntityDef e)
|
||||
{
|
||||
if (e == null) return;
|
||||
if (Entities == null) Entities = new YmapEntityDef[0];
|
||||
var entities = Entities.ToList();
|
||||
entities.Add(e);
|
||||
Entities = entities.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public class MloInstanceEntitySet
|
||||
{
|
||||
public MloInstanceEntitySet(MCMloEntitySet entSet, MloInstanceData instance)
|
||||
{
|
||||
EntitySet = entSet;
|
||||
Entities = new List<YmapEntityDef>();
|
||||
Instance = instance;
|
||||
}
|
||||
|
||||
public MCMloEntitySet EntitySet { get; set; }
|
||||
public List<YmapEntityDef> Entities { get; set; }
|
||||
public MloInstanceData Instance { get; set; }
|
||||
|
||||
public uint[] Locations
|
||||
{
|
||||
get { return EntitySet?.Locations; }
|
||||
set { if (EntitySet != null) EntitySet.Locations = value; }
|
||||
}
|
||||
|
||||
public bool Visible { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2428,7 +2428,9 @@ namespace CodeWalker.GameFiles
|
||||
public Vector3 BBMax { get { return (_Data.bbMax); } }
|
||||
public Vector3 BBMin_CW { get; set; }
|
||||
public Vector3 BBMax_CW { get; set; }
|
||||
|
||||
|
||||
public MloArchetype Archetype { get; set; }
|
||||
public int Index { get; set; }
|
||||
|
||||
public MCMloRoomDef() { }
|
||||
public MCMloRoomDef(Meta meta, CMloRoomDef data)
|
||||
@@ -2610,7 +2612,7 @@ namespace CodeWalker.GameFiles
|
||||
Entities = new MCEntityDef[ents.Length];
|
||||
for (int i = 0; i < ents.Length; i++)
|
||||
{
|
||||
Entities[i] = new MCEntityDef(meta, ents[i]);
|
||||
Entities[i] = new MCEntityDef(meta, ref ents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2750,23 +2752,26 @@ namespace CodeWalker.GameFiles
|
||||
[TC(typeof(EXP))] public class MCEntityDef : MetaWrapper
|
||||
{
|
||||
public CEntityDef _Data;
|
||||
public CEntityDef Data { get { return _Data; } }
|
||||
public CEntityDef Data { get { return _Data; } set { _Data = value; } }
|
||||
public MetaWrapper[] Extensions { get; set; }
|
||||
|
||||
|
||||
public MCEntityDef() { }
|
||||
public MloArchetype Archetype { get; set; } // for browsing/reference purposes
|
||||
|
||||
public MCEntityDef(MCEntityDef copy)
|
||||
{
|
||||
if (copy != null)
|
||||
{
|
||||
_Data = copy.Data;
|
||||
}
|
||||
if (copy != null) _Data = copy.Data;
|
||||
}
|
||||
public MCEntityDef(Meta meta, CEntityDef d)
|
||||
public MCEntityDef(Meta meta, ref CEntityDef d)
|
||||
{
|
||||
_Data = d;
|
||||
Extensions = MetaTypes.GetExtensions(meta, _Data.extensions);
|
||||
}
|
||||
public MCEntityDef(ref CEntityDef d, MloArchetype arch)
|
||||
{
|
||||
_Data = d;
|
||||
Archetype = arch;
|
||||
}
|
||||
|
||||
public override void Load(Meta meta, MetaPOINTER ptr)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user