Ejemplo n.º 1
0
        public void AsSet_With_T1_T2_Should_return_EntitySet_with_all_Entity_with_component_T1_T2()
        {
            using World world   = new(4);
            using EntitySet set = world.GetEntities().With <bool>().With <int>().AsSet();

            List <Entity> entities = new()
            {
                world.CreateEntity(),
                          world.CreateEntity(),
                          world.CreateEntity(),
                          world.CreateEntity()
            };

            Check.That(set.GetEntities().ToArray()).IsEmpty();

            foreach (Entity entity in entities)
            {
                entity.Set(true);
            }

            Check.That(set.GetEntities().ToArray()).IsEmpty();

            foreach (Entity entity in entities)
            {
                entity.Set(42);
            }

            Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);

            Entity temp = entities[2];

            temp.Remove <bool>();
            entities.Remove(temp);

            Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);

            temp.Set(true);
            temp.Remove <int>();

            Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Completes the task and changes the sprite.
        /// </summary>
        public void Destroy()
        {
            if (taskComponent.Type != TaskType.DestroyMainrfame)
            {
                throw new InvalidOperationException();
            }

            taskComponent.Completed = true;

            (Entity.Get <SpriteComponent>().SpriteProvider as SpriteFromSheet).CurrentFrame = 20;
            Entity.Remove <DestructableComponent>();
        }
Ejemplo n.º 3
0
        private static void RemoveObjectFromPool(uint id)
        {
            _gameObjects.Remove(id);
            var entity = Entity.Get(id);

            if (entity != null)
            {
                entity.UnsubscribeFromCollision();
            }

            Entity.Remove(id);
        }
        public void TestEntityRemovedFromFamilyWhenComponentRemovedAndFamilyNotAlreadyAccessed()
        {
            var entity = new Entity();

            entity.Add(new Point());
            entity.Add(new Matrix());
            _game.AddEntity(entity);
            entity.Remove <Point>();
            var nodes = _game.GetNodeList <MockNode>();

            Assert.IsNull(nodes.Head);
        }
Ejemplo n.º 5
0
        public override void Start()
        {
            var animComponent = Target ?? Entity.Get <AnimationComponent>();

            if (animComponent != null)
            {
                PlayAnimations(animComponent);
            }

            // Destroy this script since it's no longer needed
            Entity.Remove(this);
        }
        public void TestEntityIsRemovedWhenComponentRemoved()
        {
            var entity = new Entity();

            entity.Add(new Point());
            _family.NewEntity(entity);
            entity.Remove(typeof(Point));
            _family.ComponentRemovedFromEntity(entity, typeof(Point));
            var nodes = _family.NodeList;

            Assert.IsNull(nodes.Head);
        }
Ejemplo n.º 7
0
        public void Build_WithEither_T1_T2_Should_return_EntitySet_with_all_Entity_with_component_T1_or_T2()
        {
            using (World world = new World(4))
                using (EntitySet set = world.GetEntities().WithEither <bool, int>().Build())
                {
                    List <Entity> entities = new List <Entity>
                    {
                        world.CreateEntity(),
                                  world.CreateEntity(),
                                  world.CreateEntity(),
                                  world.CreateEntity()
                    };

                    Check.That(set.GetEntities().ToArray()).IsEmpty();

                    foreach (Entity entity in entities)
                    {
                        entity.Set(true);
                    }

                    Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);

                    foreach (Entity entity in entities)
                    {
                        entity.Set(42);
                    }

                    Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);

                    Entity temp = entities[2];
                    temp.Remove <bool>();

                    Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);

                    temp.Remove <int>();
                    entities.Remove(temp);

                    Check.That(set.GetEntities().ToArray()).ContainsExactly(entities);
                }
        }
Ejemplo n.º 8
0
        // Each entity has a unique instance in the engine, therefore even identical
        // entities are unique. However some attributes can be culled, for example
        // an "angles" attribute of "0 0 0".
        public static void optimizeEntities(BSP me)
        {
            for (int i = 0; i < me.Entities.Count; i++)
            {
                Entity ent = me.Entities[i];
                switch (ent["classname"])
                {
                case "multi_manager":
                case "multisource":
                case "env_fade":
                case "trigger_relay":
                case "multi_kill_manager":
                case "trigger_counter":
                case "trigger_auto":
                    ent.Remove("angles");
                    ent.Remove("origin");
                    break;

                case "light":
                case "light_spot":
                    if (ent["targetname"] == "")
                    {
                        me.Entities.RemoveAt(i);
                        i--;
                        continue;
                    }
                    break;
                }
                if (ent.Angles[0] == 0 && ent.Angles[1] == 0 && ent.Angles[2] == 0)
                {
                    ent.Remove("angles");
                }
                if (ent.Origin[0] == 0 && ent.Origin[1] == 0 && ent.Origin[2] == 0)
                {
                    ent.Remove("origin");
                }
                ent.Remove("sequencename");
            }
        }
Ejemplo n.º 9
0
        protected override void Handle(ProgramData data)
        {
            if (_entity == data.GameData.Player)
            {
                _entity.Character = '%';
                _entity.Color     = Color.DarkRed;
                data.GameData.MessageLog.AddMessage("You died!", Color.Red);
                data.GameData.GameState = GameState.PlayerDead;
            }
            else
            {
                data.GameData.MessageLog.AddMessage($"{_entity.Name} is dead!", Color.Orange);

                _entity.Character = '%';
                _entity.Color     = Color.DarkRed;
                _entity.Blocks    = false;
                _entity.Remove <FighterComponent>();
                _entity.Remove <AiComponent>();
                _entity.Name        = $"remains of {_entity.Name}";
                _entity.RenderOrder = RenderOrder.Corpse;
            }
        }
Ejemplo n.º 10
0
        public void RemoveComponent()
        {
            Entity Test = new Entity();

            Assert.IsNull(Test.Get <Transform>());
            Test.Add <Transform>();
            Assert.AreEqual(0, Test.Items.Count);
            Assert.AreEqual(1, Test.Components.Count);
            Test.Remove <Transform>();
            Assert.IsNull(Test.Get <Transform>());
            Assert.AreEqual(0, Test.Items.Count);
            Assert.AreEqual(0, Test.Components.Count);
        }
Ejemplo n.º 11
0
 public bool PickupEntity(Entity entity)
 {
     if (entity != null)
     {
         if (entity is ItemEntity item && item.Pickup(Owner))
         {
         }
         else if (entity.HasComponent <Pickupable>())
         {
             _pickupedEntity = entity;
             entity.Remove();
             return(true);
         }
     }
Ejemplo n.º 12
0
        public override void Start()
        {
            base.Start();

            if (manager == null)
            {
                manager = this;
                InputManager.Initialize(Input);
            }
            else
            {
                Entity.Remove(this);
            }
        }
Ejemplo n.º 13
0
        public void Update()
        {
            var direction = Vector3.Normalize(destination - entity.Location);

            entity.TranslateIn(direction);
            var traveled = entity.Location - startingLocation;

            if (traveled.magnitude > heading.magnitude)
            {
                // Gone past destination
                entity.TeleportTo(destination);
                entity.Remove(this);
            }
        }
Ejemplo n.º 14
0
        public void Should_call_EntityRemoved_When_entity_removed()
        {
            using (World world = new World(4))
                using (EntitySet set = world.GetEntities().With <bool>().Build())
                {
                    Entity removedEntity = default;
                    set.EntityRemoved += (in Entity e) => removedEntity = e;

                    Entity entity = world.CreateEntity();
                    entity.Set <bool>();
                    entity.Remove <bool>();

                    Check.That(removedEntity).IsEqualTo(entity);
                }
        }
 // TODO: Polish these up.
 public virtual Entity ent42ToEntRad(Entity inEnt)
 {
     if (inEnt["classname"].Equals("func_door_rotating", StringComparison.InvariantCultureIgnoreCase))
     {
         inEnt["classname"] = "func_rotatingdoor";
     }
     else
     {
         if (inEnt["classname"].Equals("worldspawn", StringComparison.InvariantCultureIgnoreCase))
         {
             inEnt.Remove("mapversion");
         }
     }
     return(inEnt);
 }
        /// <summary>
        /// Postprocesser to convert an <see cref="Entity"/> from a Nightfire BSP to one for GTKRadiant.
        /// </summary>
        /// <param name="entity">The <see cref="Entity"/> to parse.</param>
        private void PostProcessNightfireEntity(Entity entity)
        {
            switch (entity.ClassName.ToLower())
            {
            case "func_door_rotating": {
                entity["classname"] = "func_rotatingdoor";
                break;
            }

            case "worldspawn": {
                entity.Remove("mapversion");
                break;
            }
            }
        }
Ejemplo n.º 17
0
        public void Generate()
        {
            (verts, tris) = _marchingCubes.CreateMeshData(points);

            if ((verts == null || verts.Length == 0) && _vertexBufferBinding.Buffer != null)
            {
                _vertexBufferBinding.Buffer.Dispose();
                _indexBufferBinding.Buffer.Dispose();
                return;
            }

            if (verts == null || verts.Length == 0)
            {
                return;
            }

            // Copying the generated verts for the collider
            // TODO Could probably do this a better way..
            colVerts = new Vector3[verts.Length];
            for (int i = 0; i < verts.Length; i++)
            {
                colVerts[i] = verts[i].Position;
            }

            if (_mesh == null)
            {
                CreateMesh();
                return;
            }

            // Only remake the buffers if we're trying to put in more than it can handle
            if (_vertexBufferBinding.Buffer.IsDisposed || verts.Length >= _vertexBufferBinding.Buffer.ElementCount)
            {
                _vertexBufferBinding.Buffer.Dispose();
                _indexBufferBinding.Buffer.Dispose();
                Entity.Remove(_modelComponent);
                Entity.Remove(_colliderComponent);
                CreateMesh();
            }
            else
            {
                _vertexBufferBinding.Buffer.SetData(_commandList, verts);
                _indexBufferBinding.Buffer.SetData(_commandList, tris);
                _mesh.Draw.DrawCount = tris.Length;
                Entity.Remove(_colliderComponent);
                CreateCollider();
            }
        }
        public override void Update()
        {
            // Note we can't use Start because the RenderFeature isn't initialized in time.
            var uiRenderFeature = SceneSystem.GraphicsCompositor.RenderFeatures.FirstOrDefault(x => x is UIRenderFeature) as UIRenderFeature;

            Debug.Assert(uiRenderFeature != null, "GraphicsCompositor is missing UIRenderFeature");
            if (!uiRenderFeature.Initialized)
            {
                return;
            }
            var rendererFactory = new GameUIRendererFactory(Services);

            rendererFactory.RegisterToUIRenderFeature(uiRenderFeature);

            Entity.Remove(this);    // Startup has finished, we can remove this script to prevent further action
        }
Ejemplo n.º 19
0
        public void Keys_Should_return_keys()
        {
            using World world = new World();

            using EntityMap <int> map = world.GetEntities().AsMap <int>();

            Entity entity = world.CreateEntity();

            entity.Set(42);

            Check.That(map.Keys.AsEnumerable()).ContainsExactly(42);

            entity.Remove <int>();

            Check.That(map.Keys).IsEmpty();
        }
Ejemplo n.º 20
0
        private Vector2 GetNewPosition(Entity entity, Vector2 currentPosition, Vector2 targetPosition, float state)
        {
            Vector2 newPosition = currentPosition;
            var     offset      = _speed * state;
            var     step        = GetStep(GetDirection(targetPosition, currentPosition), offset);

            if (!IsOnThePlace(newPosition, targetPosition, offset))
            {
                newPosition += step;
            }
            else
            {
                newPosition = targetPosition;
                entity.Remove <TargetPosition>();
            }
            return(newPosition);
        }
Ejemplo n.º 21
0
        public LookupTarget(string text)
        {
            text = text.Replace("[]", "¬");

            string[] split =
                text.Split(new char[] { ' ', ';', '(', ')', '{', '}', '<', '!', '|', '&', '=', '[', ']' });

            if (split.Length == 0)
            {
                return;
            }

            Name      = split[split.Length - 1];
            Entity    = Name;
            LookAhead = String.Empty;
            IsIndexed = false;

            int i = Entity.LastIndexOf('.');

            if (i != -1)
            {
                LookAhead = Entity.Substring(i + 1);
                Entity    = Entity.Substring(0, i);

                /*
                 * Set name to type name. If its a variable
                 * it will be overwritten later with the variable
                 * name; if not it's a static and the type name is
                 * the correct name.
                 */

                Name = Entity;

                if (Entity.EndsWith("¬"))
                {
                    IsIndexed = true;
                    Entity    = Entity.Remove(Entity.Length - 1);
                }
            }
            else
            {
                LookAhead = Entity;
                Entity    = String.Empty;
            }
        }
Ejemplo n.º 22
0
        // Declared public member fields and properties will show in the game studio
        public override void Update()
        {
            DebugText.Print(Game.UpdateTime.FramePerSecond.ToString(), new Int2(x: 10, y: 10));
            DebugText.Print("Weapon used : " + currentWeapon, new Int2(x: 50, y: 50));
            DebugText.Print("Script index : " + scriptUsed, new Int2(x: 50, y: 75));
            DebugText.Print(
                "[PhysicsGun : " + ((Entity.Get <MovePhysicsHandle>() != null)?1:0) +
                " ; HeatGun : " + ((Entity.Get <HeatGunScript>() != null)?1:0) + " ]"
                , new Int2(x: 50, y: 25));

            if (Input.IsKeyPressed(Keys.E))
            {
                Entity.Remove(weaponScripts[scriptUsed]);
                scriptUsed    = (scriptUsed + 1) % weaponScripts.Length;
                currentWeapon = (Weapons)scriptUsed;
                Entity.Add(weaponScripts[scriptUsed]);
            }
        }
Ejemplo n.º 23
0
        public virtual void RemoveEntity(Entity ent)
        {
            if (!ent.IsRemoved)
            {
                ent.Remove();
            }

            if (IsServer && ent.SendToClients && EntityRemoved != null)
            {
                EntityRemoved(ent);
            }

            myEntities.Remove(ent.EntityID);

            if (ent.Chunk != null)
            {
                ent.Chunk.RemoveEntity(ent);
            }
        }
Ejemplo n.º 24
0
        public void TestComponentRemovedChecksWithAllFamilies()
        {
            _game.GetNodeList <MockNode>();
            _game.GetNodeList <MockNode2>();
            var entity = new Entity();

            _game.AddEntity(entity);
            entity.Add(new Point());
            entity.Remove <Point>();
            var results = new List <int>
            {
                MockFamily.Instances[0].ComponentRemovedCalls,
                MockFamily.Instances[1].ComponentRemovedCalls
            };

            Assert.AreEqual(new List <int> {
                1, 1
            }, results);
        }
Ejemplo n.º 25
0
 public bool Remove(string code)
 {
     try
     {
         var entity = Entity.FirstOrDefault(e => e.Code == code);
         if (entity != null)
         {
             Entity.Remove(entity);
             Save();
             return(true);
         }
         else
         {
             return(false);
         }
     }
     catch (System.Exception e)
     {
         throw e;
     }
 }
Ejemplo n.º 26
0
        public void testRemoveComponent()
        {
            Entity entity = new Entity();
            Id     id     = new Id();

            id.Value = 1;
            entity.Add(id);
            Name name = new Name();

            name.Value = "bob";
            entity.Add(name);

            NodeList <TestNode> nodeList = Ash.GetNodeList <TestNode>();

            Ash.AddEntity(entity);
            //Ash.RemoveEntity(entity);
            Assert.AreEqual(nodeList.Count, 1);

            entity.Remove(typeof(Name));
            Assert.AreEqual(nodeList.Count, 0);             // entity should no longer be in nodeList
        }
Ejemplo n.º 27
0
 public override void delete()
 {
     if (this.input1Binding != null)
     {
         Entity entity = this.Input1Target.Value.Target;
         if (entity != null && entity.Active)
         {
             entity.Remove(this.input1Binding);
         }
         this.input1Binding = null;
     }
     if (this.input2Binding != null)
     {
         Entity entity = this.Input2Target.Value.Target;
         if (entity != null && entity.Active)
         {
             entity.Remove(this.input2Binding);
         }
         this.input2Binding = null;
     }
     base.delete();
 }
Ejemplo n.º 28
0
        public override void Start()
        {
            // We retrieve the Ammo component that is also attached to the current entity
            AmmoComponent ammoComponent1 = Entity.Get <AmmoComponent>();

            // We can now access public methods and properties of the retrieve component
            ammoCount1 = ammoComponent1.GetTotalAmmo();

            // We now remove the AmmoComponent from our entity. If we try to retrieve it again, null will be returned
            Entity.Remove <AmmoComponent>();
            AmmoComponent ammoComponent2 = Entity.Get <AmmoComponent>();

            // Now that 'ammoComponent' is null, we will never be able to retrieve the total ammo
            if (ammoComponent2 != null)
            {
                // This line will never happen
                ammoCount2 = ammoComponent2.GetTotalAmmo();
            }

            // Add the component again so that it doesn't crash next run
            Entity.Add(ammoComponent1);
        }
Ejemplo n.º 29
0
        private void MovePlayerTowardsTouchedPosition(Vector2 touchedPosition)
        {
            var        ray = camera.ScreenPointToRay(touchedPosition);
            RaycastHit hit;
            bool       didHit = Physics
                                .Raycast(ray, out hit, float.PositiveInfinity, layerMask);

            // Adjust for y level of player
            var destination = new Vector3(hit.point.x, player.Location.y, hit.point.z);

            if (didHit)
            {
                player.Remove(previousMove);
                player.Add(new MoveToDestination(player, destination));
            }

            if (TouchedInteractable(hit))
            {
                var model = hit.collider.GetComponent <Model>();
                if (model != null)
                {
                    //model.Entity.Add(new SpawnEntity(model.Entity, main, entityConfig));
                    //hit.collider.gameObject.SendMessage("React", player, SendMessageOptions.DontRequireReceiver);
                }
                var interaction = hit.collider.GetComponent <Interaction>();
                if (interaction != null)
                {
                    interaction.React();
                }
                var gameObject = hit.collider.gameObject;
                ExecuteEvents.Execute <InteractionReceiver>(
                    gameObject,
                    null,
                    (interactionReceiver, eventData) => {
                    interactionReceiver.Receive(new Events.Interactions.Interaction(null));
                });
            }
        }
Ejemplo n.º 30
0
        public void RenameMarketInfoRearrangeDictionary(MarketInfo marketInfo)
        {
            if (Entity.ContainsKey(marketInfo.Name))
            {
                throw new Exception("the Market[" + marketInfo.Name + "] is already defined, choose another name");
            }
            string oldMarketName = null;

            foreach (string marketName in Entity.Keys)
            {
                if (Entity[marketName] == marketInfo)
                {
                    oldMarketName = marketName;
                    break;
                }
            }
            if (string.IsNullOrEmpty(oldMarketName))
            {
                throw new Exception("CRAZY#86 the Market[" + marketInfo.Name + "] wasn't found in Markets");
            }
            Entity.Remove(oldMarketName);
            Entity.Add(marketInfo.Name, marketInfo);
        }
	// -entityToByteArray()
	// Converts the entity and its brushes into byte arrays rather than Strings,
	// which can then be written to a file much faster. Concatenating Strings is
	// a costly operation, especially when hundreds of thousands of Strings are
	// in play. This is one of two parts to writing a file quickly. The second
	// part is to call the FileOutputStream.write() method only once, with a
	// gigantic array, rather than several times with many small arrays. File I/O
	// from a hard drive is another costly operation, best done by handling
	// massive amounts of data in one go, rather than tiny amounts of data thousands
	// of times.
	private byte[] entityToByteArray(Entity inputData, int num) {
		byte[] outputData;
		Vector3D origin;
		if (inputData.BrushBased) {
			origin = inputData.Origin;
			inputData.Remove("origin");
			inputData.Remove("model");
			if (origin[0] != 0 || origin[1] != 0 || origin[2] != 0)
			{
				// If this entity uses the "origin" attribute
				MAPBrush newOriginBrush = MAPBrush.createBrush(new Vector3D(- Settings.originBrushSize, - Settings.originBrushSize, - Settings.originBrushSize), new Vector3D(Settings.originBrushSize, Settings.originBrushSize, Settings.originBrushSize), "special/origin");
				inputData.Brushes.Add(newOriginBrush);
			}
		} else {
			origin = Vector3D.ZERO;
		}
		string temp = "";
		if(!inputData["classname"].Equals("worldspawn", StringComparison.InvariantCultureIgnoreCase)) {
			temp += "// entity "+num+(char)0x0D+(char)0x0A;
		}
		temp += "{";
		int len = temp.Length+5;
		// Get the lengths of all attributes together
		foreach (string key in inputData.Attributes.Keys) {
			len += key.Length + inputData[key].Length + 7; // Four quotes, a space and a newline
		}
		outputData = new byte[len];
		int offset = 0;
		for (int i = 0; i < temp.Length; i++) {
			outputData[offset++] = (byte)temp[i];
		}
		outputData[offset++] = (byte)0x0D;
		outputData[offset++] = (byte)0x0A;
		foreach (string key in inputData.Attributes.Keys) {
			// For each attribute
			outputData[offset++] = (byte)'\"'; // 1
			for (int j = 0; j < key.Length; j++) {
				// Then for each byte in the attribute
				outputData[offset++] = (byte) key[j]; // add it to the output array
			}
			outputData[offset++] = (byte)'\"'; // 2
			outputData[offset++] = (byte)' '; // 3
			outputData[offset++] = (byte)'\"'; // 4
			for (int j = 0; j < inputData.Attributes[key].Length; j++) {
				// Then for each byte in the attribute
				outputData[offset++] = (byte) inputData.Attributes[key][j]; // add it to the output array
			}
			outputData[offset++] = (byte)'\"'; // 5
			outputData[offset++] = (byte)0x0D; // 6
			outputData[offset++] = (byte)0x0A; // 7
		}
		int brushArraySize = 0;
		byte[][] brushes = new byte[inputData.Brushes.Count][];
		for (int j = 0; j < inputData.Brushes.Count; j++)
		{
			brushes[j] = brushToByteArray(inputData.Brushes[j], j);
			brushArraySize += brushes[j].Length;
		}
		int brushoffset = 0;
		byte[] brushArray = new byte[brushArraySize];
		for (int j = 0; j < inputData.Brushes.Count; j++) {
			// For each brush in the entity
			for (int k = 0; k < brushes[j].Length; k++)
			{
				brushArray[brushoffset + k] = brushes[j][k];
			}
			brushoffset += brushes[j].Length;
		}
		if (brushArray.Length != 0)
		{
			len += brushArray.Length;
			byte[] newOut = new byte[len];
			for (int j = 0; j < outputData.Length; j++)
			{
				newOut[j] = outputData[j];
			}
			for (int j = 0; j < brushArray.Length; j++)
			{
				newOut[j + outputData.Length - 3] = brushArray[j];
			}
			offset += brushArray.Length;
			outputData = newOut;
		}
		outputData[offset++] = (byte)'}';
		outputData[offset++] = (byte)0x0D;
		outputData[offset++] = (byte)0x0A;
		return outputData;
	}
Ejemplo n.º 32
0
	// Turn a triggering entity (like a func_button or trigger_multiple) into a Source
	// engine trigger using entity I/O. There's a few complications to this: There's
	// no generic output which always acts like the triggers in other engines, and there's
	// no "Fire" input. I try to figure out which ones are best based on their classnames
	// but it's not 100% foolproof, and I have to add a case for every specific class.
	public virtual Entity parseEntityIO(Entity inEnt) {
		if (!(inEnt["target"]=="")) {
			double delay = 0.0;
			try {
				delay = Double.Parse(inEnt["delay"]);
			} catch (System.FormatException) { ; }
			if (!inEnt["target"].Equals("")) {
				Entity[] targets = getTargets(inEnt["target"]);
				for (int i = 0; i < targets.Length; i++) {
					if (targets[i].attributeIs("classname", "multi_manager") || targets[i].attributeIs("classname", "multi_kill_manager")) {
						Entity mm = parseMultimanager(targets[i]);
						//for (int j = 0; j < mm.Attributes.Count; j++) {
						foreach (Tuple<string, string, string, string, double, int, string, Tuple<string>> connection in mm.Connections) {
							if (inEnt.attributeIs("classname", "logic_relay") && inEnt.Attributes.ContainsKey("delay")) {
								inEnt.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("OnTrigger", connection.Item2, connection.Item3, connection.Item4, connection.Item5 + delay, connection.Item6, "", new Tuple<string>("")));
							} else {
								inEnt.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>(inEnt.fireAction(), connection.Item2, connection.Item3, connection.Item4, connection.Item5, connection.Item6, "", new Tuple<string>("")));
							}
						}
					} else {
						string outputAction = targets[i].onFire();
						if (inEnt.attributeIs("triggerstate", "0")) {
							outputAction = targets[i].onDisable();
						} else {
							if (inEnt.attributeIs("triggerstate", "1")) {
								outputAction = targets[i].onEnable();
							}
						}
						inEnt.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>(inEnt.fireAction(), targets[i]["targetname"], outputAction, "", delay, -1, "", new Tuple<string>("")));
					}
				}
			}
			if (!inEnt["killtarget"].Equals(""))
			{
				inEnt.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>(inEnt.fireAction(), inEnt["killtarget"], "Kill", "", delay, -1, "", new Tuple<string>("")));
			}
			inEnt.Remove("target");
			inEnt.Remove("killtarget");
			inEnt.Remove("triggerstate");
			inEnt.Remove("delay");
		}
		return inEnt;
	}
Ejemplo n.º 33
0
	// Multimanagers are also a special case. There are none in Source. Instead, I
	// need to add EVERY targetted entity in a multimanager to the original trigger
	// entity as an output with the specified delay. Things get even more complicated
	// when a multi_manager fires another multi_manager. In this case, this method will
	// recurse on itself until all the complexity is worked out.
	// One potential problem is if two multi_managers continuously call each other, this
	// method will recurse infinitely until there is a stack overflow. This might happen
	// when there is some sort of cycle going on in the map and multi_managers call each
	// other recursively to run the cycle with a delay. I solve this with an atrificial
	// limit of 8 multimanager recursions.
	// TODO: It would be better to detect this problem when it happens.
	// TODO: Instead of adding more attributes, parse into connections.
	private Entity parseMultimanager(Entity inEnt)
	{
		mmStackLength++;
		Entity dummy = new Entity(inEnt);
		dummy.Remove("classname");
		dummy.Remove("origin");
		dummy.Remove("angles");
		dummy.Remove("targetname");
		List<string> delete = new List<string>();
		foreach(string st in dummy.Attributes.Keys) {
			string target = st;
			double delay = 0.0;
			try {
				delay = Double.Parse(dummy[st]);
			} catch {
			}
			for (int j = target.Length - 1; j >= 0; j--)
			{
				if (target[j] == '#')
				{
					target = target.Substring(0, (j) - (0));
					//dummy.renameAttribute(st, target);
					break;
				}
			}
			Entity[] targets = getTargets(target);
			delete.Add(st);
			for (int j = 0; j < targets.Length; j++)
			{
				if (inEnt.attributeIs("classname", "multi_kill_manager"))
				{
					if (targets.Length > 1)
					{
						dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("condition", target + j, "Kill", "", delay, -1, "", new Tuple<string>("")));
					}
					else
					{
						dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("condition", target, "Kill", "", delay, -1, "", new Tuple<string>("")));
					}
				}
				else
				{
					if (targets[j].attributeIs("classname", "multi_manager") || targets[j].attributeIs("classname", "multi_kill_manager"))
					{
						if (mmStackLength <= Settings.MMStackSize)
						{
							Entity mm = parseMultimanager(targets[j]);
							foreach (Tuple<string, string, string, string, double, int, string, Tuple<string>> connection in mm.Connections) {
								dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>(connection.Item1, connection.Item2, connection.Item3, connection.Item4, connection.Item5 + delay, connection.Item6, connection.Item7, connection.Rest));
							}
						}
						else
						{
							DecompilerThread.OnMessage(this, "WARNING: Multimanager stack overflow on entity " + inEnt["targetname"] + " calling " + targets[j]["targetname"] + "!");
							DecompilerThread.OnMessage(this, "This is probably because of multi_managers repeatedly calling eachother. You can increase multimanager stack size in debug options.");
						}
					}
					else
					{
						if (targets.Length > 1)
						{
							//for(int k = 0; k < targets.Length; k++) {
								string outputAction = targets[j].onFire();
								if (inEnt.attributeIs("triggerstate", "0"))
								{
									outputAction = targets[j].onDisable();
								}
								else
								{
									if (inEnt.attributeIs("triggerstate", "1"))
									{
										outputAction = targets[j].onEnable();
									}
								}
								dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("condition", target+j, outputAction, "", delay, -1, "", new Tuple<string>("")));
							//}
						}
						else if(targets.Length == 1) {
							string outputAction = targets[0].onFire();
							if (inEnt.attributeIs("triggerstate", "0"))
							{
								outputAction = targets[0].onDisable();
							}
							else
							{
								if (inEnt.attributeIs("triggerstate", "1"))
								{
									outputAction = targets[0].onEnable();
								}
							}
							dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("condition", target, outputAction, "", delay, -1, "", new Tuple<string>("")));
						} else {
							dummy.Connections.Add(new Tuple<string, string, string, string, double, int, string, Tuple<string>>("condition", target, "Toggle", "", delay, -1, "", new Tuple<string>("")));
						}
					}
				}
			}
		}
		foreach(string st in delete) {
			dummy.Remove(st);
		}
		mmStackLength--;
		return dummy;
	}
Ejemplo n.º 34
0
	// -entityToByteArray()
	// Converts the entity and its brushes into byte arrays rather than Strings,
	// which can then be written to a file much faster. Concatenating Strings is
	// a costly operation, especially when hundreds of thousands of Strings are
	// in play. This is one of two parts to writing a file quickly. The second
	// part is to call the FileOutputStream.write() method only once, with a
	// gigantic array, rather than several times with many small arrays. File I/O
	// from a hard drive is another costly operation, best done by handling
	// massive amounts of data in one go, rather than tiny amounts of data thousands
	// of times.
	private byte[] entityToByteArray(Entity inEnt) {
		inEnt["id"] = ((System.Int32) nextID++).ToString();
		byte[] outputData;
		Vector3D origin = Vector3D.ZERO;
		if (inEnt.BrushBased) {
			inEnt.Remove("model");
		}
		if (inEnt.Brushes.Count > 0)
		{
			origin = inEnt.Origin;
		}
		string temp;
		if(inEnt["classname"].Equals("worldspawn", StringComparison.InvariantCultureIgnoreCase)) {
			temp = "world"+(char)0x0D+(char)0x0A+"{"+(char)0x0D+(char)0x0A;
		} else {
			temp = "entity"+(char)0x0D+(char)0x0A+"{"+(char)0x0D+(char)0x0A;
		}
		int len = temp.Length+3; // Closing brace, newline
		// Get the lengths of all attributes together
		foreach (string key in inEnt.Attributes.Keys) {
			len += key.Length + inEnt[key].Length + 8; // Four quotes, a space, a tab and a newline
		}
		if (inEnt.Connections.Count > 0) {
			len += 22; // tab, "connections", newline, tab, "{", newline, tab, "}", newline
			foreach (Tuple<string, string, string, string, double, int, string, Tuple<string>> connection in inEnt.Connections) {
				if(connection.Item7 == "" && connection.Rest.Item1 == "") {
					len += connection.Item1.Length + connection.Item2.Length + connection.Item3.Length + connection.Item4.Length + connection.Item5.ToString().Length + connection.Item6.ToString().Length + 13; // Two tabs, four quotes, space, four commas, newline
				} else {
					len += connection.Item1.Length + connection.Item2.Length + connection.Item3.Length + connection.Item4.Length + connection.Item5.ToString().Length + connection.Item6.ToString().Length + connection.Item7.Length + connection.Rest.Item1.Length + 15; // Two tabs, four quotes, space, six commas, newline
				}
			}
		}
		outputData = new byte[len];
		int offset = 0;
		for (int i = 0; i < temp.Length; i++) {
			outputData[offset++] = (byte)temp[i];
		}
		foreach (string key in inEnt.Attributes.Keys) {
			outputData[offset++] = (byte) (0x09); // 1
			outputData[offset++] = (byte)'\"'; // 2
			for (int j = 0; j < key.Length; j++) {
				// Then for each byte in the attribute
				outputData[j + offset] = (byte) key[j]; // add it to the output array
			}
			offset += key.Length;
			outputData[offset++] = (byte)'\"'; // 3
			outputData[offset++] = (byte)' '; // 4
			outputData[offset++] = (byte)'\"'; // 5
			for (int j = 0; j < inEnt.Attributes[key].Length; j++) {
				// Then for each byte in the attribute
				outputData[j + offset] = (byte) inEnt.Attributes[key][j]; // add it to the output array
			}
			offset += inEnt.Attributes[key].Length;
			outputData[offset++] = (byte)'\"'; // 6
			outputData[offset++] = (byte)0x0D; // 7
			outputData[offset++] = (byte)0x0A; // 8
		}
		if (inEnt.Connections.Count > 0) {
			outputData[offset++] = (byte)0x09; // tab 1
			outputData[offset++] = (byte)'c'; // 2
			outputData[offset++] = (byte)'o'; // 3
			outputData[offset++] = (byte)'n'; // 4
			outputData[offset++] = (byte)'n'; // 5
			outputData[offset++] = (byte)'e'; // 6
			outputData[offset++] = (byte)'c'; // 7
			outputData[offset++] = (byte)'t'; // 8
			outputData[offset++] = (byte)'i'; // 9
			outputData[offset++] = (byte)'o'; // 10
			outputData[offset++] = (byte)'n'; // 11
			outputData[offset++] = (byte)'s'; // 12
			outputData[offset++] = (byte)0x0D; // 13
			outputData[offset++] = (byte)0x0A; // newline 14
			outputData[offset++] = (byte)0x09; //tab 15
			outputData[offset++] = (byte)'{'; // 16
			outputData[offset++] = (byte)0x0D; // 17
			outputData[offset++] = (byte)0x0A; // newline 18
			foreach (Tuple<string, string, string, string, double, int, string, Tuple<string>> connection in inEnt.Connections) {
				string str = "";
				if(connection.Item7 == "" && connection.Rest.Item1 == "") {
					str = ""+(char)0x09 + (char)0x09 + "\""+connection.Item1+"\" \""+connection.Item2+","+connection.Item3+","+connection.Item4+","+connection.Item5.ToString()+","+connection.Item6.ToString()+"\""+(char)0x0D+(char)0x0A;
				} else {
					str = ""+(char)0x09 + (char)0x09 + "\""+connection.Item1+"\" \""+connection.Item2+","+connection.Item3+","+connection.Item4+","+connection.Item5.ToString()+","+connection.Item6.ToString()+","+connection.Item7+","+connection.Rest.Item1+"\""+(char)0x0D+(char)0x0A;
				}
				for (int j = 0; j < str.Length; j++) {
					// Then for each byte in the string
					outputData[offset++] = (byte)str[j]; // add it to the output array
				}
			}
			outputData[offset++] = (byte)0x09; // tab 19
			outputData[offset++] = (byte)'}'; // 20
			outputData[offset++] = (byte)0x0D; // 21
			outputData[offset++] = (byte)0x0A; // newline 22
		}
		int brushArraySize = 0;
		byte[][] brushes = new byte[inEnt.Brushes.Count][];
		for (int j = 0; j < inEnt.Brushes.Count; j++)
		{
			// For each brush in the entity
			bool containsNonClipSide = false;
			for (int k=0; k<inEnt.Brushes[j].NumSides; k++) {
				if (!inEnt.Brushes[j][k].Texture.ToLower().Contains("clip")) {
					containsNonClipSide = true;
					break;
				}
			}
			if (inEnt.Brushes[j].Detail && inEnt.attributeIs("classname", "worldspawn") && containsNonClipSide)
			{
				inEnt.Brushes[j].Detail = false; // Otherwise it will add an infinite number of func_details to the array
				Entity newDetailEntity = new Entity("func_detail");
				for (int k = 0; k < inEnt.Brushes[j].NumSides; k++)
				{
					MAPBrushSide currentSide = inEnt.Brushes[j][k];
					if (currentSide.Texture.Equals("special/TRIGGER", StringComparison.InvariantCultureIgnoreCase))
					{
						currentSide.Texture = "TOOLS/TOOLSHINT"; // Hint is the only thing that still works that doesn't collide with the player
					}
				}
				newDetailEntity.Brushes.Add(inEnt.Brushes[j]);
				data.Add(newDetailEntity);
				brushes[j] = new byte[0]; // No data here! The brush will be output in its entity instead.
			}
			else
			{
				inEnt.Brushes[j].translate(new Vector3D(origin));
				brushes[j] = brushToByteArray(inEnt.Brushes[j]);
				brushArraySize += brushes[j].Length;
			}
		}
		int brushoffset = 0;
		byte[] brushArray = new byte[brushArraySize];
		for (int j = 0; j < inEnt.Brushes.Count; j++)
		{
			// For each brush in the entity
			for (int k = 0; k < brushes[j].Length; k++)
			{
				brushArray[brushoffset + k] = brushes[j][k];
			}
			brushoffset += brushes[j].Length;
		}
		if (brushArray.Length != 0)
		{
			len += brushArray.Length;
			byte[] newOut = new byte[len];
			for (int j = 0; j < outputData.Length; j++)
			{
				newOut[j] = outputData[j];
			}
			for (int j = 0; j < brushArray.Length; j++)
			{
				newOut[j + outputData.Length - 3] = brushArray[j];
			}
			offset += brushArray.Length;
			outputData = newOut;
		}
		outputData[offset++] = (byte)'}';
		outputData[offset++] = (byte)0x0D;
		outputData[offset++] = (byte)0x0A;
		return outputData;
	}
Ejemplo n.º 35
0
	// Turn a Q2 entity into a Hammer one. This won't magically fix every single
	// thing to work in Gearcraft, for example the Nightfire engine had no support
	// for area portals. But it should save map porters some time, especially when
	// it comes to the Capture The Flag mod.
	public virtual Entity ent38ToEntVMF(Entity inEnt)
	{
		if (!inEnt["angle"].Equals(""))
		{
			inEnt["angles"] = "0 " + inEnt["angle"] + " 0";
			inEnt.Remove("angle");
		}
		if (inEnt.attributeIs("classname", "func_wall"))
		{
			inEnt["classname"] = "func_brush";
			if (!inEnt["targetname"].Equals(""))
			{
				// Really this should depend on spawnflag 2 or 4
				inEnt["solidity"] = "0"; // TODO: Make sure the attribute is actually "solidity"
			}
			else
			{
				// 2 I believe is "Start enabled" and 4 is "toggleable", or the other way around. Not sure. Could use an OR.
				inEnt["solidity"] = "2";
			}
		}
		else
		{
			if (inEnt.attributeIs("classname", "info_player_start"))
			{
				Vector3D origin = inEnt.Origin;
				inEnt["origin"] = origin.X + " " + origin.Y + " " + (origin.Z + 18);
			}
			else
			{
				if (inEnt.attributeIs("classname", "info_player_deathmatch"))
				{
					Vector3D origin = inEnt.Origin;
					inEnt["origin"] = origin.X + " " + origin.Y + " " + (origin.Z + 18);
				}
				else
				{
					if (inEnt.attributeIs("classname", "light"))
					{
						string color = inEnt["_color"];
						string intensity = inEnt["light"];
						string[] nums = color.Split(' ');
						double[] lightNumbers = new double[4];
						for (int j = 0; j < 3 && j < nums.Length; j++)
						{
							try
							{
								lightNumbers[j] = Double.Parse(nums[j]);
								lightNumbers[j] *= 255; // Quake 2's numbers are from 0 to 1, Nightfire are from 0 to 255
							}
							catch (System.FormatException)
							{
								;
							}
						}
						try
						{
							lightNumbers[s] = System.Double.Parse(intensity) / 2; // Quake 2's light intensity is waaaaaay too bright
						}
						catch (System.FormatException)
						{
							;
						}
						inEnt.Remove("_color");
						inEnt.Remove("light");
						inEnt["_light"] = lightNumbers[r] + " " + lightNumbers[g] + " " + lightNumbers[b] + " " + lightNumbers[s];
					}
					else
					{
						if (inEnt.attributeIs("classname", "misc_teleporter"))
						{
							Vector3D origin = inEnt.Origin;
							Vector3D mins = new Vector3D(origin.X - 24, origin.Y - 24, origin.Z - 24);
							Vector3D maxs = new Vector3D(origin.X + 24, origin.Y + 24, origin.Z + 48);
							inEnt.Brushes.Add(MAPBrush.createBrush(mins, maxs, "tools/toolstrigger"));
							inEnt.Remove("origin");
							inEnt["classname"] = "trigger_teleport";
						}
						else
						{
							if (inEnt.attributeIs("classname", "misc_teleporter_dest"))
							{
								inEnt["classname"] = "info_target";
							}
						}
					}
				}
			}
		}
		return inEnt;
	}
Ejemplo n.º 36
0
	// Turn a Nightfire entity into a Hammer one.
	public virtual Entity ent42ToEntVMF(Entity inEnt)
	{
		if(inEnt.Angles[0] != 0) {
			inEnt["angles"] = (-inEnt.Angles[0])+" "+inEnt.Angles[1]+" "+inEnt.Angles[2];
		}
		if (!inEnt["body"].Equals(""))
		{
			inEnt.renameAttribute("body", "SetBodyGroup");
		}
		if (inEnt["rendercolor"].Equals("0 0 0"))
		{
			inEnt["rendercolor"] = "255 255 255";
		}
		if (inEnt["angles"].Equals("0 -1 0"))
		{
			inEnt["angles"] = "-90 0 0";
		}
		try
		{
			if (inEnt["model"].Substring(inEnt["model"].Length - 4).ToUpper().Equals(".spz".ToUpper()))
			{
				inEnt["model"] = inEnt["model"].Substring(0, (inEnt["model"].Length - 4) - (0)) + ".spr";
			}
		}
		catch (System.ArgumentOutOfRangeException)
		{
			;
		}
		if (inEnt.attributeIs("classname", "light_spot"))
		{
			try
			{
				inEnt["pitch"] = ((double) (inEnt.Angles[0] + System.Double.Parse(inEnt["pitch"]))).ToString();
			}
			catch (System.FormatException e)
			{
				inEnt["pitch"] = ((double) inEnt.Angles[0]).ToString();
			}
			try
			{
				if (System.Double.Parse(inEnt["_cone"]) > 90.0)
				{
					inEnt["_cone"] = "90";
				}
				else
				{
					if (System.Double.Parse(inEnt["_cone"]) < 0.0)
					{
						inEnt["_cone"] = "0";
					}
				}
			}
			catch (System.FormatException e)
			{
				;
			}
			try
			{
				if (System.Double.Parse(inEnt["_cone2"]) > 90.0)
				{
					inEnt["_cone2"] = "90";
				}
				else
				{
					if (System.Double.Parse(inEnt["_cone2"]) < 0.0)
					{
						inEnt["_cone2"] = "0";
					}
				}
			}
			catch (System.FormatException e)
			{
				;
			}
			inEnt.renameAttribute("_cone", "_inner_cone");
			inEnt.renameAttribute("_cone2", "_cone");
		}
		else
		{
			if (inEnt.attributeIs("classname", "func_wall"))
			{
				if (inEnt["rendermode"].Equals("0"))
				{
					inEnt["classname"] = "func_detail";
					for (int i = 0; i < inEnt.Brushes.Count; i++)
					{
						MAPBrush currentBrush = inEnt.Brushes[i];
						for (int j = 0; j < currentBrush.NumSides; j++)
						{
							MAPBrushSide currentSide = currentBrush[j];
							if (currentSide.Texture.Equals("special/TRIGGER", StringComparison.InvariantCultureIgnoreCase))
							{
								currentSide.Texture = "TOOLS/TOOLSHINT"; // Hint is the only thing that still works that doesn't collide with the player
							}
						}
					}
					inEnt.Remove("rendermode");
				}
				else
				{
					inEnt["classname"] = "func_brush";
					inEnt["solidity"] = "2";
					inEnt.Remove("angles");
				}
			}
			else
			{
				if (inEnt.attributeIs("classname", "func_wall_toggle"))
				{
					inEnt["classname"] = "func_brush";
					inEnt["solidity"] = "0";
					inEnt.Remove("angles");
					try
					{
						if (inEnt.spawnflagsSet(1))
						{
							inEnt["StartDisabled"] = "1";
							inEnt.disableSpawnflags(1);
						}
						else
						{
							inEnt["StartDisabled"] = "0";
						}
					}
					catch (System.FormatException)
					{
						inEnt["StartDisabled"] = "0";
					}
				}
				else
				{
					if (inEnt.attributeIs("classname", "func_illusionary"))
					{
						inEnt["classname"] = "func_brush";
						inEnt["solidity"] = "1";
						inEnt.Remove("angles");
					}
					else
					{
						if (inEnt.attributeIs("classname", "item_generic"))
						{
							inEnt["classname"] = "prop_dynamic";
							inEnt["solid"] = "0";
							inEnt.Remove("effects");
							inEnt.Remove("fixedlight");
						}
						else
						{
							if (inEnt.attributeIs("classname", "env_glow"))
							{
								inEnt["classname"] = "env_sprite";
							}
							else
							{
								if (inEnt.attributeIs("classname", "info_teleport_destination"))
								{
									inEnt["classname"] = "info_target";
								}
								else
								{
									if (inEnt.attributeIs("classname", "info_player_deathmatch") || inEnt.attributeIs("classname", "info_player_start"))
									{
										Vector3D origin = inEnt.Origin;
										inEnt["origin"] = origin.X + " " + origin.Y + " " + (origin.Z - 40);
									}
									else
									{
										if (inEnt.attributeIs("classname", "info_ctfspawn"))
										{
											if (inEnt["team_no"].Equals("1"))
											{
												inEnt["classname"] = "ctf_combine_player_spawn";
												inEnt.Remove("team_no");
											}
											else
											{
												if (inEnt["team_no"].Equals("2"))
												{
													inEnt["classname"] = "ctf_rebel_player_spawn";
													inEnt.Remove("team_no");
												}
											}
											Vector3D origin = inEnt.Origin;
											inEnt["origin"] = origin.X + " " + origin.Y + " " + (origin.Z - 40);
										}
										else
										{
											if (inEnt.attributeIs("classname", "item_ctfflag"))
											{
												inEnt.Remove("skin");
												inEnt.Remove("goal_min");
												inEnt.Remove("goal_max");
												inEnt.Remove("model");
												inEnt["SpawnWithCaptureEnabled"] = "1";
												if (inEnt["goal_no"].Equals("1"))
												{
													inEnt["classname"] = "ctf_combine_flag";
													inEnt["targetname"] = "combine_flag";
													inEnt.Remove("goal_no");
												}
												else
												{
													if (inEnt["goal_no"].Equals("2"))
													{
														inEnt["classname"] = "ctf_rebel_flag";
														inEnt["targetname"] = "rebel_flag";
														inEnt.Remove("goal_no");
													}
												}
											}
											else
											{
												if (inEnt.attributeIs("classname", "func_ladder"))
												{
													for (int i = 0; i < inEnt.Brushes.Count; i++)
													{
														MAPBrush currentBrush = inEnt.Brushes[i];
														for (int j = 0; j < currentBrush.NumSides; j++)
														{
															MAPBrushSide currentSide = currentBrush[j];
															currentSide.Texture = "TOOLS/TOOLSINVISIBLELADDER";
														}
													}
												}
												else
												{
													if (inEnt.attributeIs("classname", "func_door"))
													{
														inEnt["movedir"] = inEnt["angles"];
														inEnt["noise1"] = inEnt["movement_noise"];
														inEnt.Remove("movement_noise");
														inEnt.Remove("angles");
														if (inEnt.spawnflagsSet(1))
														{
															inEnt["spawnpos"] = "1";
															inEnt.disableSpawnflags(1);
														}
														inEnt["renderamt"] = "255";
													}
													else
													{
														if (inEnt.attributeIs("classname", "func_button"))
														{
															inEnt["movedir"] = inEnt["angles"];
															inEnt.Remove("angles");
															for (int i = 0; i < inEnt.Brushes.Count; i++)
															{
																MAPBrush currentBrush = inEnt.Brushes[i];
																for (int j = 0; j < currentBrush.NumSides; j++)
																{
																	MAPBrushSide currentSide = currentBrush[j];
																	if (currentSide.Texture.Equals("special/TRIGGER", StringComparison.InvariantCultureIgnoreCase))
																	{
																		currentSide.Texture = "TOOLS/TOOLSHINT"; // Hint is the only thing that still works that doesn't collide with the player
																	}
																}
															}
															if (!inEnt.spawnflagsSet(256))
															{
																// Nightfire's "touch activates" flag, same as source!
																if (!inEnt["health"].Equals("") && !inEnt["health"].Equals("0"))
																{
																	inEnt.enableSpawnflags(512);
																}
																else
																{
																	inEnt.enableSpawnflags(1024);
																}
															}
														}
														else
														{
															if (inEnt.attributeIs("classname", "trigger_hurt"))
															{
																if (inEnt.spawnflagsSet(2))
																{
																	inEnt["StartDisabled"] = "1";
																}
																if (!inEnt.spawnflagsSet(8))
																{
																	inEnt["spawnflags"] = "1";
																}
																else
																{
																	inEnt["spawnflags"] = "0";
																}
																inEnt.renameAttribute("dmg", "damage");
															}
															else
															{
																if (inEnt.attributeIs("classname", "trigger_auto"))
																{
																	inEnt["classname"] = "logic_auto";
																}
																else
																{
																	if (inEnt.attributeIs("classname", "trigger_once") || inEnt.attributeIs("classname", "trigger_multiple"))
																	{
																		if (inEnt.spawnflagsSet(8) || inEnt.spawnflagsSet(1))
																		{
																			inEnt.disableSpawnflags(1);
																			inEnt.disableSpawnflags(8);
																			inEnt.enableSpawnflags(2);
																		}
																		if (inEnt.spawnflagsSet(2))
																		{
																			inEnt.disableSpawnflags(1);
																		}
																		else
																		{
																			inEnt.enableSpawnflags(1);
																		}
																	}
																	else
																	{
																		if (inEnt.attributeIs("classname", "func_door_rotating"))
																		{
																			if (inEnt.spawnflagsSet(1))
																			{
																				inEnt["spawnpos"] = "1";
																				inEnt.disableSpawnflags(1);
																			}
																			inEnt["noise1"] = inEnt["movement_noise"];
																			inEnt.Remove("movement_noise");
																		}
																		else
																		{
																			if (inEnt.attributeIs("classname", "trigger_push"))
																			{
																				inEnt["pushdir"] = inEnt["angles"];
																				inEnt.Remove("angles");
																			}
																			else
																			{
																				if (inEnt.attributeIs("classname", "light_environment"))
																				{
																					Entity newShadowControl = new Entity("shadow_control");
																					Entity newEnvSun = new Entity("env_sun");
																					newShadowControl["angles"] = inEnt["angles"];
																					newEnvSun["angles"] = inEnt["angles"];
																					newShadowControl["origin"] = inEnt["origin"];
																					newEnvSun["origin"] = inEnt["origin"];
																					newShadowControl["color"] ="128 128 128";
																					data.Add(newShadowControl);
																					data.Add(newEnvSun);
																				}
																				else
																				{
																					if (inEnt.attributeIs("classname", "func_rot_button"))
																					{
																						inEnt.Remove("angles");
																						for (int i = 0; i < inEnt.Brushes.Count; i++)
																						{
																							MAPBrush currentBrush = inEnt.Brushes[i];
																							for (int j = 0; j < currentBrush.NumSides; j++)
																							{
																								MAPBrushSide currentSide = currentBrush[j];
																								if (currentSide.Texture.ToUpper().Equals("special/TRIGGER".ToUpper()))
																								{
																									currentSide.Texture = "TOOLS/TOOLSHINT"; // Hint is the only thing that still works that doesn't collide with the player
																								}
																							}
																						}
																						if (!inEnt.spawnflagsSet(256))
																						{
																							// Nightfire's "touch activates" flag, same as source!
																							if (!inEnt["health"].Equals("") && !inEnt["health"].Equals("0"))
																							{
																								inEnt.enableSpawnflags(512);
																							}
																							else
																							{
																								inEnt.enableSpawnflags(1024);
																							}
																						}
																					}
																					else
																					{
																						if (inEnt.attributeIs("classname", "func_tracktrain"))
																						{
																							inEnt.renameAttribute("movesnd", "MoveSound");
																							inEnt.renameAttribute("stopsnd", "StopSound");
																						}
																						else
																						{
																							if (inEnt.attributeIs("classname", "path_track"))
																							{
																								if (inEnt.spawnflagsSet(1))
																								{
																									inEnt.Remove("targetname");
																								}
																							}
																							else
																							{
																								if (inEnt.attributeIs("classname", "trigger_relay"))
																								{
																									inEnt["classname"] = "logic_relay";
																								}
																								else
																								{
																									if (inEnt.attributeIs("classname", "trigger_counter"))
																									{
																										inEnt["classname"] = "math_counter";
																										inEnt["max"] = inEnt["count"];
																										inEnt["min"] = "0";
																										inEnt["startvalue"] = "0";
																										inEnt.Remove("count");
																									}
																								}
																							}
																						}
																					}
																				}
																			}
																		}
																	} // Lol
																} // so
															} // many
														} // closing
													} // braces
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		return inEnt;
	}
	// -entityToByteArray()
	// Converts the entity and its brushes into byte arrays rather than Strings,
	// which can then be written to a file much faster. Concatenating Strings is
	// a costly operation, especially when hundreds of thousands of Strings are
	// in play. This is one of two parts to writing a file quickly. The second
	// part is to call the FileOutputStream.write() method only once, with a
	// gigantic array, rather than several times with many small arrays. File I/O
	// from a hard drive is another costly operation, best done by handling
	// massive amounts of data in one go, rather than tiny amounts of data thousands
	// of times.
	private byte[] entityToByteArray(Entity inEnt) {
		byte[] output;
		Vector3D origin = Vector3D.ZERO;
		if (inEnt.BrushBased) {
			inEnt.Remove("model");
		}
		if (inEnt.Brushes.Count > 0) {
			origin = inEnt.Origin;
		}
		string temp = "// entity "+currentEntity+(char)0x0A+"{"+(char)0x0A;
		int len = temp.Length + 2; // Closing brace and a newline
		// Get the lengths of all attributes together
		foreach (string key in inEnt.Attributes.Keys) {
			len += key.Length + inEnt.Attributes[key].Length + 6; // Four quotes, a space and a newline
		}
		output = new byte[len];
		int offset = 0;
		for(int i=0;i<temp.Length;i++) {
			output[offset++] = (byte)temp[i];
		}
		foreach (string key in inEnt.Attributes.Keys) {
			// For each attribute
			output[offset++] = (byte)'\"'; // 1
			for (int j = 0; j < key.Length; j++) {
				// Then for each byte in the attribute
				output[j + offset] = (byte) key[j]; // add it to the output array
			}
			offset += key.Length;
			output[offset++] = (byte)'\"'; // 2
			output[offset++] = (byte)' '; // 3
			output[offset++] = (byte)'\"'; // 4
			for (int j = 0; j < inEnt.Attributes[key].Length; j++) {
				// Then for each byte in the attribute
				output[j + offset] = (byte) inEnt.Attributes[key][j]; // add it to the output array
			}
			offset += inEnt.Attributes[key].Length;
			output[offset++] = (byte)'\"'; // 5
			output[offset++] = (byte)0x0D; // 6
		}
		int brushArraySize = 0;
		byte[][] brushes = new byte[inEnt.Brushes.Count][];
		for (int j = 0; j < inEnt.Brushes.Count; j++) {
			// For each brush in the entity
			// models with origin brushes need to be offset into their in-use position
			inEnt.Brushes[j].translate(origin);
			brushes[j] = brushToByteArray(inEnt.Brushes[j], j);
			brushArraySize += brushes[j].Length;
		}
		int brushoffset = 0;
		byte[] brushArray = new byte[brushArraySize];
		for (int j = 0; j < inEnt.Brushes.Count; j++) {
			// For each brush in the entity
			for (int k = 0; k < brushes[j].Length; k++) {
				brushArray[brushoffset + k] = brushes[j][k];
			}
			brushoffset += brushes[j].Length;
		}
		if (brushArray.Length != 0) {
			len += brushArray.Length;
			byte[] newOut = new byte[len];
			for (int j = 0; j < output.Length; j++) {
				newOut[j] = output[j];
			}
			for (int j = 0; j < brushArray.Length; j++) {
				newOut[j + output.Length - 2] = brushArray[j];
			}
			offset += brushArray.Length;
			output = newOut;
		}
		output[offset++] = (byte)'}';
		output[offset++] = (byte)0x0A;
		return output;
	}
	// TODO: Polish these up.
	public virtual Entity ent42ToEntRad(Entity inEnt) {
		if (inEnt["classname"].Equals("func_door_rotating", StringComparison.InvariantCultureIgnoreCase)) {
			inEnt["classname"] = "func_rotatingdoor";
		} else {
			if (inEnt["classname"].Equals("worldspawn", StringComparison.InvariantCultureIgnoreCase)) {
				inEnt.Remove("mapversion");
			}
		}
		return inEnt;
	}