Beispiel #1
0
        /// <summary>
        /// 计算指定地区的综合工作指数
        ///
        /// 综合工作指数 = SUM(缩放平移过的建筑工作效率 * 建筑优先级)
        /// 厢房效率不计入统计
        ///
        /// 由于必须在最开始执行,所以无法使用 prepared data
        /// </summary>
        /// <param name="partId"></param>
        /// <param name="placeId"></param>
        /// <returns></returns>
        private static float GetCompositeWorkIndex(int partId, int placeId)
        {
            float compositeWorkIndex = 0.0f;

            // 统计所有建筑的工作效率(厢房效率不计入统计)
            var buildings = DateFile.instance.homeBuildingsDate[partId][placeId];

            foreach (int buildingIndex in buildings.Keys)
            {
                if (!Original.BuildingNeedsWorker(partId, placeId, buildingIndex))
                {
                    continue;
                }

                if (Bedroom.IsBedroom(partId, placeId, buildingIndex))
                {
                    continue;
                }

                if (DateFile.instance.actorsWorkingDate.ContainsKey(partId) &&
                    DateFile.instance.actorsWorkingDate[partId].ContainsKey(placeId) &&
                    DateFile.instance.actorsWorkingDate[partId][placeId].ContainsKey(buildingIndex))
                {
                    int   workerId                = DateFile.instance.actorsWorkingDate[partId][placeId][buildingIndex];
                    int   workEffectiveness       = Original.GetWorkEffectiveness(partId, placeId, buildingIndex, workerId);
                    float scaledWorkEffectiveness = (workEffectiveness - 100f) / 100f;
                    int   priority                = HumanResource.GetBuildingWorkingPriority(partId, placeId, buildingIndex);

                    compositeWorkIndex += scaledWorkEffectiveness * priority;
                }
            }

            return(compositeWorkIndex);
        }
Beispiel #2
0
        public static void LogBuildingAndWorker(BuildingWorkInfo info, int selectedWorkerId,
                                                int partId, int placeId, TaiwuDate currDate, Dictionary <int, Dictionary <int, int> > workerAttrs,
                                                bool suppressNoWorkerWarnning)
        {
            var building       = DateFile.instance.homeBuildingsDate[partId][placeId][info.buildingIndex];
            int baseBuildingId = building[0];
            int buildingLevel  = building[1];

            var    baseBuilding = DateFile.instance.basehomePlaceDate[baseBuildingId];
            string buildingName = baseBuilding[0];

            string attrName = Output.GetRequiredAttrName(info.requiredAttrId);

            string logText = string.Format("{0}:{1} ({2}) {3} [{4}, {5}] - ",
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(info.priority.ToString("F0").PadLeft(4))),
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_YELLOW, Common.ToFullWidth(buildingName.PadRight(5))),
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(buildingLevel.ToString().PadLeft(2))),
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_RICE_WHITE, Common.ToFullWidth(attrName.PadRight(2))),
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(info.halfWorkingAttrValue.ToString().PadLeft(3))),
                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(info.fullWorkingAttrValue.ToString().PadLeft(3))));

            if (selectedWorkerId >= 0)
            {
                string workerName = DateFile.instance.GetActorName(selectedWorkerId);
                int    attrValue  = info.requiredAttrId != 0 ? workerAttrs[selectedWorkerId][info.requiredAttrId] : -1;
                int    mood       = int.Parse(DateFile.instance.GetActorDate(selectedWorkerId, 4, false));
                int    favor      = DateFile.instance.GetActorFavor(false, DateFile.instance.MianActorID(), selectedWorkerId, getLevel: true);

                // 这里的工作效率并不一定等于最终工作效率,因为可能还有厢房未分配
                int workEffectiveness = info.requiredAttrId != 0 ?
                                        Original.GetWorkEffectiveness(partId, placeId, info.buildingIndex, selectedWorkerId) : -1;
                string workEffectivenessStr = workEffectiveness >= 0 ? workEffectiveness / 2 + "%" : "N/A";

                MajordomoWindow.instance.AppendMessage(currDate, Message.IMPORTANCE_LOW, logText + string.Format(
                                                           "{0} 资质: {1} 心情: {2} 好感: {3} 工作效率: {4}",
                                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_YELLOW, Common.ToFullWidth(workerName.PadRight(5))),
                                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(attrValue.ToString().PadLeft(3))),
                                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(mood.ToString().PadLeft(4))),
                                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, Common.ToFullWidth(favor.ToString().PadLeft(2))),
                                                           TaiwuCommon.SetColor(TaiwuCommon.COLOR_WHITE, Common.ToFullWidth(workEffectivenessStr.PadLeft(4)))));
            }
            else
            {
                if (suppressNoWorkerWarnning)
                {
                    MajordomoWindow.instance.AppendMessage(currDate, Message.IMPORTANCE_LOW,
                                                           logText + TaiwuCommon.SetColor(TaiwuCommon.COLOR_LIGHT_GRAY, "无合适人选"));
                }
                else
                {
                    MajordomoWindow.instance.AppendMessage(currDate, Message.IMPORTANCE_HIGH,
                                                           logText + TaiwuCommon.SetColor(TaiwuCommon.COLOR_RED, "无合适人选"));
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// 为指定建筑选择合适的工作人员
        /// 按资质顺序检查实际效率是否达到及格线(或心情好感未达到标准),若达到则选择
        /// 若没有任何人达到及格线(或心情好感皆达到标准),或者没有任何工作人员,则返回 -1
        /// </summary>
        /// <param name="buildingIndex"></param>
        /// <param name="requiredAttrId"></param>
        /// <returns></returns>
        private int SelectBuildingWorker(int buildingIndex, int requiredAttrId)
        {
            int selectedWorkerId = -1;

            List <int> candidates = this.attrCandidates[requiredAttrId];

            candidates = candidates.Where(workerId => !this.excludedWorkers.Contains(workerId)).ToList();
            if (!candidates.Any())
            {
                return(-1);
            }

            if (requiredAttrId != 0)
            {
                foreach (int workerId in candidates)
                {
                    int effect = Original.GetWorkEffectiveness(this.partId, this.placeId, buildingIndex, workerId);
                    if (effect >= WORK_EFFECTIVENESS_HALF)
                    {
                        selectedWorkerId = workerId;
                        break;
                    }
                }
            }
            else
            {
                foreach (int workerId in candidates)
                {
                    int lackedMoodAndFavor = this.workerAttrs[workerId][requiredAttrId];
                    if (lackedMoodAndFavor > 0)
                    {
                        selectedWorkerId = workerId;
                        break;
                    }
                }
            }

            if (selectedWorkerId >= 0)
            {
                this.excludedBuildings.Add(buildingIndex);
                this.excludedWorkers.Add(selectedWorkerId);
            }

            return(selectedWorkerId);
        }
Beispiel #4
0
        /// <summary>
        /// 计算指定地区的工作统计信息
        ///
        /// 综合工作指数 = SUM(缩放平移过的建筑工作效率 * 建筑优先级)
        /// 厢房效率不计入统计
        ///
        /// 由于必须在最开始执行,所以无法使用 prepared data
        /// </summary>
        /// <param name="partId"></param>
        /// <param name="placeId"></param>
        /// <returns></returns>
        private static WorkingStats GetWorkingStats(int partId, int placeId)
        {
            var stats = new WorkingStats();

            // 统计所有建筑的工作效率(厢房效率不计入统计)
            var buildings = DateFile.instance.homeBuildingsDate[partId][placeId];

            foreach (int buildingIndex in buildings.Keys)
            {
                if (!Original.BuildingNeedsWorker(partId, placeId, buildingIndex))
                {
                    continue;
                }

                if (Bedroom.IsBedroom(partId, placeId, buildingIndex))
                {
                    continue;
                }

                if (DateFile.instance.actorsWorkingDate.ContainsKey(partId) &&
                    DateFile.instance.actorsWorkingDate[partId].ContainsKey(placeId) &&
                    DateFile.instance.actorsWorkingDate[partId][placeId].ContainsKey(buildingIndex))
                {
                    int   workerId                = DateFile.instance.actorsWorkingDate[partId][placeId][buildingIndex];
                    int   workEffectiveness       = Original.GetWorkEffectiveness(partId, placeId, buildingIndex, workerId);
                    float scaledWorkEffectiveness = (workEffectiveness - 100f) / 100f;
                    float priority                = HumanResource.GetBuildingWorkingPriority(partId, placeId, buildingIndex, withAdjacentBedrooms: false);

                    ++stats.nProductiveBuildings;
                    stats.avgWorkEffectiveness += workEffectiveness / 200f;
                    stats.compositeWorkIndex   += scaledWorkEffectiveness * priority;
                }
            }

            if (stats.nProductiveBuildings > 0)
            {
                stats.avgWorkEffectiveness /= stats.nProductiveBuildings;
            }
            return(stats);
        }
Beispiel #5
0
        public static void LogBuildingAndWorker(BuildingWorkInfo info, int selectedWorkerId,
                                                int partId, int placeId, Dictionary <int, Dictionary <int, int> > workerAttrs)
        {
            var building       = DateFile.instance.homeBuildingsDate[partId][placeId][info.buildingIndex];
            int baseBuildingId = building[0];
            int buildingLevel  = building[1];

            var    baseBuilding = DateFile.instance.basehomePlaceDate[baseBuildingId];
            string buildingName = baseBuilding[0];

            string attrName = Output.GetRequiredAttrName(info.requiredAttrId);

            string logText = $"{info.priority}\t" +
                             $"{buildingName} ({buildingLevel}): " +
                             $"{attrName} [{info.halfWorkingAttrValue}, {info.fullWorkingAttrValue}] - ";

            if (selectedWorkerId >= 0)
            {
                string workerName = DateFile.instance.GetActorName(selectedWorkerId);
                int    attrValue  = info.requiredAttrId != 0 ? workerAttrs[selectedWorkerId][info.requiredAttrId] : -1;
                int    mood       = int.Parse(DateFile.instance.GetActorDate(selectedWorkerId, 4, addValue: false));
                int    favor      = DateFile.instance.GetActorFavor(false, DateFile.instance.MianActorID(), selectedWorkerId, getLevel: true);

                // 这里的工作效率并不一定等于最终工作效率,因为可能还有厢房未分配
                int workEffectiveness = info.requiredAttrId != 0 ?
                                        Original.GetWorkEffectiveness(partId, placeId, info.buildingIndex, selectedWorkerId) : -1;
                string workEffectivenessStr = workEffectiveness >= 0 ? workEffectiveness / 2 + "%" : "N/A";

                Main.Logger.Log(logText +
                                $"{workerName}, 资质: {attrValue}, 心情: {mood}, 好感: {favor}, 工作效率: {workEffectivenessStr}");
            }
            else
            {
                Main.Logger.Log(logText + "<无合适人选>");
            }
        }