2017-09-21 18:33:05 +08:00
using SharpDX ;
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace CodeWalker.GameFiles
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Archetype
{
2017-09-28 12:28:09 +08:00
public virtual MetaName Type = > MetaName . CBaseArchetypeDef ;
public CBaseArchetypeDef _BaseArchetypeDef ;
2018-12-03 16:54:04 +08:00
public CBaseArchetypeDef BaseArchetypeDef = > _BaseArchetypeDef ; // for browsing.
2017-09-28 12:28:09 +08:00
2017-09-21 18:33:05 +08:00
public MetaHash Hash { get ; set ; }
public YtypFile Ytyp { get ; set ; }
public MetaHash DrawableDict { get ; set ; }
public MetaHash TextureDict { get ; set ; }
public MetaHash ClipDict { get ; set ; }
public Vector3 BBMin { get ; set ; }
public Vector3 BBMax { get ; set ; }
public Vector3 BSCenter { get ; set ; }
public float BSRadius { get ; set ; }
public float LodDist { get ; set ; }
public MetaWrapper [ ] Extensions { get ; set ; }
2017-09-28 12:28:09 +08:00
2017-09-21 18:33:05 +08:00
2018-12-03 16:54:04 +08:00
public string Name
2017-09-21 18:33:05 +08:00
{
2018-12-03 16:54:04 +08:00
get
2017-09-21 18:33:05 +08:00
{
2017-09-28 12:28:09 +08:00
return _BaseArchetypeDef . name . ToString ( ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-12-03 16:54:04 +08:00
public string AssetName
2017-09-21 18:33:05 +08:00
{
2018-12-03 16:54:04 +08:00
get
2017-09-21 18:33:05 +08:00
{
2017-09-28 12:28:09 +08:00
return _BaseArchetypeDef . assetName . ToString ( ) ;
2017-09-21 18:33:05 +08:00
}
}
2017-09-28 12:28:09 +08:00
protected void InitVars ( ref CBaseArchetypeDef arch )
2017-09-21 18:33:05 +08:00
{
2018-12-03 16:54:04 +08:00
_BaseArchetypeDef = arch ;
2017-09-21 18:33:05 +08:00
Hash = arch . assetName ;
if ( Hash . Hash = = 0 ) Hash = arch . name ;
DrawableDict = arch . drawableDictionary ;
TextureDict = arch . textureDictionary ;
ClipDict = arch . clipDictionary ;
BBMin = arch . bbMin ;
BBMax = arch . bbMax ;
BSCenter = arch . bsCentre ;
BSRadius = arch . bsRadius ;
2017-09-28 00:24:21 +08:00
LodDist = arch . lodDist ;
}
public void Init ( YtypFile ytyp , ref CBaseArchetypeDef arch )
{
Ytyp = ytyp ;
InitVars ( ref arch ) ;
2017-09-21 18:33:05 +08:00
}
2017-09-28 12:28:09 +08:00
public virtual bool IsActive ( float hour )
2017-09-21 18:33:05 +08:00
{
2017-09-28 12:28:09 +08:00
return true ;
2017-09-21 18:33:05 +08:00
}
2017-09-28 12:28:09 +08:00
public override string ToString ( )
{
return _BaseArchetypeDef . ToString ( ) ;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TimeArchetype : Archetype
{
public override MetaName Type = > MetaName . CTimeArchetypeDef ;
2018-12-03 16:54:04 +08:00
public CTimeArchetypeDef _TimeArchetypeDef ;
public CTimeArchetypeDef TimeArchetypeDef = > _TimeArchetypeDef ; // for browsing.
2017-09-28 12:28:09 +08:00
public uint TimeFlags { get ; set ; }
public bool [ ] ActiveHours { get ; set ; }
public string [ ] ActiveHoursText { get ; set ; }
2018-12-16 19:32:33 +08:00
public bool ExtraFlag { get { return ( ( TimeFlags > > 24 ) & 1 ) = = 1 ; } }
2017-09-28 12:28:09 +08:00
public void Init ( YtypFile ytyp , ref CTimeArchetypeDef arch )
2017-09-21 18:33:05 +08:00
{
Ytyp = ytyp ;
2017-09-28 00:24:21 +08:00
InitVars ( ref arch . _BaseArchetypeDef ) ;
2018-12-03 16:54:04 +08:00
_TimeArchetypeDef = arch ;
2017-09-28 12:28:09 +08:00
2018-12-03 16:54:04 +08:00
TimeFlags = arch . TimeArchetypeDef . timeFlags ;
2018-12-16 19:32:33 +08:00
UpdateActiveHours ( ) ;
}
public override bool IsActive ( float hour )
{
if ( ActiveHours = = null ) return true ;
int h = ( ( int ) hour ) % 24 ;
if ( ( h < 0 ) | | ( h > 23 ) ) return true ;
return ActiveHours [ h ] ;
}
public void UpdateActiveHours ( )
{
if ( ActiveHours = = null )
{
ActiveHours = new bool [ 24 ] ;
ActiveHoursText = new string [ 24 ] ;
}
2017-09-28 12:28:09 +08:00
for ( int i = 0 ; i < 24 ; i + + )
{
bool v = ( ( TimeFlags > > i ) & 1 ) = = 1 ;
ActiveHours [ i ] = v ;
int nxth = ( i < 23 ) ? ( i + 1 ) : 0 ;
string hrs = string . Format ( "{0:00}:00 - {1:00}:00" , i , nxth ) ;
ActiveHoursText [ i ] = ( hrs + ( v ? " - On" : " - Off" ) ) ;
}
2017-09-21 18:33:05 +08:00
}
2018-12-16 19:32:33 +08:00
public void SetTimeFlags ( uint flags )
2017-09-21 18:33:05 +08:00
{
2018-12-16 19:32:33 +08:00
TimeFlags = flags ;
_TimeArchetypeDef . _TimeArchetypeDef . timeFlags = flags ;
UpdateActiveHours ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-12-16 19:32:33 +08:00
2017-09-21 18:33:05 +08:00
}
2017-09-28 12:28:09 +08:00
public class MloArchetype : Archetype
2017-09-21 18:33:05 +08:00
{
2017-09-28 12:28:09 +08:00
public override MetaName Type = > MetaName . CMloArchetypeDef ;
2018-07-27 04:16:54 +08:00
2018-12-03 16:54:04 +08:00
public CMloArchetypeDef MloArchetypeDef = > _MloArchetypeDef ; // for browsing.
public CMloArchetypeDef _MloArchetypeDef ;
public CMloArchetypeDefData _MloArchetypeDefData ;
2017-09-28 12:28:09 +08:00
2018-01-02 12:37:09 +08:00
public MCEntityDef [ ] entities { get ; set ; }
public MCMloRoomDef [ ] rooms { get ; set ; }
public MCMloPortalDef [ ] portals { get ; set ; }
public MCMloEntitySet [ ] entitySets { get ; set ; }
2017-09-21 18:33:05 +08:00
public CMloTimeCycleModifier [ ] timeCycleModifiers { get ; set ; }
2017-09-28 12:28:09 +08:00
2018-12-03 16:54:04 +08:00
2017-09-28 12:28:09 +08:00
public void Init ( YtypFile ytyp , ref CMloArchetypeDef arch )
{
Ytyp = ytyp ;
InitVars ( ref arch . _BaseArchetypeDef ) ;
2018-12-03 16:54:04 +08:00
_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 ( ) ;
}
2017-09-28 12:28:09 +08:00
}
2018-01-02 12:37:09 +08:00
public void LoadChildren ( Meta meta )
{
2018-12-03 16:54:04 +08:00
var centities = MetaTypes . ConvertDataArray < CEntityDef > ( meta , MetaName . CEntityDef , _MloArchetypeDefData . entities ) ;
2018-01-02 12:37:09 +08:00
if ( centities ! = null )
{
entities = new MCEntityDef [ centities . Length ] ;
for ( int i = 0 ; i < centities . Length ; i + + )
{
2018-12-03 16:54:04 +08:00
entities [ i ] = new MCEntityDef ( meta , ref centities [ i ] ) { Archetype = this } ;
2018-01-02 12:37:09 +08:00
}
}
2018-12-03 16:54:04 +08:00
var crooms = MetaTypes . ConvertDataArray < CMloRoomDef > ( meta , MetaName . CMloRoomDef , _MloArchetypeDefData . rooms ) ;
2018-01-02 12:37:09 +08:00
if ( crooms ! = null )
{
rooms = new MCMloRoomDef [ crooms . Length ] ;
for ( int i = 0 ; i < crooms . Length ; i + + )
{
2018-12-03 16:54:04 +08:00
rooms [ i ] = new MCMloRoomDef ( meta , crooms [ i ] ) { Archetype = this , Index = i } ;
2018-01-02 12:37:09 +08:00
}
}
2018-12-03 16:54:04 +08:00
var cportals = MetaTypes . ConvertDataArray < CMloPortalDef > ( meta , MetaName . CMloPortalDef , _MloArchetypeDefData . portals ) ;
2018-01-02 12:37:09 +08:00
if ( cportals ! = null )
{
portals = new MCMloPortalDef [ cportals . Length ] ;
for ( int i = 0 ; i < cportals . Length ; i + + )
{
portals [ i ] = new MCMloPortalDef ( meta , cportals [ i ] ) ;
}
}
2018-12-03 16:54:04 +08:00
var centitySets = MetaTypes . ConvertDataArray < CMloEntitySet > ( meta , MetaName . CMloEntitySet , _MloArchetypeDefData . entitySets ) ;
2018-01-02 12:37:09 +08:00
if ( centitySets ! = null )
{
entitySets = new MCMloEntitySet [ centitySets . Length ] ;
for ( int i = 0 ; i < centitySets . Length ; i + + )
{
entitySets [ i ] = new MCMloEntitySet ( meta , centitySets [ i ] ) ;
}
}
2018-12-03 16:54:04 +08:00
timeCycleModifiers = MetaTypes . ConvertDataArray < CMloTimeCycleModifier > ( meta , MetaName . CMloTimeCycleModifier , _MloArchetypeDefData . timeCycleModifiers ) ;
2018-01-02 12:37:09 +08:00
}
2018-12-03 16:54:04 +08:00
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 ;
2017-09-21 18:33:05 +08:00
2018-12-03 16:54:04 +08:00
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 ;
}
2017-09-28 12:28:09 +08:00
2018-12-03 16:54:04 +08:00
return room ;
}
}
2017-09-28 12:28:09 +08:00
2017-09-21 18:33:05 +08:00
[TypeConverter(typeof(ExpandableObjectConverter))]
2017-09-28 00:24:21 +08:00
public class MloInstanceData
2017-09-21 18:33:05 +08:00
{
2017-09-28 00:24:21 +08:00
public YmapEntityDef Owner { get ; set ; }
public CMloInstanceDef _Instance ;
public CMloInstanceDef Instance { get { return _Instance ; } set { _Instance = value ; } }
2018-01-02 06:44:45 +08:00
public uint [ ] defaultEntitySets { get ; set ; }
2017-09-28 00:24:21 +08:00
public YmapEntityDef [ ] Entities { get ; set ; }
2018-12-03 16:54:04 +08:00
public Dictionary < MetaHash , MloInstanceEntitySet > EntitySets { get ; set ; }
2017-09-28 00:24:21 +08:00
2018-12-03 16:54:04 +08:00
public MloInstanceData ( )
{
EntitySets = new Dictionary < MetaHash , MloInstanceEntitySet > ( ) ;
}
2017-09-21 18:33:05 +08:00
2017-09-28 12:28:09 +08:00
public void CreateYmapEntities ( YmapEntityDef owner , MloArchetype mloa )
2017-09-21 18:33:05 +08:00
{
2017-09-28 00:24:21 +08:00
Owner = owner ;
2017-09-21 18:33:05 +08:00
if ( owner = = null ) return ;
2017-09-28 12:28:09 +08:00
if ( mloa . entities = = null ) return ;
var ec = mloa . entities . Length ;
2018-01-02 14:43:47 +08:00
var entlist = new List < YmapEntityDef > ( ) ;
2017-09-28 00:24:21 +08:00
for ( int i = 0 ; i < ec ; i + + )
2017-09-21 18:33:05 +08:00
{
2018-01-02 14:43:47 +08:00
YmapEntityDef e = CreateYmapEntity ( owner , mloa . entities [ i ] , i ) ;
entlist . Add ( e ) ;
2017-09-28 00:24:21 +08:00
}
2018-01-02 12:37:09 +08:00
2018-01-02 14:43:47 +08:00
int lasti = ec ;
2018-01-02 12:37:09 +08:00
var entitySets = mloa . entitySets ;
if ( entitySets ! = null )
{
2018-01-02 14:43:47 +08:00
for ( int i = 0 ; i < entitySets . Length ; i + + )
{
var entitySet = entitySets [ i ] ;
if ( entitySet . Entities ! = null )
{
2018-12-03 16:54:04 +08:00
EntitySets [ entitySet . _Data . name ] = new MloInstanceEntitySet ( entitySet , this ) ;
MloInstanceEntitySet instset = EntitySets [ entitySet . _Data . name ] ;
2018-01-02 14:43:47 +08:00
for ( int j = 0 ; j < entitySet . Entities . Length ; j + + )
{
YmapEntityDef e = CreateYmapEntity ( owner , entitySet . Entities [ j ] , lasti ) ;
2018-12-03 16:54:04 +08:00
EntitySets [ entitySet . _Data . name ] . Entities . Add ( e ) ;
e . MloEntitySet = instset ;
2018-01-02 14:43:47 +08:00
lasti + + ;
}
}
}
}
2018-12-03 16:54:04 +08:00
if ( ( defaultEntitySets ! = null ) & & ( entitySets ! = null ) )
2018-01-02 14:43:47 +08:00
{
2018-12-03 16:54:04 +08:00
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 ;
}
2018-01-02 12:37:09 +08:00
}
2018-01-02 14:43:47 +08:00
Entities = entlist . ToArray ( ) ;
}
2018-12-03 16:54:04 +08:00
public void InitYmapEntityArchetypes ( GameFileCache gfc )
2018-01-02 14:43:47 +08:00
{
2018-12-03 16:54:04 +08:00
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 ) ;
2018-01-02 14:43:47 +08:00
e . Extensions = ment . Extensions ;
e . MloRefPosition = e . Position ;
e . MloRefOrientation = e . Orientation ;
e . MloParent = owner ;
e . Position = owner . Position + owner . Orientation . Multiply ( e . MloRefPosition ) ;
e . Orientation = Quaternion . Multiply ( owner . Orientation , e . MloRefOrientation ) ;
e . UpdateWidgetPosition ( ) ;
e . UpdateWidgetOrientation ( ) ;
2018-12-03 16:54:04 +08:00
2018-01-02 14:43:47 +08:00
return e ;
2017-09-28 00:24:21 +08:00
}
2017-09-21 18:33:05 +08:00
2018-12-03 16:54:04 +08:00
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 ] ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 06:44:45 +08:00
public void SetPosition ( Vector3 pos )
{
var cent = _Instance . CEntityDef ;
cent . position = pos ;
_Instance . CEntityDef = cent ; //TODO: maybe find a better way of doing this...
}
public void SetOrientation ( Quaternion ori )
{
var cent = _Instance . CEntityDef ;
cent . rotation = new Vector4 ( ori . X , ori . Y , ori . Z , ori . W ) ; //mlo instances have oppposite orientations to normal entities...
_Instance . CEntityDef = cent ; //TODO: maybe find a better way of doing this...
}
2017-09-28 00:24:21 +08:00
public void UpdateEntities ( )
{
if ( Entities = = null ) return ;
if ( Owner = = null ) return ;
for ( int i = 0 ; i < Entities . Length ; i + + )
{
YmapEntityDef e = Entities [ i ] ;
2018-12-03 16:54:04 +08:00
UpdateEntity ( e ) ;
2017-09-21 18:33:05 +08:00
}
2017-09-28 00:24:21 +08:00
2017-09-21 18:33:05 +08:00
}
2017-09-28 00:24:21 +08:00
2018-12-03 16:54:04 +08:00
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 ( ) ;
}
2018-12-16 19:32:33 +08:00
public void UpdateDefaultEntitySets ( )
{
var list = new List < uint > ( ) ;
var mloarch = Owner ? . Archetype as MloArchetype ;
for ( uint i = 0 ; i < mloarch . entitySets . Length ; i + + )
{
var entset = mloarch . entitySets [ i ] ;
MloInstanceEntitySet instset = null ;
EntitySets . TryGetValue ( entset . _Data . name , out instset ) ;
if ( instset ! = null )
{
if ( instset . Visible )
{
list . Add ( i ) ;
}
}
}
defaultEntitySets = list . ToArray ( ) ;
}
2018-12-03 16:54:04 +08:00
}
2017-09-28 00:24:21 +08:00
2018-12-03 16:54:04 +08:00
[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 ; }
}
2018-01-02 06:44:45 +08:00
2018-12-03 16:54:04 +08:00
public bool Visible { get ; set ; }
2017-09-21 18:33:05 +08:00
}
2017-09-28 00:24:21 +08:00
2017-09-21 18:33:05 +08:00
}