This commit is contained in:
2025-12-14 21:04:22 +01:00
parent c4eb7e944d
commit 3a7b81bfd7
112 changed files with 12 additions and 16665 deletions

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.Dragon
{
public class SpawnBabyDragonPacket : Packet
{
public override ushort packetId => (int)Enums.Packets.SpawnBabyDragon;
public Vector3 start { get; set; }
public override void HandlePacketClient()
{
DragonSpawn.inst.SpawnBabyDragon(start);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.Dragon
{
public class SpawnMamaDragonPacket : Packet
{
public override ushort packetId => (int)Enums.Packets.SpawnMamaDragon;
public Vector3 start { get; set; }
public override void HandlePacketClient()
{
DragonSpawn.inst.SpawnMamaDragon(start);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.Dragon
{
public class SpawnSiegeDragonPacket : Packet
{
public override ushort packetId => (int)Enums.Packets.SpawnSiegeDragon;
public Vector3 start { get; set; }
public override void HandlePacketClient()
{
DragonSpawn.inst.SpawnSiegeDragon(start);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameBuilding
{
public class CompleteBuild : Packet
{
public override ushort packetId => (int)Enums.Packets.CompleteBuild;
public Guid buildingId { get; set; }
public override void HandlePacketClient()
{
if (KCClient.client.Id == clientId) return;
Player.inst.GetBuilding(buildingId).CompleteBuild();
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameBuilding
{
public class UpdateConstruction : Packet
{
public override ushort packetId => (int)Enums.Packets.UpdateConstruction;
public Guid buildingId { get; set; }
public float constructionProgress { get; set; }
public override void HandlePacketClient()
{
if (KCClient.client.Id == clientId) return;
//Main.helper.Log($"Received packet from: {clientId} receiving client is {KCClient.client.Id}");
Player.inst.GetBuilding(buildingId).constructionProgress = constructionProgress;
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.GamePlayer
{
public class AddVillagerPacket : Packet
{
public override ushort packetId => (ushort)Enums.Packets.AddVillager;
public Guid guid { get; set; }
public Vector3 position { get; set; }
public override void HandlePacketClient()
{
try
{
if (KCClient.client.Id == clientId) return;
// Check for duplicate villager by guid
var existingVillager = player.inst.Workers.data.FirstOrDefault(w => w != null && w.guid == guid);
if (existingVillager != null)
{
Main.helper.Log($"Villager with guid {guid} already exists, skipping duplicate");
return;
}
Main.helper.Log("Received add villager packet from " + player.name + $"({player.id})");
Villager newVillager = Villager.CreateVillager();
newVillager.guid = guid;
// Set villager position
if (position != Vector3.zero)
{
newVillager.TeleportTo(position);
}
player.inst.Workers.Add(newVillager);
player.inst.Homeless.Add(newVillager);
}
catch (Exception e)
{
Main.helper.Log("Error handling add villager packet: " + e.Message);
Main.helper.Log(e.StackTrace);
}
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GamePlayer
{
public class SetupInitialWorkersPacket : Packet
{
public override ushort packetId => (ushort)Enums.Packets.SetupInitialWorkers;
public Guid keepGuid { get; set; }
public override void HandlePacketClient()
{
if (KCClient.client.Id == clientId) return;
/*Keep keep = player.inst.GetBuilding(keepGuid).GetComponent<Keep>();
if (keep == null)
{
Main.helper.Log("Keep not found.");
return;
}
player.inst.SetupInitialWorkers(keep);*/
}
public override void HandlePacketServer()
{
}
}
}

View File

@@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameTrees
{
public class FellTree : Packet
{
public override ushort packetId => (int)Enums.Packets.FellTree;
public int idx { get; set; }
public int x { get; set; }
public int z { get; set; }
public override void HandlePacketClient()
{
Cell cell = World.inst.GetCellData(x, z);
TreeSystem.inst.FellTree(cell, idx);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameTrees
{
public class GrowTree : Packet
{
public override ushort packetId => (int)Enums.Packets.GrowTree;
public int X { get; set; }
public int Z { get; set; }
public override void HandlePacketClient()
{
Cell cell = World.inst.GetCellData(X, Z);
TreeSystem.inst.GrowTree(cell);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameTrees
{
public class ShakeTree : Packet
{
public override ushort packetId => (int)Enums.Packets.ShakeTree;
public int idx { get; set; }
public override void HandlePacketClient()
{
TreeSystem.inst.ShakeTree(idx);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.GameVillager
{
public class VillagerTeleportTo : Packet
{
public override ushort packetId => (ushort)Enums.Packets.VillagerTeleportTo;
public Guid guid { get; set; }
public Vector3 pos { get; set; }
public override void HandlePacketClient()
{
if (KCClient.client.Id == clientId) return;
try
{
Villager.villagers.data.Where(x => x.guid == guid).FirstOrDefault().TeleportTo(pos);
Main.helper.Log($"Teleporting villager to {pos.ToString()}");
}
catch (Exception e)
{
Main.helper.Log("Error handling villager teleport packet: " + e.Message);
}
}
public override void HandlePacketServer()
{
}
}
}

View File

@@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game.GameWeather
{
public class ChangeWeather : Packet
{
public override ushort packetId => (int)Enums.Packets.ChangeWeather;
public int weatherType { get; set; }
public override void HandlePacketClient()
{
Weather.CurrentWeather = ((Weather.WeatherType)weatherType);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}

View File

@@ -1,204 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace KCM.Packets.Game.GameWorld
{
public class WorldPlace : Packet
{
public override ushort packetId => (int)Enums.Packets.WorldPlace;
public string customName { get; set; }
public Guid guid { get; set; }
public string uniqueName { get; set; }
public Quaternion rotation { get; set; }
public Vector3 globalPosition { get; set; }
public Vector3 localPosition { get; set; }
public bool built { get; set; }
public bool placed { get; set; }
public bool open { get; set; }
public bool doBuildAnimation { get; set; }
public bool constructionPaused { get; set; }
public float constructionProgress { get; set; }
public float life { get; set; }
public float ModifiedMaxLife { get; set; }
public int yearBuilt { get; set; }
public float decayProtection { get; set; }
public bool seenByPlayer { get; set; }
public override void HandlePacketClient()
{
if (clientId == KCClient.client.Id) return; //prevent double placing on same client
PlaceBuilding();
}
public override void HandlePacketServer()
{
//PlaceBuilding();
//SendToAll(clientId);
}
public void PlaceBuilding()
{
Main.LogSync("========== BUILDING PLACEMENT START ==========");
Main.LogSync($"Building: {uniqueName} from player: {player?.name} (id={player?.id})");
Main.LogSync($" guid={guid}");
Main.LogSync($" globalPosition={globalPosition}");
Main.LogSync($" localPosition={localPosition}");
Main.LogSync($" rotation={rotation} (euler={rotation.eulerAngles})");
Main.LogSync($" built={built}, placed={placed}, open={open}");
Main.LogSync($" constructionProgress={constructionProgress}, constructionPaused={constructionPaused}");
Main.LogSync($" life={life}, ModifiedMaxLife={ModifiedMaxLife}");
Main.LogSync($" yearBuilt={yearBuilt}, decayProtection={decayProtection}");
// Check for duplicate building by guid to prevent double placement from network retries
var existingBuilding = player.inst.Buildings.data.FirstOrDefault(b => b != null && b.guid == guid);
if (existingBuilding != null)
{
Main.helper.Log($"Building with guid {guid} already exists for player {player.name}, skipping duplicate placement");
return;
}
//var originalPlayer = Player.inst;
//Player.inst = player.inst;
Building.BuildingSaveData structureData = new Building.BuildingSaveData()
{
uniqueName = uniqueName,
customName = customName,
guid = guid,
rotation = rotation,
globalPosition = globalPosition,
localPosition = localPosition,
built = built,
placed = placed,
open = open,
doBuildAnimation = doBuildAnimation,
constructionPaused = constructionPaused,
constructionProgress = constructionProgress,
life = life,
ModifiedMaxLife = ModifiedMaxLife,
//CollectForBuild = CollectForBuild,
yearBuilt = yearBuilt,
decayProtection = decayProtection,
seenByPlayer = seenByPlayer
};
//Player originalInst = Player.inst;
//Player.inst = player.inst;
Building Building = GameState.inst.GetPlaceableByUniqueName(structureData.uniqueName);
bool flag = Building;
if (flag)
{
Building building = UnityEngine.Object.Instantiate<Building>(Building);
building.transform.position = structureData.globalPosition;
Main.helper.Log("Building init");
building.Init();
building.transform.SetParent(player.inst.buildingContainer.transform, true);
Main.helper.Log("Building unpack");
structureData.Unpack(building);
Main.helper.Log(player.inst.ToString());
Main.helper.Log((player.inst.PlayerLandmassOwner == null).ToString());
Main.helper.Log(building.LandMass().ToString());
Main.helper.Log("Player add Building unpacked");
player.inst.AddBuilding(building);
Main.ApplyPendingBuildingState(building);
try
{
player.inst.PlayerLandmassOwner.TakeOwnership(building.LandMass());
bool flag2 = building.GetComponent<Keep>() != null && building.TeamID() == player.inst.PlayerLandmassOwner.teamId;
Main.helper.Log("Set keep " + flag2);
if (flag2)
{
player.inst.keep = building.GetComponent<Keep>();
}
}
catch (Exception e)
{
Main.helper.Log(e.Message);
}
Main.helper.Log("Place from load");
Cell cell = World.inst.PlaceFromLoad(building);
Main.helper.Log("unpack stage 2");
structureData.UnpackStage2(building);
// Update materials/textures for correct display
building.UpdateMaterialSelection();
// Update road rotation for proper visuals
Road roadComp = building.GetComponent<Road>();
if (roadComp != null)
{
roadComp.UpdateRotation();
}
// Update aqueduct rotation
Aqueduct aqueductComp = building.GetComponent<Aqueduct>();
if (aqueductComp != null)
{
aqueductComp.UpdateRotation();
}
building.SetVisibleForFog(false);
Main.helper.Log("Landmass owner take ownership");
Main.helper.Log($"{player.id} (team {player.inst.PlayerLandmassOwner.teamId}) banner: {player.inst.PlayerLandmassOwner.bannerIdx} Placed building {building.name} at {building.transform.position}");
//Player.inst = originalInst; // Reset player back to normal // Might not be needed anymore with player ref patches?
Main.helper.Log($"Host player Landmass Names Count: {Player.inst.LandMassNames.Count}, Contents: {string.Join(", ", Player.inst.LandMassNames)}");
Main.helper.Log($"Client player ({player.name}) Landmass Names Count: {player.inst.LandMassNames.Count}, Contents: {string.Join(", ", player.inst.LandMassNames)}");
// Ensure LandMassNames arrays are large enough to prevent IndexOutOfRangeException
int landMass = building.LandMass();
// Expand player.inst.LandMassNames if needed
while (player.inst.LandMassNames.Count <= landMass)
{
player.inst.LandMassNames.Add("");
}
// Expand Player.inst.LandMassNames if needed
while (Player.inst.LandMassNames.Count <= landMass)
{
Player.inst.LandMassNames.Add("");
}
player.inst.LandMassNames[landMass] = player.kingdomName;
Player.inst.LandMassNames[landMass] = player.kingdomName;
// Log final building state after placement
Main.LogSync("---------- BUILDING PLACED FINAL STATE ----------");
Main.LogSync($" Final position: {building.transform.position}");
if (building.transform.childCount > 0)
{
Main.LogSync($" Child[0] rotation: {building.transform.GetChild(0).rotation} (euler={building.transform.GetChild(0).rotation.eulerAngles})");
Main.LogSync($" Child[0] localPosition: {building.transform.GetChild(0).localPosition}");
}
Main.LogSync($" IsBuilt={building.IsBuilt()}, IsPlaced={building.IsPlaced()}");
Main.LogSync($" TeamID={building.TeamID()}, LandMass={building.LandMass()}");
Main.LogSync("========== BUILDING PLACEMENT END ==========");
}
else
{
Main.LogSync($"FAILED to place building: {structureData.uniqueName} - GetPlaceableByUniqueName returned null");
}
}
}
}

View File

@@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Analytics;
namespace KCM.Packets.Game
{
public class PlaceKeepRandomly : Packet
{
public override ushort packetId => (ushort)Enums.Packets.PlaceKeepRandomly;
public int landmassIdx { get; set; }
public override void HandlePacketClient()
{
try
{
Building keep = UnityEngine.Object.Instantiate<Building>(GameState.inst.GetPlaceableByUniqueName(World.keepName));
keep.Init();
Cell[] cells = World.inst.GetCellsData().Where(x => x.landMassIdx == landmassIdx).ToArray();
Cell keepCell = null;
foreach (Cell cell in cells)
{
Cell nearbyStoneCell = FindNearbyStoneCell(cells, cell.x, cell.z, landmassIdx, 15); // Place keep within 15 tiles of stone
Cell nearbyWaterCell = FindNearbyWaterCell(cells, cell.x, cell.z, landmassIdx, 6); // Do not place keep within 6 tiles of water
Cell clearCell = FindClearCell(cells, cell.x, cell.z, landmassIdx, 4); // cells in 4 by 4 radius are clear?
if (clearCell != null & nearbyStoneCell != null && nearbyWaterCell == null && cell.Type == ResourceType.None)
{
Console.WriteLine($"Nearby stone cell found at ({nearbyStoneCell.x}, {nearbyStoneCell.z})");
keepCell = cell;
break;
}
else
continue;
}
keep.transform.position = keepCell.Position;
keep.SendMessage("OnPlayerPlacement", SendMessageOptions.DontRequireReceiver);
Player.inst.PlayerLandmassOwner.TakeOwnership(keep.LandMass());
Player.inst.keep = keep.GetComponent<Keep>();
Player.inst.RefreshVisibility(true);
RandomPlacement(keep);
} catch (Exception e)
{
Main.helper.Log($"Error placing keep randomly: {e.Message}");
}
}
private void RandomPlacement(Building keep) // This is a hack so I can detect when its being called by this packet
{
World.inst.Place(keep);
Cam.inst.SetTrackingPos(keep.GetPosition());
}
private static Cell FindNearbyStoneCell(Cell[] cells, int x, int z, int landmassIdx, int radius)
{
return cells.FirstOrDefault(cell => IsResourceInRadius(cell, x, z, radius, ResourceType.Stone));
}
private static Cell FindNearbyWaterCell(Cell[] cells, int x, int z, int landmassIdx, int radius)
{
return cells.FirstOrDefault(cell => IsResourceInRadius(cell, x, z, radius, ResourceType.Water));
}
private static Cell FindClearCell(Cell[] cells, int x, int z, int landmassIdx, int radius)
{
return cells.FirstOrDefault(cell => IsResourceInRadius(cell, x, z, radius, ResourceType.None));
}
private static bool IsResourceInRadius(Cell cell, int x, int z, int radius, ResourceType desiredResource)
{
bool isWithinRadius = Math.Sqrt((cell.x - x) * (cell.x - x) + (cell.z - z) * (cell.z - z)) <= radius;
bool isNotCentralCell = cell.x != x || cell.z != z;
bool isStoneType = cell.Type == desiredResource;
bool isWater = desiredResource == ResourceType.Water ? false : cell.deepWater || cell.Type == ResourceType.Water;
return isWithinRadius && isNotCentralCell && isStoneType && !isWater;
}
public override void HandlePacketServer()
{
}
}
}

View File

@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KCM.Packets.Game
{
public class SetSpeed : Packet
{
public override ushort packetId => (int)Enums.Packets.SetSpeed;
public int speed { get; set; }
public override void HandlePacketClient()
{
if (clientId == KCClient.client.Id) // Prevent speed softlock
return;
SpeedControlUI.inst.SetSpeed(speed);
}
public override void HandlePacketServer()
{
//throw new NotImplementedException();
}
}
}