using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Xml.Serialization; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Networking.Types; using UnityEngine.UI; using static System.Collections.Specialized.BitVector32; using static UnityEditor.Progress; public class EvacuationPanel : MonoBehaviour { public Dictionary distributePeople = new Dictionary();// 分配给各个场景的人数 public List personnelItems;//左侧区域 public Transform personnelContent; public Panel panel; public GameObject personnelPrefabs; public GameObject classPrefab; public GameObject classCount;// public GameObject scenePrefab;//区域预制体 public Transform sceneCount;//区域预制体的容器 public GameObject jueseChoicePanel; public Transform content; public Text topText; private GameObject selectedScene = null;//当前选中场景 public List classItemList = new List(); public List classMateList = new List(); [Header("学生数量")] public InputField StuCountInputField; public Button CountsubmitBtn; public Sprite rsprite; public Sprite fsprite; public GameObject JuesechoicePop; public JueseChoicePop jc = new JueseChoicePop(); public JSONReader js; [Header("总按钮")] public Button redistributeBtn; public Button submitBtn; [Header("Npc数量")] public int npcNum; [Header("Npc类型")] public string npcType; public string roleid; public int isHere; [Header("可分配列表")] List nonZeroAreas = new List(); public SelectScenePanel selectScene; private HashSet clearedAreas = new HashSet(); public List clearRegion=new List();//被清除的区域 // Start is called before the first frame update void Start() { redistributeBtn.interactable = false; //SetNpcType(); //nonZeroAreas= GetNonZeroNpcRatioAreas(); jc = JuesechoicePop.GetComponent(); CountsubmitBtn.onClick.AddListener(Submit); submitBtn.onClick.AddListener(totalSubmit); StuCountInputField.onEndEdit.AddListener(CheckInput); SetScene(); SetClass(); } void Update() { CheckInput(StuCountInputField.text); //IsRedistribution(); IsOpen(selectScene.difficultyId); } //上传数据 public void totalSubmit() { createTemplateInfo.Instance.auth_CreateTemplate.npcList = new List(); foreach(var npcInfo in personnelItems) { Debug.LogError("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); NpcList nPC = new NpcList(); nPC.npcId = npcInfo.npcId.ToString(); nPC.areaId = npcInfo.sceneId.ToString(); nPC.isHere=npcInfo.isHere; nPC.num = npcInfo.NpcNum; createTemplateInfo.Instance.auth_CreateTemplate.npcList.Add(nPC); } panel.panelToggle[3].interactable = true; // 启用第二个Toggle panel.panelToggle[3].gameObject.transform.GetComponent().sprite = panel.toggleImage[1]; panel.panelToggle[4].interactable = true; // 启用第三个Toggle panel.panelToggle[4].gameObject.transform.GetComponent().sprite = panel.toggleImage[1]; } //设置Npc类型 public void SetNpcType() { foreach (var scene in panel.sceneDataDictionary) { foreach (var npcData in js.locationDictionary) { // 解析角色限制字段 string roleLimit = npcData.Value.NpcRatio; if(npcData.Value.NpcRatio=="-1") { continue; } else { // 先按“,”分隔 string[] roleLimitSections = roleLimit.Split(','); if (scene.Key == npcData.Value.Note) { // 只有当 scene.Key 和 npcData.Value.Note 匹配时才执行 this.npcType = roleLimitSections[1]; roleid = roleLimitSections[0]; } } } } } //文字框提交按钮 public void Submit() { // 输入验证 int count; if (!int.TryParse(StuCountInputField.text, out count) || count <= 0) { Debug.LogError("请输入有效的总人数!"); return; } StuCountInputField.text = ""; // 调用分配方法 var result = DistributeNpcByRatio(personnelItems, count); // 更新 UI 和数据 foreach (var kvp in result) { PersonnelItem item = personnelItems.Find(p => p.sceneId == kvp.Key); if (item != null) { item.SetInfo(kvp.Value.ToString()); // 更新UI显示 item.NpcNum = kvp.Value; // 更新Npc数量 item.personnelImage.gameObject.SetActive(true); // 显示图标 Debug.Log($"Scene ID: {kvp.Key}, Assigned NPC Count: {kvp.Value}"); } } } //Npc分配 public Dictionary DistributeNpcByRatio(List personnelItems, int totalNpcCount) { Dictionary sceneRatios = new Dictionary(); // 存储场景ID和比例 float totalRatio = 0; // 所有场景的比例之和 // 遍历所有可以分配的区域,解析NpcRatio,提取分配比例 foreach (var item in personnelItems) { LocationData locationData = js.GetAreaDateById(item.sceneId); string[] allLimits = locationData.NpcRatio.Split('|'); // 多个比例段 foreach (string limit in allLimits) { string[] parts = limit.Split(','); if (parts.Length >= 5) // 确保数据有效 { int sceneId = item.sceneId; // 使用 PersonnelItem 的 sceneId float ratio = float.Parse(parts[4]); // 第五项是分配比例 item.npcId = int.Parse(parts[2]); item .isHere=int.Parse(parts[3]); if (!sceneRatios.ContainsKey(sceneId)) { sceneRatios.Add(sceneId, ratio); totalRatio += ratio; // 累加所有场景的比例 } } } } // 如果没有有效的分配比例,直接返回空结果 if (sceneRatios.Count == 0 || totalRatio == 0) { Debug.LogError("没有找到有效的分配比例!"); return new Dictionary(); } // 根据比例分配人数 Dictionary finalDistribution = new Dictionary(); int remainingNpc = totalNpcCount; foreach (var entry in sceneRatios) { int allocatedNpc = Mathf.FloorToInt(totalNpcCount * (entry.Value / totalRatio)); // 按比例分配 finalDistribution[entry.Key] = allocatedNpc; // 添加到分配结果 remainingNpc -= allocatedNpc; // 更新剩余NPC数量 } // 将剩余人数分配给当前人数最少的场景 while (remainingNpc > 0) { int minScene = finalDistribution.OrderBy(kvp => kvp.Value).First().Key; // 找到当前人数最少的场景 finalDistribution[minScene]++; remainingNpc--; } return finalDistribution; } //设置左侧场景显示2.0 public void SetScene() { foreach (var item in js.locationDictionary) { if(item.Value.NpcRatio=="-1") { continue; } else { string[] npcratio = item.Value.NpcRatio.Split('|'); foreach(var npcLimit in npcratio) { string[] limit = npcLimit.Split(','); if (limit[0] == selectScene.idcidentId.ToString()&& limit[1] == selectScene.difficultyId.ToString()) { GameObject sceneitem = GameObject.Instantiate(personnelPrefabs, personnelContent); PersonnelItem personnelItem = sceneitem.GetComponent(); Button button = personnelItem.transform.Find("sceneText").GetComponent