DIFF

RebuildingSpawner.c

#ifdef DIAG_DEVELOPER
class RebuildingSpawner
{
	static PlayerBase m_Player;
	static EntityAI m_Rebuidable;
	static ref array<string> m_AllRebuildableTypes;
	static ref array<string> m_RebuildableTypesUsed = {};
	static float m_Delay = 3000.0; //ms
	static float m_Dist = 10.0; //m
	static int m_LastIdx = -1;
	static bool m_IsSpawned;
	static bool m_Loop;
	static vector m_SpawnPos;
	
	static int m_DbgLockCounter;
	
	static void StartRebuildablesSpawning(bool loop = false, array<string> overrides = null)
	{
		//in case you also doubleclick by accident
		StopRebuildablesSpawning();
		
		if (!overrides)
		{
			if (!m_AllRebuildableTypes)
				InitAllRebuildableTypes();
			
			m_RebuildableTypesUsed.Copy(m_AllRebuildableTypes);
		}
		else
		{
			m_RebuildableTypesUsed.Copy(overrides);
		}
		
		if (g_Game.IsDedicatedServer())
			m_Player = PlayerBase.Cast(g_Game.GetPlayerByIndex());
		else
			m_Player = PlayerBase.Cast(g_Game.GetPlayer());
		m_SpawnPos = m_Player.GetPosition() + m_Player.GetDirection() * m_Dist;
		
		m_LastIdx = -1;
		m_Loop = loop;
		if (m_Rebuidable)
			m_Rebuidable.DeleteSafe();
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ProcessRebuildablesSpawning, m_Delay);
	}
	
	static void StopRebuildablesSpawning()
	{
		if (m_Rebuidable)
			m_Rebuidable.DeleteSafe();
		g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(ProcessRebuildablesSpawning);
	}
	
	///////////////////////////////////
	
	protected static void InitAllRebuildableTypes()
	{
		string basePath = "cfgVehicles";
		string typeName;
		m_AllRebuildableTypes = new array<string>();
		int count = g_Game.ConfigGetChildrenCount(basePath);
		for (int q = 0; q < count; ++q)
		{
			g_Game.ConfigGetChildName(basePath, q, typeName);
			string cfgPath = "cfgVehicles " + typeName + " Construction";
			if (g_Game.ConfigIsExisting(cfgPath) && !g_Game.IsKindOf(typeName, "BaseBuildingBase"))
				m_AllRebuildableTypes.Insert(typeName);
		}
	}
	
	protected static void ProcessRebuildablesSpawning()
	{
		if (m_Rebuidable)
		{
			m_Rebuidable.DeleteSafe();
			
		if (m_LastIdx >= m_RebuildableTypesUsed.Count() - 1)
			{
				if (m_Loop)
					m_LastIdx = -1;
				else
					return;
			}
			g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ProcessRebuildablesSpawning, m_Delay);
		}
		else
		{
			++m_LastIdx;
			if (m_LastIdx >= m_RebuildableTypesUsed.Count())
				return;
			
			SpawnAndRebuildAllParts(m_RebuildableTypesUsed[m_LastIdx]);
			g_Game.GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(ProcessRebuildablesSpawning, m_Delay);
		}
	}
	
	protected static void SpawnAndRebuildAllParts(string type)
	{
		m_Rebuidable = EntityAI.Cast(g_Game.CreateObjectEx(type, m_SpawnPos, ECE_PLACE_ON_SURFACE));
		ConstructionBase con = ConstructionBase.Cast(m_Rebuidable.GetConstructionBasic());
		map<string, ref ConstructionPart> partsMap = con.GetConstructionParts(); //simple array under define, too lazy to solve now
		foreach (string name, ref ConstructionPart part : partsMap) 
		{
			con.BuildPartServerEx(null, name, -1);
		}
	}
	
	static void RebuildAllWoodenPartsFiltered(ConstructionBase con, EntityAI ent)
	{
		TStringArray wallsDoored = new TStringArray();
		TStringArray wallsWindowed = new TStringArray();
		TStringArray wallsSimple = new TStringArray();
		TStringArray doors = new TStringArray();
		TStringArray windows = new TStringArray();
		
		string tmp;
		GetCLIParam("RBLDRebuildEverythingWithLocks", tmp);
		int maxTotalLockCount = tmp.ToInt();
		GameInventory inv = ent.GetInventory();
		
		//Print("DbgLocks | Entity: " + ent + " | lock count: " + (RebuildingSpawner.m_DbgLockCounter - 1));
		//go through all parts first, directly build the simple ones
		array<ConstructionPart> constructionPartArray = con.GetConstructionPartArray();
		foreach (ConstructionPart part : constructionPartArray)
		{
			if (part.IsUtilityPart())
				continue;
			
			string partName = part.GetPartName();
			if (partName.Contains("rubble") || partName.Contains("roof"))
			{
				con.BuildPartServerEx(null, partName, -1);
				continue;
			}
			
			if (!partName.Contains("_wood"))
				continue;
			
			if (partName.Contains("wall"))
			{
				if (partName.Contains("_window_"))
					wallsWindowed.Insert(partName);
				if (partName.Contains("_door_"))
					wallsDoored.Insert(partName);
				else
					wallsSimple.Insert(partName);
			}
			else if (partName.Contains("door"))
			{
				doors.Insert(partName);
			}
			else if (partName.Contains("window"))
			{
				windows.Insert(partName);
			}
		}
		
		//1. walls with doors
		foreach (string wallWithDoors : wallsDoored)
		{
			if (!con.HasConflictPart(wallWithDoors))
				con.BuildPartServerEx(null, wallWithDoors, -1);
		}
		
		//2. walls with windows
		foreach (string wallWithWindows : wallsWindowed)
		{
			if (!con.HasConflictPart(wallWithWindows))
				con.BuildPartServerEx(null, wallWithWindows, -1);
		}
		
		//3. simple walls
		foreach (string wallSimple : wallsSimple)
		{
			if (!con.HasConflictPart(wallSimple))
				con.BuildPartServerEx(null, wallSimple, -1);
		}
		
		//4. doors
		foreach (string door : doors)
		{
			if (!con.HasConflictPart(door) && con.HasRequiredPart(door)) //later parts need to check requirements too
			{
				con.BuildPartServerEx(null, door, -1);
				
				if (m_DbgLockCounter > maxTotalLockCount)
					continue;
				
				int idx1 = door.IndexOf("door") + 4;
				int idx2 = door.IndexOf("_wood");
				string attSlotName = door.Substring(idx1, idx2 - idx1); //slot number
				attSlotName = string.Format("Att_CodeLock%1_Wood", attSlotName);
				int slotID = InventorySlots.GetSlotIdFromString(attSlotName);
				DigitalCodeLock lock;
				
				if (Class.CastTo(lock, inv.FindAttachment(slotID))) //found old
				{
					++m_DbgLockCounter;
				}
				else if (!lock && Class.CastTo(lock, inv.CreateAttachmentEx("DigitalCodeLock", slotID))) //or spawned new
				{
					++m_DbgLockCounter;
					lock.OnDebugSpawn();
				}
			}
		}
		
		//5. windows
		foreach (string window : windows)
		{
			if (!con.HasConflictPart(door) && con.HasRequiredPart(window)) //later parts need to check requirements too
				con.BuildPartServerEx(null, window, -1);
		}
	}
}
#endif