/// <summary> /// Add a child entity to this entity /// </summary> /// <param name="child">The entity</param> public void AddEntity(Entity child) { if (child.ParentContainer == null) { child.Init(); } else { child.ParentContainer.RemoveChild(child); } if (this is EntityGameView) { var view = this as EntityGameView; child.SetParentView(view); child.SetParent(view); } else if (this is Entity) { var parent = this as Entity; child.SetParentView(parent.GameView); child.SetParent(parent); } AddChild(child); }
private void OnMovementModeChanged() { switch (MovementMode) { case PlayerMovementMode.FirstPerson: _playerEntity.IsActive = true; _cameraEntity.SetParent(_playerEntity); _cameraEntity.EulerAngles = Vector3.Zero; _cameraTargetPosition = new Vector3(0, 0.6f, 0); break; case PlayerMovementMode.ThirdPerson: _playerEntity.IsActive = true; _cameraEntity.SetParent(_playerEntity); _cameraEntity.EulerAngles = Vector3.Zero; _cameraTargetPosition = new Vector3(0, 1, 3); break; case PlayerMovementMode.GodMode: _cameraEntity.SetParent(null); _playerEntity.IsActive = false; _cameraEntity.Position = _playerEntity.GlobalPosition + new Vector3(0, 1, 0); break; default: throw new ArgumentOutOfRangeException(); } }
void AddNewEntity() { Vector3 pos; UInt16 entKey = GameManager.instance.GetEntityKeyRandomly(); Entity ent = PoolingManager.InstantiateByPooling(entKey); if (ent != null) { ent.SetParent(this); ent.transform.localScale = Vector3.one; //int cnt = owner.entityList.Count + 1; if (squareData.reversal == true) { pos = new Vector3(0, -GameDatabase.instance.tileHeight, 0); } else { pos = new Vector3(0, GameDatabase.instance.tileHeight, 0); } ent.transform.localPosition = pos; ent.gameObject.SetActive(false); entityList.Add(ent); } }
private async Task SellTicketAndSetEntityToNextNode(Entity customerEntity) { IsProcessing = true; // TODO properly synchronize this to prevent threading issues var customer = customerEntity.GetBehavior <CustomerBehavior>(); if (customer == null) { // not a customer -> ignore customerEntity.SetParent(NextNode.Entity, Reasons.NotAllowed); ResetIsProcessingAndCheckForNextCustomer(); return; } if (!customer.Inventory.TryTakeItem(Items.Money, TicketPrice)) { // not enough money -> set forward customer.Entity.SetParent(NextNode.Entity, Reasons.DoesNotHaveRequiredItem); ResetIsProcessingAndCheckForNextCustomer(); return; } // enough money taken -> wait processing time, give ticket and set forward if (MaximumProcessingSeconds > 0) { var waitTime = TimeSpan.FromSeconds(new Random().Next(MinimumProcessingSeconds, MaximumProcessingSeconds)); await Timing.Delay(waitTime); } customer.Inventory.AddItem(Items.SkiTicket, 1); customer.Entity.IsEnabled = true; customer.Entity.SetParent(NextNode.Entity, Reasons.Processing.Finished, SetParentFlags.SuppressChildEnter); ResetIsProcessingAndCheckForNextCustomer(); }
public void DropEquipped() { Entity drop = Equipped; drop.SetParent(null); drop.Position = drop.Position + new Vector2(0.5f, 0); drop.transform.localScale = Vector3.one; }
public Wall(Scene scene, IList<Vector2> vertices) : base(scene, vertices) { SetBodyType(BodyType.Static); Entity entity = new Entity(scene); entity.AddModel(ModelFactory.CreatePolygon(vertices, new Vector3(0, 0, 1))); entity.SetParent(this); SetCollisionCategory(Category.All); }
public void ReplaceEntity() { if (entityList != null && entityList.Count > 0) { entity = entityList[entityList.Count - 1]; // entity.gameObject.SetActive(true); entityList.Remove(entity); entity.SetParent(this); } }
/// <summary> /// Add an entity that has the specified component in it /// </summary> /// <typeparam name="TComponent">The component</typeparam> /// <returns></returns> public TComponent Add <TComponent>() where TComponent : IComponent, new() { Entity entity = new Entity(); entity.Name = typeof(TComponent).Name; TComponent com = entity.AddComponent <TComponent>(); entity.SetParent(this); return(com); }
public void AddChild(string key, Entity child) { if (!childEntities.ContainsKey(key)) { childEntities[key] = new List <Entity>(); memory[key] = childEntities[key]; } childEntities[key].Add(child); child.SetParent(this); child.onEntityDied += RemoveChild; }
public override void Active() { base.Active(); //TODO 更新コンテナに自分を入れる overseeEntity.SetParent(entity); eagleDirection = (C_Switch3)entity.GetNormalComponent("C_Switch3"); moveAreaLeft = entity.transform.Position.X; moveAreaRight = moveAreaLeft + 500; }
public void SetAttachedEntity(Entity entity = null) { AttachedEntity = entity; if (AttachedEntity == null) { DestroyIcon(); } else { AttachedEntity.SetParent(PlayerEntity.Player); AttachedEntity.Hide(); CreateIcon(); } }
public Bullet(Scene scene, Vector2 position, Vector2 velocity) : base(scene, PolygonFactory.CreateNGon(3, 0.1f, new Vector2()), new Transform2(position)) { Entity = new Entity(Scene); SetVelocity(Transform2.CreateVelocity(velocity)); Entity.SetParent(this); Model model = ModelFactory.CreatePolygon(Vertices, new Vector3(0, 0, 1)); //Model model = ModelFactory.CreateArrow(new Vector3(0f, 0f, 1f), velocity.Normalized() * 0.1f, 0.1f, 0.3f, 0.15f); model.SetColor(new Vector3(1, 1, 0)); Entity.AddModel(model); OnCollision += Bullet_OnCollision; SetCollisionCategory(Category.Cat1); SetCollidesWith(~Category.Cat1); }
public void AddToSlot(Entity entity) { if (Equipped != null) { DropEquipped(); } if (entity != null) { entity.SetParent(Owner); entity.transform.SetParent(transform); entity.transform.localPosition = Vector3.zero; entity.transform.localScale = Vector3.one; entity.transform.localRotation = Quaternion.identity; Equipped = entity; } }
public bool TryLoad(Entity entityToLoad) { if (FreeSlots == 0) { return(false); } if (!HasDriver && !EntityCanBeDriver(entityToLoad) && FreeSlots == 1) { return(false); // cannot load non-driver into last slot } if (entityToLoad.HasBehavior <MovableBehavior>()) { entityToLoad.GetBehavior <MovableBehavior>().SetTarget(null); } entityToLoad.SetParent(Entity, TryLoadReason); _passengers.Add(entityToLoad); return(true); }
private void OnUpdate(EngineUpdateEventArgs args) { var thisPosition = Entity.GetBehavior <TransformBehavior>().Position; var targetPosition = Target?.GetBehavior <TransformBehavior>()?.Position ?? Vector3.Zero; if (Vector3.Distance(thisPosition, targetPosition) <= float.Epsilon) { lock (_lock) { if (_hasTargetReached) { return; } _hasTargetReached = true; var parentEnterResult = Entity.SetParent(Target, Reasons.TargetReached); _targetReached.OnNext(new TargetReachedEngineEventArgs(Engine.Engine.Current, Target, parentEnterResult)); } } else { if (_hasTargetReached) { _hasTargetReached = false; var location = _lastTarget?.GetImplementation <IGraphNode>()? .AdjacentEdges.FirstOrDefault( _ => (Equals(_.GetImplementation <IGraphEdge>().Start.Entity, _lastTarget) && Equals(_.GetImplementation <IGraphEdge>().End.Entity, Target)) || (Equals(_.GetImplementation <IGraphEdge>().End.Entity, _lastTarget) && Equals(_.GetImplementation <IGraphEdge>().Start.Entity, Target))); Entity.SetParent(location, Reasons.MovingStarted); } var movementVector = Vector3.Normalize(targetPosition - thisPosition); var movementFactor = Speed * (float)args.DeltaTime.TotalSeconds; var maxMovementFactor = Vector3.Distance(thisPosition, targetPosition); var newPosition = thisPosition + Math.Min(movementFactor, maxMovementFactor) * movementVector; Entity.GetBehavior <TransformBehavior>().Position = newPosition; } }
protected override void OnEnable() { screenContainer.renderer.isVisible = true; screenContainer.material.SetFloat("alpha", 1f); CoroutineExecutor.Add(Routine(), true); IEnumerator Routine() { var backBlack = new Entity().CreateComponent <Renderer>(); backBlack.SetParent(screenContainer.renderer); backBlack.Position = new Vector3(0f, 0f, -2f); backBlack.size = screenContainer.renderer.size; backBlack.onRender = (_, output) => Graphics.Clear(output, Color4.Black); GUIElement[] labelContainers = new GUIElement[data.captions.Length]; GUIElement[] labels = new GUIElement[data.captions.Length]; for (int i = 0; i < data.captions.Length; i++) { labelContainers[i] = GUIElement.CreateContainer(screenContainer.renderer, new Vector3(0f, (data.captions.Length - 1 - i * 2 + (i == 0 ? 0.2f : 0f)) * data.fontSize * data.interval, -3f), new Vector2(19.2f, 2f * data.fontSize), "Game/Alpha"); labels[i] = GUIElement.CreateEmpty(labelContainers[i].renderer, new Vector3(0f, 0f, 0f), new Vector2(19.2f, 2f * data.fontSize)); { var textBox = labels[i].Entity.CreateComponent <TextBox>(); textBox.InitFromRenderer(); textBox.CharHeight = i switch { 0 => 1f, _ => 0.8f, } *data.fontSize; textBox.Text = new TextColored(data.captions[i], new SColor(1f, 1f, 1f)); textBox.Align = ODEngine.Core.Text.TextAlign.Center; } labelContainers[i].material.SetFloat("alpha", 0f); } foreach (var i in CoroutineExecutor.ForTime(data.startDelay)) // Start delay { if (!isEnable) { Finish2(); yield break; } yield return(null); } if (data.isSimultaneous) // Labels fade in { foreach (var i in CoroutineExecutor.ForTime(data.fadeInTime)) { if (!isEnable) { Finish2(); yield break; } for (int j = 0; j < data.captions.Length; j++) { labelContainers[j].material.SetFloat("alpha", i * i); yield return(null); } } } else { for (int i = 0; i < data.captions.Length; i++) { foreach (var j in CoroutineExecutor.ForTime(data.fadeInTime)) { if (!isEnable) { Finish2(); yield break; } labelContainers[i].material.SetFloat("alpha", j * j); yield return(null); } } } foreach (var _ in CoroutineExecutor.ForTime(data.showTime)) // Show { if (!isEnable) { Finish2(); yield break; } yield return(null); } foreach (var i in CoroutineExecutor.ForTime(data.captionsFadeOutTime)) // Fade out { if (!isEnable) { Finish2(); yield break; } for (int j = 0; j < data.captions.Length; j++) { labelContainers[j].material.SetFloat("alpha", (1f - i) * (1f - i)); } yield return(null); } Finish2(); void Finish2() { for (int i = 0; i < data.captions.Length; i++) { labels[i].Entity.Destroy(); labelContainers[i].Entity.Destroy(); } } foreach (var i in CoroutineExecutor.ForTime(data.screenFadeOutTime)) { if (!isEnable) { Finish(); yield break; } screenContainer.material.SetFloat("alpha", (1f - i) * (1f - i)); yield return(null); } Finish(); void Finish() { backBlack.Entity.Destroy(); Disable(); } } }
public void StepTest7() { Scene scene = new Scene(); Actor actor = new Actor(scene, PolygonFactory.CreateRectangle(2, 2)); actor.SetTransform(new Transform2(new Vector2(1, 1))); actor.SetVelocity(Transform2.CreateVelocity(new Vector2(0, 3))); Entity entity = new Entity(scene); entity.SetParent(actor); FloatPortal enter = new FloatPortal(scene); enter.SetTransform(new Transform2(new Vector2(1, 2), 1, (float)Math.PI / 2)); //enter.SetVelocity(Transform2.CreateVelocity(new Vector2(1, 0))); FloatPortal exit = new FloatPortal(scene); exit.SetTransform(new Transform2(new Vector2(10, 10))); exit.SetVelocity(Transform2.CreateVelocity(new Vector2(10, 0))); enter.Linked = exit; exit.Linked = enter; PortalCommon.UpdateWorldTransform(scene); SimulationStep.Step(scene.GetAll().OfType<IPortalCommon>(), scene.GetAll().OfType<IPortal>(), 1, null); Assert.IsTrue(entity.GetTransform() == new Transform2()); Assert.IsTrue(entity.GetVelocity() == Transform2.CreateVelocity()); Assert.IsTrue(actor.GetTransform() == actor.WorldTransform); Assert.IsTrue(actor.GetVelocity() == actor.WorldVelocity); }
/// <summary> /// Creates a Scene from an EditorScene. Scene is intended for gameplay use. /// </summary> public static Scene Export(EditorScene level, Controller controller) { Scene scene = new Scene(); /*if (level.GetAll().OfType<EditorPlayer>().Count() > 0) { Camera2 camera = new Camera2(scene); camera.SetTransform(new Transform2(new Vector2(), 10, 0)); scene.SetActiveCamera(camera); if (level.ActiveCamera != null) { camera.Aspect = level.ActiveCamera.Aspect; } } else*/ { if (level.ActiveCamera != null) { ControllerCamera camera = level.ActiveCamera.ShallowClone(); camera.Scene = scene; scene.SetActiveCamera(camera); } } #region create background Model background = Game.ModelFactory.CreatePlane(); background.Texture = level.Renderer.GetTexture("grid.png"); background.SetColor(new Vector3(1, 1, 0.5f)); background.Transform.Position = new Vector3(0, 0, -5f); float size = 50; background.Transform.Scale = new Vector3(size, size, size); background.TransformUv.Size = size; Entity back = new Entity(scene, new Vector2(0f, 0f)); back.Name = "Background"; back.AddModel(background); back.IsPortalable = false; #endregion Dictionary<EditorObject, SceneNode> dictionary = new Dictionary<EditorObject, SceneNode>(); AnimationDriver animation = new AnimationDriver(); scene.SceneObjectList.Add(animation); List<EditorObject> editorObjects = level.GetAll().OfType<EditorObject>().ToList(); foreach (EditorObject e in editorObjects) { if (e is EditorPortal) { EditorPortal cast = (EditorPortal)e; Entity entity = new Entity(scene); entity.IsPortalable = false; entity.AddModel(ModelFactory.CreatePortal()); entity.ModelList[0].Transform.Position += new Vector3(0, 0, -2); if (cast.OnEdge) { FixturePortal portal = new FixturePortal(scene); portal.Name = cast.Name; dictionary.Add(cast, portal); entity.SetParent(portal); } else { FloatPortal portal = new FloatPortal(scene); portal.Name = cast.Name; portal.SetTransform(cast.GetTransform()); dictionary.Add(cast, portal); entity.SetParent(portal); if (cast.AnimatedTransform != null) { animation.Add(portal, cast.AnimatedTransform); portal.SetTransform(cast.AnimatedTransform.GetTransform(0)); } else { portal.SetTransform(cast.GetTransform()); } } } else if (e is EditorEntity) { EditorEntity cast = (EditorEntity)e; Entity clone = new Entity(scene); clone.Name = cast.Name; clone.AddModelRange(cast.Models); dictionary.Add(cast, clone); if (cast.AnimatedTransform != null) { animation.Add(clone, cast.AnimatedTransform); clone.SetTransform(cast.AnimatedTransform.GetTransform(0)); } else { clone.SetTransform(cast.GetTransform()); } } else if (e is IWall) { EditorObject cast = e; Transform2 t = cast.GetTransform(); Actor actor = new Actor(scene, ((IWall)e).Vertices, t); actor.Name = cast.Name; Transform2 tEntity = new Transform2(); Entity entity = new Entity(scene, tEntity); entity.Name = cast.Name; entity.SetParent(actor); if (e is EditorWall) { EditorWall castWall = (EditorWall)e; actor.SetBodyType(BodyType.Static); //actor.Vertices = castWall.Vertices; entity.AddModel(Game.ModelFactory.CreatePolygon(castWall.Vertices)); //entity.AddModel(Game.ModelFactory.CreateActorDebug(actor)); dictionary.Add(castWall, actor); } else if (e is EditorActor) { //actor.SetVelocity(new Transform2(new Vector2(0.2f, 0))); EditorActor castActor = (EditorActor)e; //actor.Vertices = castActor.Vertices; entity.AddModel(castActor.GetActorModel(castActor)); //entity.AddModel(Game.ModelFactory.CreateActorDebug(actor)); dictionary.Add(castActor, actor); } else { Debug.Assert(false); } if (cast.AnimatedTransform != null) { animation.Add(actor, cast.AnimatedTransform); actor.SetTransform(cast.AnimatedTransform.GetTransform(0)); actor.SetBodyType(BodyType.Kinematic); } else { actor.SetTransform(cast.GetTransform()); } } else if (e is EditorPlayer) { EditorPlayer cast = (EditorPlayer)e; Player player = new Player(controller); Vector2[] polygon = PolygonFactory.CreateNGon(6, 0.5f, new Vector2()); Actor actor = new Actor(scene, polygon); player.SetActor(actor); actor.SetTransform(new Transform2(cast.GetWorldTransform().Position)); //player.Camera = (Camera2)scene.ActiveCamera; Entity entity = new Entity(scene, new Transform2()); entity.Name = cast.Name; entity.SetParent(actor); entity.AddModel(Game.ModelFactory.CreatePolygon(polygon)); scene.SceneObjectList.Add(player); dictionary.Add(cast, player.Actor); } else { Debug.Assert(false); } } foreach (EditorObject e in editorObjects) { SceneNode parent = e.Parent == null ? null : dictionary[e.Parent]; SceneNode clone = dictionary[e]; clone.SetParent(parent); if (clone is IPortal) { if (clone is FixturePortal) { FixturePortal cast = (FixturePortal)clone; cast.SetPosition((IWall)parent, ((EditorPortal)e).PolygonTransform, e.GetTransform().Size, e.GetTransform().MirrorX); Debug.Assert(((IWall)parent).Vertices.Count > 0); IPortal portalEditor = (IPortal)e; if (portalEditor.Linked != null) { cast.Linked = (IPortal)dictionary[(EditorPortal)portalEditor.Linked]; } } else if (clone is FloatPortal) { FloatPortal cast = (FloatPortal)clone; IPortal portalEditor = (IPortal)e; if (portalEditor.Linked != null) { cast.Linked = (IPortal)dictionary[(EditorPortal)portalEditor.Linked]; } } } } PortalCommon.UpdateWorldTransform(scene); return scene; }
public Player(World world) { _inputSystem = GameInstance.GetService <InputSystem>(); _playerEntity = world.EntitySystem.CreateEntity(true); var mesh = new Mesh(GameInstance.GraphicsDevice, Primitives.GenerateQuadForYBillboard()); var diffuseTexture = GameInstance.Content.Load <Texture2D>(ResourceNames.Textures.DefaultGuy); var material = new Material { DiffuseTexture = diffuseTexture, UseTransparency = true, TexcoordScale = diffuseTexture.GetTexcoordsFromPixelCoords(32, 32), IsUnlit = true }; _modelEntityComponent = _playerEntity.AddComponent(new ModelEntityComponent(_playerEntity, mesh, material, true)); _cameraEntity = world.EntitySystem.CreateEntity(); _cameraEntity.SetParent(_playerEntity); var cameraComponent = _cameraEntity.AddComponent(new CameraEntityComponent(_cameraEntity, new Skybox(GameInstance) { Scale = 50, Texture = GameInstance.Content.Load <Texture2D>(ResourceNames.Textures.skybox_texture) })); cameraComponent.FarClipDistance = 50.0f; Camera = cameraComponent.Camera; Speed = 2.0f; RotationSpeed = 2f; var forward = Animation.CreateDiscrete(0.65f, new[] { diffuseTexture.GetTexcoordsFromPixelCoords(0, 0), diffuseTexture.GetTexcoordsFromPixelCoords(32, 0), diffuseTexture.GetTexcoordsFromPixelCoords(0, 0), diffuseTexture.GetTexcoordsFromPixelCoords(64, 0), }, t => _modelEntityComponent.Material.TexcoordOffset = t, true); var left = Animation.CreateDiscrete(0.65f, new[] { diffuseTexture.GetTexcoordsFromPixelCoords(0, 32), diffuseTexture.GetTexcoordsFromPixelCoords(32, 32), diffuseTexture.GetTexcoordsFromPixelCoords(0, 32), diffuseTexture.GetTexcoordsFromPixelCoords(64, 32), }, t => _modelEntityComponent.Material.TexcoordOffset = t, true); var right = Animation.CreateDiscrete(0.65f, new[] { diffuseTexture.GetTexcoordsFromPixelCoords(0, 96), diffuseTexture.GetTexcoordsFromPixelCoords(32, 96), diffuseTexture.GetTexcoordsFromPixelCoords(0, 96), diffuseTexture.GetTexcoordsFromPixelCoords(64, 96), }, t => _modelEntityComponent.Material.TexcoordOffset = t, true); var backward = Animation.CreateDiscrete(0.65f, new[] { diffuseTexture.GetTexcoordsFromPixelCoords(0, 64), diffuseTexture.GetTexcoordsFromPixelCoords(32, 64), diffuseTexture.GetTexcoordsFromPixelCoords(0, 64), diffuseTexture.GetTexcoordsFromPixelCoords(64, 64), }, t => _modelEntityComponent.Material.TexcoordOffset = t, true); _playerEntity.AddComponent(new FigureMovementAnimationComponent(_playerEntity, forward, backward, left, right)); _movementMode = PlayerMovementMode.ThirdPerson; _cameraEntity.Position = _cameraTargetPosition; var colliderComponent = new CollisionEntityComponent(_playerEntity, new Vector3(0.35f, 0.6f, 0.35f), new Vector3(0.0f, 0.3f, 0.0f), "Player") { ResolvesPosition = true, }; _playerEntity.AddComponent(colliderComponent); _playerEntity.Position = new Vector3(5, 0, 8); }
protected override DataStructures.MapObjects.Map GetFromStream(Stream stream, IEnumerable <string> modelDirs, out Image[] lightmaps) { BinaryReader reader = new BinaryReader(stream); if (reader.ReadFixedLengthString(Encoding.ASCII, 3) != "CBR") { throw new ProviderException("CBR file is corrupted/invalid!"); } uint revision = reader.ReadUInt32(); // Lightmaps bool lightmapped = reader.ReadByte() > (byte)Lightmapped.No; if (lightmapped) { lightmaps = new Image[4]; for (int i = 0; i < 4; i++) { lightmaps[i] = Image.FromStream(new MemoryStream(reader.ReadBytes(reader.ReadInt32()))); } } else { lightmaps = null; } // Texture dictionary int texSize = reader.ReadInt32(); string[] textures = new string[texSize]; for (int i = 0; i < texSize; i++) { textures[i] = reader.ReadNullTerminatedString(); } DataStructures.MapObjects.Map map = new DataStructures.MapObjects.Map(); map.WorldSpawn = new World(map.IDGenerator.GetNextObjectID()); // Solids List <MapObject> solids = new List <MapObject>(); int solidCount = reader.ReadInt32(); for (int i = 0; i < solidCount; i++) { Solid s = new Solid(map.IDGenerator.GetNextObjectID()); s.Colour = Colour.GetRandomBrushColour(); int faceCount = reader.ReadInt32(); for (int j = 0; j < faceCount; j++) { Face f = new Face(map.IDGenerator.GetNextFaceID()); f.Colour = s.Colour; f.Texture.Name = textures[reader.ReadInt32()]; f.Texture.UAxis = reader.ReadCoordinate(); f.Texture.VAxis = reader.ReadCoordinate(); f.Texture.XShift = reader.ReadDecimal(); f.Texture.YShift = reader.ReadDecimal(); f.Texture.XScale = reader.ReadDecimal(); f.Texture.YScale = reader.ReadDecimal(); f.Texture.Rotation = reader.ReadDecimal(); int vertexCount = reader.ReadInt32(); for (int k = 0; k < vertexCount; k++) { Vertex v = new Vertex(reader.ReadCoordinate(), f); if (lightmapped) { v.LMU = reader.ReadSingle(); v.LMV = reader.ReadSingle(); v.TextureU = (decimal)reader.ReadSingle(); v.TextureV = (decimal)reader.ReadSingle(); } f.Vertices.Add(v); } f.Plane = new Plane(f.Vertices[0].Location, f.Vertices[1].Location, f.Vertices[2].Location); f.Parent = s; s.Faces.Add(f); f.UpdateBoundingBox(); } s.SetParent(map.WorldSpawn, false); s.UpdateBoundingBox(false); solids.Add(s); } // Entities List <MapObject> entities = new List <MapObject>(0); string read; bool isStillSolid = true; for (int i = 0; i < 2; i++) { while ((read = reader.ReadNullTerminatedString()) != "") { List <Property> properties = new List <Property>(); byte propertyType; while ((propertyType = reader.ReadByte()) != 255) { properties.Add(new Property() { name = reader.ReadNullTerminatedString(), type = (VariableType)propertyType }); } // Entries int entitiesOfType = reader.ReadInt32(); entities.Capacity += entitiesOfType; for (int j = 0; j < entitiesOfType; j++) { Entity e = new Entity(map.IDGenerator.GetNextObjectID()); e.Colour = Colour.GetDefaultEntityColour(); e.ClassName = read; e.EntityData.Name = read; if (isStillSolid) { int entitySolids = reader.ReadInt32(); for (int k = 0; k < entitySolids; k++) { solids[reader.ReadInt32()].SetParent(e); } } e.SetParent(map.WorldSpawn); foreach (Property property in properties) { string propertyVal; switch (property.type) { case VariableType.Bool: propertyVal = reader.ReadBoolean() ? "Yes" : "No"; break; case VariableType.Color255: propertyVal = DataStructures.MapObjects.Property.FromColor(reader.ReadRGBAColour()); break; case VariableType.Float: propertyVal = reader.ReadSingle().ToString(); break; case VariableType.Integer: propertyVal = reader.ReadInt32().ToString(); break; case VariableType.String: propertyVal = reader.ReadNullTerminatedString(); break; case VariableType.Vector: propertyVal = DataStructures.MapObjects.Property.FromCoordinate(reader.ReadCoordinate()); break; case VariableType.Choices: // TODO: Bullshit throw new NotImplementedException(); default: propertyVal = ""; break; } e.EntityData.SetPropertyValue(property.name, propertyVal); } e.UpdateBoundingBox(); entities.Add(e); } } isStillSolid = false; } // CBRE ONLY // Visgroup dictionary Visgroup currentParentVisgroup = null; while (true) { byte hierarchyControl; Visgroup newGroup = null; while ((hierarchyControl = reader.ReadByte()) == HIERARCHY_PROCCEED) { newGroup = new Visgroup(); newGroup.Colour = Colour.GetRandomBrushColour(); newGroup.ID = reader.ReadInt32(); newGroup.Name = reader.ReadNullTerminatedString(); if (currentParentVisgroup != null) { newGroup.Parent = currentParentVisgroup; currentParentVisgroup.Children.Add(newGroup); } else { map.Visgroups.Add(newGroup); } } if (hierarchyControl == HIERARCHY_DOWN) { currentParentVisgroup = newGroup; } else if (currentParentVisgroup != null) { currentParentVisgroup = currentParentVisgroup.Parent; } else { break; } } // Solid visgroups foreach (Solid mo in solids) { ReadVisgroups(reader, mo); } // Entity visgroups foreach (Entity e in entities) { ReadVisgroups(reader, e); } // Groups int directWorldGroups = reader.ReadInt32(); for (int i = 0; i < directWorldGroups; i++) { Group currentParentGroup = new Group(map.IDGenerator.GetNextObjectID()); currentParentGroup.SetParent(map.WorldSpawn); while (true) { byte hierarchyControl; while ((hierarchyControl = reader.ReadByte()) > HIERARCHY_UP) { if (hierarchyControl == IDENTIFIER_ENTITY) { entities[reader.ReadInt32()].SetParent(currentParentGroup); } else { solids[reader.ReadInt32()].SetParent(currentParentGroup); } } if (hierarchyControl == HIERARCHY_DOWN) { Group newGroup = new Group(map.IDGenerator.GetNextObjectID()); newGroup.SetParent(currentParentGroup); currentParentGroup = newGroup; } else if (currentParentGroup.Parent != map.WorldSpawn) { currentParentGroup = (Group)currentParentGroup.Parent; } else { break; } } } stream.Close(); return(map); }
protected override NodeStatus Act(Entity entity, Memory memory) { // Count children List <Entity> children = memory[childrenKey] as List <Entity>; int childCount = children != null ? children.Count : 0; // Set job availability tags string tag = JOB_TAG + jobTitle; if (childCount < capacity) { if (!entity.tags.Contains(tag)) { entity.tags.Add(tag); } if (!entity.tags.Contains(HAS_JOB_TAG)) { entity.tags.Add(HAS_JOB_TAG); } } else { if (entity.tags.Contains(tag)) { entity.tags.Remove(tag); } if (entity.tags.Contains(HAS_JOB_TAG)) { entity.tags.Remove(HAS_JOB_TAG); } } // Go thru applicants and process them List <Entity> applicants = entity.childEntities.ContainsKey(jobTitle + APPLICANTS_TAG) ? entity.childEntities[jobTitle + APPLICANTS_TAG] : null; if (applicants == null || applicants.Count <= 0) { return(NodeStatus.Success); } else { int i = 0; while (i < applicants.Count) { Entity applicant = applicants[i]; if (childCount < capacity) { entity.AddChild(childrenKey, applicant); applicant.SetParent(entity); applicant.memory[Leaf_AcceptJob.GetApplicantStateKey(entity)] = Leaf_AcceptJob.ACCEPTED; applicant.TransformTo(data); childCount++; } else { applicant.memory[Leaf_AcceptJob.GetApplicantStateKey(entity)] = Leaf_AcceptJob.REJECTED; } i++; } applicants.Clear(); } return(NodeStatus.Success); }
protected override DataStructures.MapObjects.Map GetFromStream(Stream stream, IEnumerable <string> modelDirs, out Image[] lightmaps) { lightmaps = null; var map = new DataStructures.MapObjects.Map(); map.CordonBounds = new Box(Coordinate.One * -16384, Coordinate.One * 16384); BinaryReader br = new BinaryReader(stream); //header UInt16 mapVersion = br.ReadUInt16(); byte mapFlags = br.ReadByte(); Int32 nameCount = br.ReadInt32(); Int32 nameOffset = br.ReadInt32(); Int32 objectCount = br.ReadInt32(); Int32 objectOffset = br.ReadInt32(); //get names, needed to understand the objects List <string> names = new List <string>(); br.BaseStream.Seek(nameOffset, SeekOrigin.Begin); for (int i = 0; i < nameCount; i++) { string name = br.ReadNullTerminatedString(); names.Add(name); } //now we can parse the object table List <string> materials = new List <string>(); List <Tuple <int, string> > meshReferences = new List <Tuple <int, string> >(); Dictionary <int, Group> groups = new Dictionary <int, Group>(); Dictionary <int, int> visgroups = new Dictionary <int, int>(); br.BaseStream.Seek(objectOffset, SeekOrigin.Begin); long objectStartPos = br.BaseStream.Position; for (int i = 0; i < objectCount; i++) { int index = br.ReadInt32() - 1; int size = br.ReadInt32(); string name = null; if (index >= 0 && index < names.Count) { name = names[index]; } if (name == "group") { byte flags = br.ReadByte(); Int32 groupIndex = br.ReadInt32(); Group newGroup = new Group(map.IDGenerator.GetNextObjectID()); newGroup.SetParent(map.WorldSpawn); groups.Add(i, newGroup); } else if (name == "visgroup") { byte flags = br.ReadByte(); string groupName = names[br.ReadInt32() - 1]; byte colorR = br.ReadByte(); byte colorG = br.ReadByte(); byte colorB = br.ReadByte(); Visgroup newGroup = new Visgroup() { Name = groupName, ID = visgroups.Count + 1 }; newGroup.Colour = System.Drawing.Color.FromArgb(colorR, colorG, colorB); map.Visgroups.Add(newGroup); visgroups.Add(i, newGroup.ID); } else if (name == "meshreference") { byte flags = br.ReadByte(); Int32 groupNameInd = br.ReadInt32() - 1; Int32 objectNameInd = br.ReadInt32() - 1; byte limbCount = br.ReadByte(); meshReferences.Add(new Tuple <int, string>(i, names[objectNameInd])); } else if (name == "material") { byte materialFlags = br.ReadByte(); Int32 groupIndex = br.ReadInt32(); string objectName = names[br.ReadInt32() - 1]; Int32 extensionNameIndex = -1; if ((materialFlags & 2) != 0) { extensionNameIndex = br.ReadInt32(); //TODO: what the heck is this } materials.Add(objectName); } else { br.BaseStream.Seek(size, SeekOrigin.Current); } } br.BaseStream.Position = objectStartPos; for (int i = 0; i < objectCount; i++) { int index = br.ReadInt32() - 1; int size = br.ReadInt32(); string name = null; if (index >= 0 && index < names.Count) { name = names[index]; } if (name == "mesh") { Property newProperty; long startPos = br.BaseStream.Position; byte flags = br.ReadByte(); Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.ClassName = "model"; entity.EntityData.Name = "model"; entity.Colour = Colour.GetDefaultEntityColour(); Int32 keyCount = br.ReadInt32(); for (int j = 0; j < keyCount; j++) { Int32 keyNameInd = br.ReadInt32() - 1; Int32 keyValueInd = br.ReadInt32() - 1; if (names[keyNameInd] != "classname") { newProperty = new Property(); newProperty.Key = names[keyNameInd]; newProperty.Value = names[keyValueInd]; if (newProperty.Key == "file") { newProperty.Value = System.IO.Path.GetFileNameWithoutExtension(newProperty.Value); } entity.EntityData.Properties.Add(newProperty); } } Int32 groupIndex = br.ReadInt32() - 1; Int32 visgroupIndex = br.ReadInt32() - 1; if (visgroups.ContainsKey(visgroupIndex)) { entity.Visgroups.Add(visgroups[visgroupIndex]); } byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte(); Int32 meshRefIndex = br.ReadInt32() - 1; float x = br.ReadSingle(); float z = br.ReadSingle(); float y = br.ReadSingle(); if (entity != null) { entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z); } if (entity.EntityData.GetPropertyValue("file") == null) { newProperty = new Property(); newProperty.Key = "file"; newProperty.Value = meshReferences.Find(q => q.Item1 == meshRefIndex).Item2; entity.EntityData.Properties.Add(newProperty); } float pitch = br.ReadSingle(); float yaw = br.ReadSingle(); float roll = br.ReadSingle(); newProperty = new Property(); newProperty.Key = "angles"; newProperty.Value = pitch.ToString() + " " + yaw.ToString() + " " + roll.ToString(); entity.EntityData.Properties.Add(newProperty); float xScale = 1.0f; float yScale = 1.0f; float zScale = 1.0f; if ((flags & 1) == 0) { xScale = br.ReadSingle(); yScale = br.ReadSingle(); zScale = br.ReadSingle(); } newProperty = new Property(); newProperty.Key = "scale"; newProperty.Value = xScale.ToString() + " " + yScale.ToString() + " " + zScale.ToString(); entity.EntityData.Properties.Add(newProperty); br.BaseStream.Position += size - (br.BaseStream.Position - startPos); entity.UpdateBoundingBox(); if (groups.ContainsKey(groupIndex)) { entity.SetParent(groups[groupIndex]); } else { entity.SetParent(map.WorldSpawn); } } else if (name == "entity") { byte flags = br.ReadByte(); float x = br.ReadSingle(); float z = br.ReadSingle(); float y = br.ReadSingle(); Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.Colour = Colour.GetDefaultEntityColour(); entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z); Int32 keyCount = br.ReadInt32(); for (int j = 0; j < keyCount; j++) { Int32 keyNameInd = br.ReadInt32() - 1; Int32 keyValueInd = br.ReadInt32() - 1; if (names[keyNameInd] == "classname") { entity.ClassName = names[keyValueInd]; entity.EntityData.Name = names[keyValueInd]; } else { Property newProperty = new Property(); newProperty.Key = names[keyNameInd]; newProperty.Value = names[keyValueInd]; entity.EntityData.Properties.Add(newProperty); } } Int32 groupIndex = br.ReadInt32() - 1; Int32 visgroupIndex = br.ReadInt32() - 1; if (visgroups.ContainsKey(visgroupIndex)) { entity.Visgroups.Add(visgroups[visgroupIndex]); } entity.UpdateBoundingBox(); if (groups.ContainsKey(groupIndex)) { entity.SetParent(groups[groupIndex]); } else { entity.SetParent(map.WorldSpawn); } } else if (name == "brush") { bool invisibleCollision = false; byte brushFlags = br.ReadByte(); //TODO: ??? Int32 keys = br.ReadInt32(); for (int j = 0; j < keys; j++) { Int32 keyNameInd = br.ReadInt32(); Int32 keyValueInd = br.ReadInt32(); string keyName = names[keyNameInd - 1]; if (keyName.Equals("classname", StringComparison.OrdinalIgnoreCase)) { string keyValue = names[keyValueInd - 1]; if (keyValue.Equals("field_hit", StringComparison.OrdinalIgnoreCase)) { invisibleCollision = true; } } } Int32 groupIndex = br.ReadInt32() - 1; Int32 visgroupIndex = br.ReadInt32() - 1; byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte(); List <Coordinate> vertices = new List <Coordinate>(); byte vertexCount = br.ReadByte(); for (int j = 0; j < vertexCount; j++) { decimal x = (decimal)br.ReadSingle(); decimal z = (decimal)br.ReadSingle(); decimal y = (decimal)br.ReadSingle(); vertices.Add(new Coordinate(x, y, z)); } List <Face> faces = new List <Face>(); byte faceCount = br.ReadByte(); for (int j = 0; j < faceCount; j++) { byte faceFlags = br.ReadByte(); //TODO: maybe we need these unused bits for something idk decimal planeEq0 = (decimal)br.ReadSingle(); decimal planeEq1 = (decimal)br.ReadSingle(); decimal planeEq2 = (decimal)br.ReadSingle(); decimal planeEq3 = (decimal)br.ReadSingle(); decimal texPosX = (decimal)br.ReadSingle(); decimal texPosY = (decimal)br.ReadSingle(); decimal texScaleX = (decimal)br.ReadSingle(); decimal texScaleY = (decimal)br.ReadSingle(); float texRotX = br.ReadSingle(); float texRotY = br.ReadSingle(); decimal uTexPlane0 = (decimal)br.ReadSingle(); decimal uTexPlane1 = (decimal)br.ReadSingle(); decimal uTexPlane2 = (decimal)br.ReadSingle(); decimal uTexPlane3 = (decimal)br.ReadSingle(); decimal vTexPlane0 = (decimal)br.ReadSingle(); decimal vTexPlane1 = (decimal)br.ReadSingle(); decimal vTexPlane2 = (decimal)br.ReadSingle(); decimal vTexPlane3 = (decimal)br.ReadSingle(); float luxelSize = br.ReadSingle(); Int32 smoothGroupInd = br.ReadInt32(); Int32 materialInd = br.ReadInt32() - 1; Int32 lightmapInd = -1; if ((faceFlags & 16) != 0) { lightmapInd = br.ReadInt32(); } byte indexCount = br.ReadByte(); List <byte> vertsInFace = new List <byte>(); for (int k = 0; k < indexCount; k++) { byte vertIndex = br.ReadByte(); vertsInFace.Add(vertIndex); float texCoordX = br.ReadSingle(); float texCoordY = br.ReadSingle(); float lmCoordX = 0.0f; float lmCoordY = 0.0f; if ((faceFlags & 16) != 0) { lmCoordX = br.ReadSingle(); lmCoordY = br.ReadSingle(); } } Coordinate norm = new Coordinate(planeEq0, planeEq2, planeEq1); if (Math.Abs((float)norm.LengthSquared()) > 0.001f) { if (Math.Abs((double)norm.LengthSquared() - 1) > 0.001) { throw new Exception(norm.LengthSquared().ToString()); } Face newFace = new Face(map.IDGenerator.GetNextFaceID()); foreach (byte vertInd in vertsInFace) { newFace.Vertices.Insert(0, new Vertex(vertices[vertInd], newFace)); } newFace.Plane = new Plane(newFace.Vertices[0].Location, newFace.Vertices[1].Location, newFace.Vertices[2].Location); newFace.UpdateBoundingBox(); Coordinate uNorm = new Coordinate(uTexPlane0, uTexPlane2, uTexPlane1).Normalise(); Coordinate vNorm = new Coordinate(vTexPlane0, vTexPlane2, vTexPlane1).Normalise(); if (Math.Abs((double)(uNorm.LengthSquared() - vNorm.LengthSquared())) > 0.001) { throw new Exception(uNorm.LengthSquared().ToString() + " " + vNorm.LengthSquared().ToString()); } newFace.Texture.Name = (faceFlags & 4) != 0 ? "tooltextures/remove_face" : invisibleCollision ? "tooltextures/invisible_collision" : materials[materialInd]; newFace.AlignTextureToWorld(); newFace.Texture.UAxis = uNorm * (decimal)Math.Cos(-texRotX * Math.PI / 180.0) + vNorm * (decimal)Math.Sin(-texRotX * Math.PI / 180.0); newFace.Texture.VAxis = vNorm * (decimal)Math.Cos(-texRotX * Math.PI / 180.0) - uNorm * (decimal)Math.Sin(-texRotX * Math.PI / 180.0); //huh????? if (Math.Abs(texScaleX) < 0.0001m) { if (Math.Abs(texScaleY) < 0.0001m) { texScaleX = 1m; texScaleY = 1m; } else { texScaleX = texScaleY; } } else if (Math.Abs(texScaleY) < 0.0001m) { texScaleY = texScaleX; } newFace.Texture.XScale = texScaleX / 2; newFace.Texture.YScale = texScaleY / 2; newFace.Texture.XShift = -texPosX * 2 / texScaleX; newFace.Texture.YShift = texPosY * 2 / texScaleY; newFace.Texture.Rotation = (decimal)texRotX; //seriously, what the F**K??????????? if ((texRotX - texRotY) > 120.0f) { newFace.Texture.XScale *= -1m; newFace.Texture.YScale *= -1m; newFace.Texture.Rotation -= 180m; newFace.Texture.UAxis = -newFace.Texture.UAxis; } else if ((texRotY - texRotX) > 120.0f) { newFace.Texture.XScale *= -1m; newFace.Texture.YScale *= -1m; newFace.Texture.Rotation -= 180m; newFace.Texture.VAxis = -newFace.Texture.VAxis; } newFace.Transform(new UnitScale(Coordinate.One, newFace.BoundingBox.Center), TransformFlags.None); faces.Add(newFace); } } Solid newSolid = new Solid(map.IDGenerator.GetNextObjectID()); foreach (Face face in faces) { face.Parent = newSolid; newSolid.Faces.Add(face); } if (visgroups.ContainsKey(visgroupIndex)) { newSolid.Visgroups.Add(visgroups[visgroupIndex]); } newSolid.Colour = Colour.GetRandomBrushColour(); newSolid.UpdateBoundingBox(); MapObject parent = map.WorldSpawn; if (groups.ContainsKey(groupIndex)) { parent = groups[groupIndex]; } if (newSolid.IsValid()) { newSolid.SetParent(parent); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } else { var offset = newSolid.BoundingBox.Center; // Not a valid solid, decompose into tetrahedrons/etc foreach (var face in faces) { var polygon = new Polygon(face.Vertices.Select(x => x.Location)); if (!polygon.IsValid() || !polygon.IsConvex()) { // tetrahedrons foreach (var triangle in face.GetTrianglesReversed()) { var tf = new Face(map.IDGenerator.GetNextFaceID()); tf.Plane = new Plane(triangle[0].Location, triangle[1].Location, triangle[2].Location); tf.Vertices.AddRange(triangle.Select(x => new Vertex(x.Location, tf))); tf.Texture = face.Texture.Clone(); tf.UpdateBoundingBox(); newSolid = SolidifyFace(map, tf, offset); newSolid.SetParent(parent); newSolid.UpdateBoundingBox(); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } } else { // cone/pyramid/whatever newSolid = SolidifyFace(map, face, offset); newSolid.SetParent(parent); newSolid.UpdateBoundingBox(); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } } } } else { if (name == "terrain") { MapProvider.warnings = "This map contains displacements, which are currently not supported. The map will appear incomplete."; } br.BaseStream.Seek(size, SeekOrigin.Current); } } return(map); }
protected override DataStructures.MapObjects.Map GetFromStream(Stream stream) { var map = new DataStructures.MapObjects.Map(); map.CordonBounds = new Box(Coordinate.One * -16384, Coordinate.One * 16384); BinaryReader br = new BinaryReader(stream); //header UInt16 mapVersion = br.ReadUInt16(); byte mapFlags = br.ReadByte(); Int32 nameCount = br.ReadInt32(); Int32 nameOffset = br.ReadInt32(); Int32 objectCount = br.ReadInt32(); Int32 objectOffset = br.ReadInt32(); //get names, needed to understand the objects List <string> names = new List <string>(); br.BaseStream.Seek(nameOffset, SeekOrigin.Begin); for (int i = 0; i < nameCount; i++) { string name = br.ReadNullTerminatedString(); names.Add(name); } //now we can parse the object table List <string> materials = new List <string>(); List <Tuple <int, string> > meshReferences = new List <Tuple <int, string> >(); br.BaseStream.Seek(objectOffset, SeekOrigin.Begin); long objectStartPos = br.BaseStream.Position; for (int i = 0; i < objectCount; i++) { int index = br.ReadInt32() - 1; int size = br.ReadInt32(); if (index < 0 || index >= names.Count) { throw new Exception(i.ToString() + " " + index.ToString()); } string name = names[index]; if (name == "meshreference") { byte flags = br.ReadByte(); Int32 groupNameInd = br.ReadInt32() - 1; Int32 objectNameInd = br.ReadInt32() - 1; byte limbCount = br.ReadByte(); meshReferences.Add(new Tuple <int, string>(i, names[objectNameInd])); } else if (name == "material") { byte materialFlags = br.ReadByte(); Int32 groupIndex = br.ReadInt32(); string objectName = names[br.ReadInt32() - 1]; Int32 extensionNameIndex = -1; if ((materialFlags & 2) != 0) { extensionNameIndex = br.ReadInt32(); //TODO: what the heck is this } materials.Add(objectName); } else { br.BaseStream.Seek(size, SeekOrigin.Current); } } br.BaseStream.Position = objectStartPos; for (int i = 0; i < objectCount; i++) { int index = br.ReadInt32() - 1; int size = br.ReadInt32(); if (index < 0 || index >= names.Count) { throw new Exception(i.ToString() + " " + index.ToString()); } string name = names[index]; if (name == "mesh") { Property newProperty; long startPos = br.BaseStream.Position; byte flags = br.ReadByte(); Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.ClassName = "model"; entity.EntityData.Name = "model"; entity.Colour = Colour.GetDefaultEntityColour(); Int32 keyCount = br.ReadInt32(); for (int j = 0; j < keyCount; j++) { Int32 keyNameInd = br.ReadInt32() - 1; Int32 keyValueInd = br.ReadInt32() - 1; if (names[keyNameInd] == "classname") { //entity.ClassName = names[keyValueInd]; //entity.EntityData.Name = names[keyValueInd]; } else { newProperty = new Property(); newProperty.Key = names[keyNameInd]; newProperty.Value = names[keyValueInd]; if (newProperty.Key == "file") { newProperty.Value = System.IO.Path.GetFileNameWithoutExtension(newProperty.Value); } entity.EntityData.Properties.Add(newProperty); } } Int32 group = br.ReadInt32(); Int32 visgroup = br.ReadInt32(); byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte(); Int32 meshRefIndex = br.ReadInt32() - 1; float x = br.ReadSingle(); float z = br.ReadSingle(); float y = br.ReadSingle(); if (entity != null) { entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z); } if (entity.EntityData.GetPropertyValue("file") == null) { newProperty = new Property(); newProperty.Key = "file"; newProperty.Value = meshReferences.Find(q => q.Item1 == meshRefIndex).Item2; entity.EntityData.Properties.Add(newProperty); } float pitch = br.ReadSingle(); float yaw = br.ReadSingle(); float roll = br.ReadSingle(); newProperty = new Property(); newProperty.Key = "angles"; newProperty.Value = pitch.ToString(CultureInfo.InvariantCulture) + " " + yaw.ToString(CultureInfo.InvariantCulture) + " " + roll.ToString(CultureInfo.InvariantCulture); entity.EntityData.Properties.Add(newProperty); float xScale = 1.0f; float yScale = 1.0f; float zScale = 1.0f; if ((flags & 1) == 0) { xScale = br.ReadSingle(); yScale = br.ReadSingle(); zScale = br.ReadSingle(); } newProperty = new Property(); newProperty.Key = "scale"; newProperty.Value = xScale.ToString(CultureInfo.InvariantCulture) + " " + yScale.ToString(CultureInfo.InvariantCulture) + " " + zScale.ToString(CultureInfo.InvariantCulture); entity.EntityData.Properties.Add(newProperty); br.BaseStream.Position += size - (br.BaseStream.Position - startPos); if (entity != null) { entity.UpdateBoundingBox(); entity.SetParent(map.WorldSpawn); } } else if (name == "entity") { byte flags = br.ReadByte(); float x = br.ReadSingle(); float z = br.ReadSingle(); float y = br.ReadSingle(); Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.Colour = Colour.GetDefaultEntityColour(); entity.Origin = new Coordinate((decimal)x, (decimal)y, (decimal)z); Int32 keyCount = br.ReadInt32(); for (int j = 0; j < keyCount; j++) { Int32 keyNameInd = br.ReadInt32() - 1; Int32 keyValueInd = br.ReadInt32() - 1; if (names[keyNameInd] == "classname") { entity.ClassName = names[keyValueInd]; entity.EntityData.Name = names[keyValueInd]; } else { Property newProperty = new Property(); newProperty.Key = names[keyNameInd]; newProperty.Value = names[keyValueInd]; entity.EntityData.Properties.Add(newProperty); } } Int32 group = br.ReadInt32(); Int32 visgroup = br.ReadInt32(); entity.UpdateBoundingBox(); entity.SetParent(map.WorldSpawn); } else if (name == "brush") { bool invisibleCollision = false; byte brushFlags = br.ReadByte(); //TODO: ??? Int32 keys = br.ReadInt32(); for (int j = 0; j < keys; j++) { Int32 keyNameInd = br.ReadInt32(); Int32 keyValueInd = br.ReadInt32(); string keyName = names[keyNameInd - 1]; if (keyName.Equals("classname", StringComparison.InvariantCultureIgnoreCase)) { string keyValue = names[keyValueInd - 1]; if (keyValue.Equals("field_hit", StringComparison.InvariantCultureIgnoreCase)) { invisibleCollision = true; } } } Int32 groupIndex = br.ReadInt32(); Int32 visgroupIndex = br.ReadInt32(); byte red = br.ReadByte(); byte green = br.ReadByte(); byte blue = br.ReadByte(); List <Coordinate> vertices = new List <Coordinate>(); byte vertexCount = br.ReadByte(); for (int j = 0; j < vertexCount; j++) { decimal x = (decimal)br.ReadSingle(); decimal z = (decimal)br.ReadSingle(); decimal y = (decimal)br.ReadSingle(); vertices.Add(new Coordinate(x, y, z)); } List <Face> faces = new List <Face>(); byte faceCount = br.ReadByte(); for (int j = 0; j < faceCount; j++) { byte faceFlags = br.ReadByte(); //TODO: maybe we need these unused bits for something idk decimal planeEq0 = (decimal)br.ReadSingle(); decimal planeEq1 = (decimal)br.ReadSingle(); decimal planeEq2 = (decimal)br.ReadSingle(); decimal planeEq3 = (decimal)br.ReadSingle(); decimal texPosX = (decimal)br.ReadSingle(); decimal texPosY = (decimal)br.ReadSingle(); decimal texScaleX = (decimal)br.ReadSingle(); decimal texScaleY = (decimal)br.ReadSingle(); float texRotX = br.ReadSingle(); float texRotY = br.ReadSingle(); decimal uTexPlane0 = (decimal)br.ReadSingle(); decimal uTexPlane1 = (decimal)br.ReadSingle(); decimal uTexPlane2 = (decimal)br.ReadSingle(); decimal uTexPlane3 = (decimal)br.ReadSingle(); decimal vTexPlane0 = (decimal)br.ReadSingle(); decimal vTexPlane1 = (decimal)br.ReadSingle(); decimal vTexPlane2 = (decimal)br.ReadSingle(); decimal vTexPlane3 = (decimal)br.ReadSingle(); float luxelSize = br.ReadSingle(); Int32 smoothGroupInd = br.ReadInt32(); Int32 materialInd = br.ReadInt32() - 1; Int32 lightmapInd = -1; if ((faceFlags & 16) != 0) { lightmapInd = br.ReadInt32(); } byte indexCount = br.ReadByte(); List <byte> vertsInFace = new List <byte>(); for (int k = 0; k < indexCount; k++) { byte vertIndex = br.ReadByte(); vertsInFace.Add(vertIndex); float texCoordX = br.ReadSingle(); float texCoordY = br.ReadSingle(); float lmCoordX = 0.0f; float lmCoordY = 0.0f; if ((faceFlags & 16) != 0) { lmCoordX = br.ReadSingle(); lmCoordY = br.ReadSingle(); } } Coordinate norm = new Coordinate(planeEq0, planeEq2, planeEq1); if (Math.Abs((float)norm.LengthSquared()) > 0.001f) { if (Math.Abs((double)norm.LengthSquared() - 1) > 0.001) { throw new Exception(norm.LengthSquared().ToString()); } Face newFace = new Face(map.IDGenerator.GetNextFaceID()); foreach (byte vertInd in vertsInFace) { newFace.Vertices.Insert(0, new Vertex(vertices[vertInd], newFace)); } newFace.Plane = new Plane(newFace.Vertices[0].Location, newFace.Vertices[1].Location, newFace.Vertices[2].Location); newFace.UpdateBoundingBox(); /*if ((faceFlags & 4) == 0) * { * Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); * entity.Colour = Color.Lime; * entity.Origin = newFace.BoundingBox.Center; * entity.UpdateBoundingBox(); * entity.SetParent(map.WorldSpawn); * * Property newProperty = new Property(); * newProperty.Key = "normal"; * newProperty.Value = newFace.Plane.Normal.ToString(); * entity.EntityData.Properties.Add(newProperty); * * var direction = newFace.Plane.GetClosestAxisToNormal(); * var tempV = direction == Coordinate.UnitZ ? -Coordinate.UnitY : -Coordinate.UnitZ; * var uAxis = newFace.Plane.Normal.Cross(tempV).Normalise(); * var vAxis = uAxis.Cross(newFace.Plane.Normal).Normalise(); * * newProperty = new Property(); * newProperty.Key = "uaxis"; * newProperty.Value = uAxis.ToString(); * entity.EntityData.Properties.Add(newProperty); * * newProperty = new Property(); * newProperty.Key = "vaxis"; * newProperty.Value = vAxis.ToString(); * entity.EntityData.Properties.Add(newProperty); * }*/ Coordinate uNorm = new Coordinate(uTexPlane0, uTexPlane2, uTexPlane1).Normalise(); Coordinate vNorm = new Coordinate(vTexPlane0, vTexPlane2, vTexPlane1).Normalise(); if (Math.Abs((double)(uNorm.LengthSquared() - vNorm.LengthSquared())) > 0.001) { throw new Exception(uNorm.LengthSquared().ToString() + " " + vNorm.LengthSquared().ToString()); } newFace.Texture.Name = (faceFlags & 4) != 0 ? "tooltextures/remove_face" : invisibleCollision ? "tooltextures/invisible_collision" : materials[materialInd]; newFace.AlignTextureToWorld(); //TODO: add warning? //if (texRotY != texRotX) throw new Exception((texRotX - texRotY).ToString()); newFace.Texture.UAxis = uNorm * (decimal)Math.Cos(-texRotY * Math.PI / 180.0) + vNorm * (decimal)Math.Sin(-texRotY * Math.PI / 180.0); newFace.Texture.VAxis = vNorm * (decimal)Math.Cos(-texRotY * Math.PI / 180.0) - uNorm * (decimal)Math.Sin(-texRotY * Math.PI / 180.0); newFace.Texture.XScale = texScaleX / 2; newFace.Texture.YScale = texScaleY / 2; newFace.Texture.XShift = -texPosX * 2 / texScaleX; newFace.Texture.YShift = texPosY * 2 / texScaleY; newFace.Texture.Rotation = (decimal)texRotY; newFace.Transform(new UnitScale(Coordinate.One, newFace.BoundingBox.Center), TransformFlags.None); faces.Add(newFace); } } Solid newSolid = new Solid(map.IDGenerator.GetNextObjectID()); foreach (Face face in faces) { face.Parent = newSolid; newSolid.Faces.Add(face); } newSolid.Colour = Colour.GetRandomBrushColour(); newSolid.UpdateBoundingBox(); if (newSolid.IsValid()) { newSolid.SetParent(map.WorldSpawn); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } else { var offset = newSolid.BoundingBox.Center; // Not a valid solid, decompose into tetrahedrons/etc foreach (var face in faces) { var polygon = new Polygon(face.Vertices.Select(x => x.Location)); if (!polygon.IsValid() || !polygon.IsConvex()) { // tetrahedrons foreach (var triangle in face.GetTrianglesReversed()) { var tf = new Face(map.IDGenerator.GetNextFaceID()); tf.Plane = new Plane(triangle[0].Location, triangle[1].Location, triangle[2].Location); tf.Vertices.AddRange(triangle.Select(x => new Vertex(x.Location, tf))); tf.Texture = face.Texture.Clone(); tf.UpdateBoundingBox(); newSolid = SolidifyFace(map, tf, offset); newSolid.SetParent(map.WorldSpawn); newSolid.UpdateBoundingBox(); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } } else { // cone/pyramid/whatever newSolid = SolidifyFace(map, face, offset); newSolid.SetParent(map.WorldSpawn); newSolid.UpdateBoundingBox(); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); } } } } else { br.BaseStream.Seek(size, SeekOrigin.Current); } } return(map); }
protected override DataStructures.MapObjects.Map GetFromStream(Stream stream, IEnumerable <string> modelDirs, out Image[] lightmaps) { lightmaps = null; var map = new DataStructures.MapObjects.Map(); map.CordonBounds = new Box(Coordinate.One * -16384, Coordinate.One * 16384); BinaryReader br = new BinaryReader(stream); List <ModelReference> models = null; //header bool hasLightmap = Math.Abs(br.ReadSingle()) > 0.01f; if (hasLightmap) { UInt32 lightmapSize = br.ReadUInt32(); stream.Position += lightmapSize; } int entityCount = (int)br.ReadSingle() - 2; for (int i = 0; i < entityCount; i++) { int meshCount = (int)br.ReadSingle(); List <long> memblockLocations = new List <long>(); for (int j = 0; j < meshCount; j++) { stream.Position += 4; memblockLocations.Add(stream.Position); SkipMemblock(br); } bool isBrush = Math.Abs(br.ReadSingle()) > 0.01f; if (isBrush) { Dictionary <int, List <Face> > faces = new Dictionary <int, List <Face> >(); long returnPosition = stream.Position; for (int j = 0; j < meshCount; j++) { stream.Position = memblockLocations[j]; faces.Add(j, new List <Face>()); ReadMemblockMesh(br, map, faces[j]); } stream.Position = returnPosition; SkipMemblock(br); for (int j = 0; j < 2; j++) { stream.Position += 4; } float xTranslate = br.ReadSingle(); float zTranslate = br.ReadSingle(); float yTranslate = br.ReadSingle(); float xScale = br.ReadSingle(); float zScale = br.ReadSingle(); float yScale = br.ReadSingle(); for (int j = 8; j < 25; j++) { stream.Position += 4; } List <SubmeshTextureInfo> textures = new List <SubmeshTextureInfo>(); for (int j = 0; j < meshCount; j++) { SubmeshTextureInfo submeshTextureInfo = new SubmeshTextureInfo(); submeshTextureInfo.TextureName = System.IO.Path.GetFileNameWithoutExtension(br.ReadLine()); float flags = br.ReadSingle(); bool faceIsHidden = Math.Abs(flags - 1) < 0.01f; bool faceIsLit = Math.Abs(flags - 800) < 0.01f; if (faceIsLit) { br.ReadSingle(); } for (int k = 0; k < 4; k++) { stream.Position += 4; } submeshTextureInfo.ScaleU = br.ReadSingle(); submeshTextureInfo.ScaleV = br.ReadSingle(); submeshTextureInfo.ShiftU = br.ReadSingle(); submeshTextureInfo.ShiftV = br.ReadSingle(); submeshTextureInfo.Rotation = br.ReadSingle(); if (faceIsHidden) { submeshTextureInfo.TextureName = "tooltextures/remove_face"; } textures.Add(submeshTextureInfo); } if (faces.Any()) { Solid newSolid = new Solid(map.IDGenerator.GetNextObjectID()); foreach (int key in faces.Keys) { foreach (Face face in faces[key]) { face.Parent = newSolid; newSolid.Faces.Add(face); } } newSolid.Colour = Colour.GetRandomBrushColour(); newSolid.UpdateBoundingBox(); MapObject parent = map.WorldSpawn; newSolid.SetParent(parent); newSolid.Transform(new UnitScale(Coordinate.One, newSolid.BoundingBox.Center), TransformFlags.None); newSolid.Transform(new UnitScale(new Coordinate( (decimal)xScale / newSolid.BoundingBox.Width, (decimal)yScale / newSolid.BoundingBox.Length, (decimal)zScale / newSolid.BoundingBox.Height), Coordinate.Zero), TransformFlags.None); newSolid.UpdateBoundingBox(); newSolid.Transform(new UnitTranslate(new Coordinate( (decimal)xTranslate, (decimal)yTranslate, (decimal)zTranslate)), TransformFlags.None); newSolid.UpdateBoundingBox(); foreach (int key in faces.Keys) { foreach (Face face in faces[key]) { face.Texture.Name = textures[key].TextureName; face.AlignTextureToWorld(); face.Texture.XScale = (decimal)textures[key].ScaleU * 0.25m; face.Texture.YScale = (decimal)textures[key].ScaleV * 0.25m; face.Texture.XShift = (decimal)textures[key].ShiftU; face.Texture.YShift = (decimal)textures[key].ShiftV; face.SetTextureRotation((decimal)textures[key].Rotation); } } } } else { int entitySubType = (int)br.ReadSingle(); for (int j = 1; j < 2; j++) { stream.Position += 4; } float xTranslate = br.ReadSingle(); float zTranslate = br.ReadSingle(); float yTranslate = br.ReadSingle(); float xScale = br.ReadSingle(); float zScale = br.ReadSingle(); float yScale = br.ReadSingle(); if (Math.Abs(entitySubType - 3.0f) < 0.01f) { for (int j = 8; j < 35; j++) { stream.Position += 4; } string entityName = br.ReadLine(); string entityIcon = br.ReadLine(); int propertyCount = (int)br.ReadSingle() + 1; Dictionary <string, string> properties = new Dictionary <string, string>(); for (int j = 0; j < propertyCount; j++) { string propertyName = br.ReadLine().ToLowerInvariant(); string propertyValue = br.ReadLine(); properties.Add(propertyName, propertyValue); } Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.Colour = Colour.GetDefaultEntityColour(); Property newProperty = null; switch (entityName.ToLowerInvariant()) { case "pointlight": entity.ClassName = "light"; entity.EntityData.Name = "light"; newProperty = new Property(); newProperty.Key = "range"; newProperty.Value = properties["range"]; entity.EntityData.Properties.Add(newProperty); newProperty = new Property(); newProperty.Key = "color"; newProperty.Value = properties["color"].Replace(',', ' ').Trim(); entity.EntityData.Properties.Add(newProperty); break; case "spotlight": entity.ClassName = "spotlight"; entity.EntityData.Name = "spotlight"; newProperty = new Property(); newProperty.Key = "range"; newProperty.Value = properties["range"]; entity.EntityData.Properties.Add(newProperty); newProperty = new Property(); newProperty.Key = "color"; newProperty.Value = properties["color"].Replace(',', ' ').Trim(); entity.EntityData.Properties.Add(newProperty); newProperty = new Property(); newProperty.Key = "innerconeangle"; newProperty.Value = "45"; if (decimal.TryParse(properties["innerang"], out decimal innerAngle)) { newProperty.Value = (innerAngle * 0.5m).ToString(); } entity.EntityData.Properties.Add(newProperty); newProperty = new Property(); newProperty.Key = "outerconeangle"; newProperty.Value = "90"; if (decimal.TryParse(properties["outerang"], out decimal outerAngle)) { newProperty.Value = (outerAngle * 0.5m).ToString(); } entity.EntityData.Properties.Add(newProperty); newProperty = new Property(); newProperty.Key = "angles"; newProperty.Value = "0 0 0"; string[] dirParts = properties["direction"].Split(','); if (decimal.TryParse(dirParts[0], out decimal dirX) && decimal.TryParse(dirParts[1], out decimal dirY) && decimal.TryParse(dirParts[2], out decimal dirZ)) { Coordinate dir = new Coordinate(dirX, dirY, dirZ).Normalise(); decimal pitch = DMath.RadiansToDegrees(DMath.Asin(-dir.Y)); dir.Y = 0; decimal yaw = 0m; if (dir.LengthSquared() > 0.01m) { dir = dir.Normalise(); yaw = DMath.RadiansToDegrees(DMath.Atan2(-dir.X, dir.Z)); } newProperty.Value = $"{pitch} {yaw} 0"; } entity.EntityData.Properties.Add(newProperty); break; default: entity.ClassName = entityName; entity.EntityData.Name = entityName; foreach (var key in properties.Keys) { newProperty = new Property(); newProperty.Key = key; newProperty.Value = properties[key]; entity.EntityData.Properties.Add(newProperty); } break; } entity.Origin = new Coordinate((decimal)xTranslate, (decimal)yTranslate, (decimal)zTranslate); entity.SetParent(map.WorldSpawn); } else if (Math.Abs(entitySubType - 2.0f) < 0.01f) { if (models == null) { models = LoadAllModels(modelDirs); } ModelReference model = null; Coordinate angles = null; Coordinate scale = null; long returnPosition = stream.Position; for (int j = 0; j < meshCount; j++) { stream.Position = memblockLocations[j]; UInt32 memblockSize = br.ReadUInt32(); UInt32 dwFVF = br.ReadUInt32(); UInt32 dwFVFSize = br.ReadUInt32(); UInt32 dwVertMax = br.ReadUInt32(); for (int k = 0; k < models.Count; k++) { DataStructures.Models.Mesh currMesh = models[k].Model.BodyParts[0].Meshes.Values.First()[0]; if (dwVertMax == currMesh.Vertices.Count) { List <Pair <Coordinate, Coordinate> > points = new List <Pair <Coordinate, Coordinate> >(); List <Coordinate> loadedPoints = new List <Coordinate>(); Coordinate loadedCenter = new Coordinate(0, 0, 0); Coordinate knownCenter = new Coordinate(0, 0, 0); for (int l = 0; l < dwVertMax; l++) { float x = br.ReadSingle(); float z = br.ReadSingle(); float y = br.ReadSingle(); Coordinate point = new Coordinate((decimal)x, (decimal)y, (decimal)z); loadedPoints.Add(point); loadedCenter += point; knownCenter += new Coordinate(currMesh.Vertices[l].Location); for (int m = 12; m < dwFVFSize; m += 4) { stream.Position += 4; } if (points.Count < 3) { int nativeIndex = (l / 3) * 3 + ((l % 3) + 1) % 3; Coordinate vertexLoc = new Coordinate(currMesh.Vertices[nativeIndex].Location); if (!points.Any(p => Math.Abs(p.Item1.Normalise().Dot(vertexLoc.Normalise())) > 0.95m)) { points.Add(new Pair <Coordinate, Coordinate>(vertexLoc, point)); } } } loadedCenter /= dwVertMax; knownCenter /= dwVertMax; if (points.Count >= 3) { model = models[k]; for (int l = 0; l < 3; l++) { points[l].Item1 -= knownCenter; points[l].Item1 = points[l].Item1.Normalise(); points[l].Item2 -= loadedCenter; points[l].Item2 = points[l].Item2.Normalise(); } points[2].Item1 = points[0].Item1.Cross(points[1].Item1).Normalise(); points[2].Item2 = points[0].Item2.Cross(points[1].Item2).Normalise(); points[1].Item1 = points[0].Item1.Cross(points[2].Item1).Normalise(); points[1].Item2 = points[0].Item2.Cross(points[2].Item2).Normalise(); decimal dotX0 = Coordinate.UnitX.Dot(points[0].Item1); decimal dotX1 = Coordinate.UnitX.Dot(points[1].Item1); decimal dotX2 = Coordinate.UnitX.Dot(points[2].Item1); decimal dotY0 = Coordinate.UnitY.Dot(points[0].Item1); decimal dotY1 = Coordinate.UnitY.Dot(points[1].Item1); decimal dotY2 = Coordinate.UnitY.Dot(points[2].Item1); decimal dotZ0 = Coordinate.UnitZ.Dot(points[0].Item1); decimal dotZ1 = Coordinate.UnitZ.Dot(points[1].Item1); decimal dotZ2 = Coordinate.UnitZ.Dot(points[2].Item1); Coordinate newX = (dotX0 * points[0].Item2 + dotX1 * points[1].Item2 + dotX2 * points[2].Item2); Coordinate newY = (dotY0 * points[0].Item2 + dotY1 * points[1].Item2 + dotY2 * points[2].Item2); Coordinate newZ = (dotZ0 * points[0].Item2 + dotZ1 * points[1].Item2 + dotZ2 * points[2].Item2); Coordinate unTransformedMin = new Coordinate( loadedPoints.Select(p => p.X).Min(), loadedPoints.Select(p => p.Y).Min(), loadedPoints.Select(p => p.Z).Min() ); Coordinate unTransformedBounds = new Coordinate( loadedPoints.Select(p => p.X).Max(), loadedPoints.Select(p => p.Y).Max(), loadedPoints.Select(p => p.Z).Max()) - unTransformedMin; Coordinate propScale(Coordinate p) { Coordinate retVal = p.Clone(); retVal.X *= (decimal)xScale / unTransformedBounds.X; retVal.Y *= (decimal)yScale / unTransformedBounds.Y; retVal.Z *= (decimal)zScale / unTransformedBounds.Z; return(retVal); } Coordinate centerDiff = propScale(loadedCenter - knownCenter); xTranslate += (float)centerDiff.X; yTranslate += (float)centerDiff.Y; zTranslate += (float)centerDiff.Z; Coordinate newBounds = new Coordinate( loadedPoints.Select(p => propScale(p).Dot(newX)).Max() - loadedPoints.Select(p => propScale(p).Dot(newX)).Min(), loadedPoints.Select(p => propScale(p).Dot(newY)).Max() - loadedPoints.Select(p => propScale(p).Dot(newY)).Min(), loadedPoints.Select(p => propScale(p).Dot(newZ)).Max() - loadedPoints.Select(p => propScale(p).Dot(newZ)).Min()); Coordinate newBounds2 = new Coordinate( loadedPoints.Select(p => p.Dot(newX)).Max() - loadedPoints.Select(p => p.Dot(newX)).Min(), loadedPoints.Select(p => p.Dot(newY)).Max() - loadedPoints.Select(p => p.Dot(newY)).Min(), loadedPoints.Select(p => p.Dot(newZ)).Max() - loadedPoints.Select(p => p.Dot(newZ)).Min()); scale = new Coordinate(newBounds.X / newBounds2.X, newBounds.Z / newBounds2.Z, newBounds.Y / newBounds2.Y); angles = Entity.ToEuler(newX, newY, newZ); break; } } } } stream.Position = returnPosition; for (int j = 8; j < 24; j++) { stream.Position += 4; } int materialCount = (int)br.ReadSingle() + 1; for (int j = 0; j < materialCount; j++) { string materialName = br.ReadLine(); for (int k = 0; k < 10; k++) { stream.Position += 4; } } Entity entity = new Entity(map.IDGenerator.GetNextObjectID()); entity.ClassName = "model"; entity.EntityData.Name = "model"; entity.Colour = Colour.GetDefaultEntityColour(); Property newProperty; if (model != null) { newProperty = new Property(); newProperty.Key = "file"; newProperty.Value = System.IO.Path.GetFileNameWithoutExtension(model.Path); entity.EntityData.Properties.Add(newProperty); if (angles != null) { newProperty = new Property(); newProperty.Key = "angles"; newProperty.Value = angles.ToDataString(); entity.EntityData.Properties.Add(newProperty); } if (scale != null) { newProperty = new Property(); newProperty.Key = "scale"; newProperty.Value = scale.ToDataString(); entity.EntityData.Properties.Add(newProperty); } } entity.Origin = new Coordinate((decimal)xTranslate, (decimal)yTranslate, (decimal)zTranslate); entity.SetParent(map.WorldSpawn); } } } if (models != null) { models.ForEach(m => ModelProvider.DeleteModelReference(m)); } return(map); }