private void DoExport(string name) { try { try { Scribe.InitWriting(FilePath(name), "ManagerJobs"); } catch (Exception ex) { GenUI.ErrorDialog("ProblemSavingFile".Translate(ex.ToString())); throw; } ScribeMetaHeaderUtility.WriteMetaHeader(); _jobStackIO = Manager.For(manager).JobStack; Scribe_Deep.LookDeep(ref _jobStackIO, "JobStack"); } catch (Exception ex2) { Log.Error("Exception while saving jobstack: " + ex2); } finally { Scribe.FinalizeWriting(); Messages.Message("FM.JobsExported".Translate(_jobStackIO.FullStack().Count), MessageSound.Standard); Refresh(); } }
private Toil Manage(TargetIndex targetIndex) { var station = CurJob.GetTarget(targetIndex).Thing as Building_ManagerStation; if (station == null) { Log.Error("Target of manager job was not a manager station. This should never happen."); return(null); } var comp = station.GetComp <Comp_ManagerStation>(); if (comp == null) { Log.Error("Target of manager job does not have manager station comp. This should never happen."); return(null); } var toil = new Toil(); toil.defaultDuration = (int)(comp.Props.Speed * (1 - pawn.GetStatValue(StatDef.Named("ManagingSpeed")) + .5)); #if DEBUG_WORKGIVER Log.Message("Pawn stat: " + pawn.GetStatValue(StatDef.Named("ManagingSpeed")) + " (+0.5) Station speed: " + comp.Props.Speed + "Total time: " + toil.defaultDuration); #endif toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.tickAction = delegate { toil.actor.skills.GetSkill(DefDatabase <SkillDef> .GetNamed("Managing")).Learn(0.11f); }; var finishers = new List <Action>(); finishers.Add(delegate { Manager.For(pawn.Map).TryDoWork(); }); toil.finishActions = finishers; return(toil); }
public virtual void Delete(bool cleanup = true) { if (cleanup) { CleanUp(); } Manager.For(manager).JobStack.Delete(this, false); }
public override void Tick() { base.Tick(); if (Powered != PowerTrader.PowerOn) { Powered = PowerTrader.PowerOn; } if (Powered) { int tick = Find.TickManager.TicksGame; // turn on glower Glower.SetLit(true); // random blinking on secondary if (tick % 30 == Rand.RangeInclusive(0, 25)) { SecondaryColourIndex = (SecondaryColourIndex + 1) % _colors.Length; } // primary colour if (tick % ManagerStation.Props.Speed == 0) { PrimaryColour = Manager.For(Map).TryDoWork() ? Color.green : Color.red; } // blinking on primary if (tick % 30 < 25) { PrimaryColourBlinker = PrimaryColour; } else { PrimaryColourBlinker = Color.black; } } // apply changes if (_graphicDirty) { // update LED colours Notify_ColorChanged(); _graphicDirty = false; } if (_glowDirty) { // Update glow grid Map.glowGrid.MarkGlowGridDirty(Position); // the following two should not be necesarry, but for some reason do seem to be. Map.mapDrawer.MapMeshDirty(Position, MapMeshFlag.GroundGlow); Map.mapDrawer.MapMeshDirty(Position, MapMeshFlag.Things); _glowDirty = false; } }
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced) { #if DEBUG_WORKGIVER Log.Message("Checking " + t.LabelCap + " for job."); Log.Message("ManagerStation" + (t as Building_ManagerStation != null)); Log.Message("Comp" + (t.TryGetComp <Comp_ManagerStation>() != null)); Log.Message("Incap" + (!pawn.Dead && !pawn.Downed && !pawn.IsBurning() && !t.IsBurning())); Log.Message("CanReserve and reach" + pawn.CanReserveAndReach(t, PathEndMode, Danger.Some)); var powera = t.TryGetComp <CompPowerTrader>(); Log.Message("Power" + (powera == null || powera.PowerOn)); Log.Message("Job" + (Manager.For(pawn.Map).JobStack.NextJob != null)); #endif if (!(t is Building_ManagerStation)) { return(false); } if (t.TryGetComp <Comp_ManagerStation>() == null) { return(false); } if (pawn.Dead || pawn.Downed || pawn.IsBurning() || t.IsBurning()) { return(false); } if (!pawn.CanReserveAndReach(t, PathEndMode, Danger.Some, ignoreOtherReservations: forced)) { return(false); } var power = t.TryGetComp <CompPowerTrader>(); if (power != null && !power.PowerOn) { JobFailReason.Is("Fluffy.ColonyManager.CannotManage.NoPower".Translate()); return(false); } if (!Manager.For(pawn.Map).JobStack.FullStack().Any()) { JobFailReason.Is("Fluffy.ColonyManager.CannotManage.NoJobs".Translate()); return(false); } if (Manager.For(pawn.Map).JobStack.NextJob == null) { JobFailReason.Is("Fluffy.ColonyManager.CannotManage.NoActiveJobs".Translate()); return(false); } return(true); }
public void Refresh() { // upate our list of jobs Jobs = Manager.For(manager).JobStack.FullStack <ManagerJob_Hunting>(); // update pawnkind options foreach (ManagerJob_Hunting job in Jobs) { job.RefreshAllowedAnimals(); } _selected?.RefreshAllowedAnimals(); }
private void DoImport(SaveFileInfo file) { try { // load stuff Scribe.InitLoading(_folder + "/" + file.FileInfo.Name); Manager.LoadSaveMode = Manager.Modes.ImportExport; ScribeMetaHeaderUtility.LoadGameDataHeader(ScribeMetaHeaderUtility.ScribeHeaderMode.Map, false); Scribe.EnterNode("JobStack"); _jobStackIO.ExposeData(); Scribe.ExitNode(); Scribe.FinalizeLoading(); // resolve crossreferences // these are registered during the loading stage, and cleared afterwards // will most definitely give errors/warnings on crossgame imports CrossRefResolver.ResolveAllCrossReferences(); // replace the old jobstack Manager.For(manager).NewJobStack(_jobStackIO); // remove invalid jobs var invalid = 0; foreach (ManagerJob job in Manager.For(manager).JobStack.FullStack()) { if (!job.IsValid) { invalid++; job.Delete(false); } } // provide some feedback on failed import(s) // if debug is enabled the screen will also pop up with reference errors. if (invalid > 0) { Messages.Message("FM.InvalidJobsDeleted".Translate(invalid), MessageSound.SeriousAlert); } } catch (Exception e) { Log.Error("Exception while loading jobstack: " + e); } finally { // done? Scribe.mode = LoadSaveMode.Inactive; Manager.LoadSaveMode = Manager.Modes.Normal; Messages.Message("FM.JobsImported".Translate(_jobStackIO.FullStack().Count), MessageSound.Standard); Refresh(); } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell)); var manage = Manage(TargetIndex.A); yield return(manage); // if made to by player, keep doing that untill we're out of jobs yield return(Toils_Jump.JumpIf( manage, () => GetActor().CurJob.playerForced&& Manager.For(Map).JobStack.NextJob != null)); }
public void Refresh() { _jobs = Manager.For(manager).JobStack.FullStack <ManagerJob_Foraging>(); // update plant options foreach (var job in _jobs) { job.RefreshAllowedPlants(); } // update selected ( also update thingfilter _only_ if the job is not managed yet ) _selected?.RefreshAllowedPlants(!_selected.Managed); }
public void Refresh() { // List of current job counts _jobCounts = (from job in Manager.For(manager).JobStack.FullStack() group job by job.Tab.Label into jobs select new Pair <string, int>(jobs.Key, jobs.Count())).ToList(); // fetch the list of saved jobs _saveFiles = GetSavedFilesList(); // set a valid default name _saveName = DefaultSaveName(); }
public override bool HasJobOnThing(Pawn pawn, Thing t) { #if DEBUG_WORKGIVER Log.Message("Checking " + t.LabelCap + " for job."); Log.Message("ManagerStation" + (t as Building_ManagerStation != null)); Log.Message("Comp" + (t.TryGetComp <Comp_ManagerStation>() != null)); Log.Message("Incap" + (!pawn.Dead && !pawn.Downed && !pawn.IsBurning() && !t.IsBurning())); Log.Message("CanReserve and reach" + pawn.CanReserveAndReach(t, PathEndMode, Danger.Some)); var powera = t.TryGetComp <CompPowerTrader>(); Log.Message("Power" + (powera == null || powera.PowerOn)); Log.Message("Job" + (Manager.For(pawn.Map).JobStack.NextJob != null)); #endif if (!(t is Building_ManagerStation)) { return(false); } if (t.TryGetComp <Comp_ManagerStation>() == null) { return(false); } if (pawn.Dead || pawn.Downed || pawn.IsBurning() || t.IsBurning()) { return(false); } if (!pawn.CanReserveAndReach(t, PathEndMode, Danger.Some)) { return(false); } var power = t.TryGetComp <CompPowerTrader>(); if (power != null && !power.PowerOn) { return(false); } if (Manager.For(pawn.Map).JobStack.NextJob != null) { return(true); } return(false); }
private Toil Manage(TargetIndex targetIndex) { var station = GetActor().jobs.curJob.GetTarget(targetIndex).Thing as Building_ManagerStation; if (station == null) { Log.Error("Target of manager job was not a manager station."); return(null); } var comp = station.GetComp <Comp_ManagerStation>(); if (comp == null) { Log.Error("Target of manager job does not have manager station comp. This should never happen."); return(null); } var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.initAction = () => { workDone = 0; workNeeded = (int) (comp.Props.Speed * (1 - pawn.GetStatValue(StatDef.Named("ManagingSpeed")) + .5)); }; toil.tickAction = () => { // learn a bit pawn.skills.GetSkill(DefDatabase <SkillDef> .GetNamed("Intellectual")) .Learn(0.11f); // update counter workDone++; // are we done yet? if (workDone > workNeeded) { Manager.For(pawn.Map).TryDoWork(); ReadyForNextToil(); } }; toil.WithProgressBar(TargetIndex.A, () => workDone / workNeeded); return(toil); }
public override void PreOpen() { base.PreOpen(); // TODO: reimplement help dialog //if ( !Manager.For( Find.VisibleMap ).HelpShown ) //{ // Find.WindowStack.Add( new Dialog_Message( "FM.HelpMessage".Translate(), "FM.HelpTitle".Translate() ) ); // Manager.For( Find.VisibleMap ).HelpShown = true; //} Manager.For(Find.VisibleMap).RefreshTabs(); Manager.For(Find.VisibleMap).AddPowerTabIfUnlocked(); // don't show tabs for other maps if (CurrentTab.manager.map != Find.VisibleMap) { CurrentTab = DefaultTab; } CurrentTab.PreOpen(); }
private void Refresh() { // currently managed _currentJobs = Manager.For(manager).JobStack.FullStack <ManagerJob_Livestock>(); // concatenate lists of animals on biome and animals in colony. _availablePawnKinds = manager.map.Biome.AllWildAnimals.ToList(); _availablePawnKinds.AddRange( manager.map.mapPawns.AllPawns .Where(p => p.RaceProps.Animal) .Select(p => p.kindDef)); _availablePawnKinds = _availablePawnKinds // get distinct pawnkinds from the merges .Distinct() // remove already managed pawnkinds .Where(pk => !_currentJobs.Select(job => job.Trigger.pawnKind).Contains(pk)) // order by label .OrderBy(def => def.LabelCap) .ToList(); }
public void Refresh() { _jobs = Manager.For(manager).JobStack.FullStack <ManagerJob_Foraging>(); }
public override AlertReport GetReport() { return(Manager.For(Find.CurrentMap).JobStack.FullStack().Count > 0 && !AnyConsciousManagerPawn()); }
public override AlertReport GetReport() { return(Manager.For(Find.CurrentMap).JobStack.FullStack().Count > 0 && !AnyManagerTable()); }
public void DoContent(Rect rect) { // layout: settings | animals // draw background Widgets.DrawMenuSection(rect); // some variables float width = rect.width; float height = rect.height - _topAreaHeight - _button.y - _margin; var cols = 2; float colWidth = width / cols - _margin; var colRects = new List <Rect>(); var colTitleRects = new List <Rect>(); var buttonRect = new Rect(rect.width - _button.x, rect.height - _button.y, _button.x - _margin, _button.y - _margin); // set up rects for (var j = 0; j < cols; j++) { colRects.Add(new Rect(j * colWidth + j * _margin + _margin / 2, _topAreaHeight, colWidth, height)); colTitleRects.Add(new Rect(j * colWidth + j * _margin + _margin / 2, 0f, colWidth, _topAreaHeight)); } // keep track of location Vector2 cur = Vector2.zero; // begin window GUI.BeginGroup(rect); // settings. Utilities.Label(colTitleRects[0], "FMH.Options".Translate(), anchor: TextAnchor.LowerLeft, lrMargin: _margin * 2, font: GameFont.Tiny); GUI.DrawTexture(colRects[0], Resources.SlightlyDarkBackground); GUI.BeginGroup(colRects[0]); // target count (1) int currentCount = _selected.Trigger.CurCount; int corpseCount = _selected.GetMeatInCorpses(); int designatedCount = _selected.GetMeatInDesignations(); int targetCount = _selected.Trigger.Count; _selected.Trigger.DrawTriggerConfig(ref cur, colWidth, _entryHeight, true, "FMH.TargetCount".Translate(currentCount, corpseCount, designatedCount, targetCount), "FMH.TargetCountTooltip".Translate(currentCount, corpseCount, designatedCount, targetCount)); // allow human meat (2) var humanMeatRect = new Rect(cur.x, cur.y, colWidth, _entryHeight); Utilities.DrawToggle(humanMeatRect, "FMH.AllowHumanMeat".Translate(), _selected.Trigger.ThresholdFilter.Allows(Utilities_Hunting.HumanMeat), delegate { _selected.AllowHumanLikeMeat(true); }, delegate { _selected.AllowHumanLikeMeat(false); }); cur.y += _entryHeight; // unforbid corpses (3) var ufCorpseRect = new Rect(cur.x, cur.y, colWidth, _entryHeight); Widgets.DrawAltRect(ufCorpseRect); Utilities.DrawToggle(ufCorpseRect, "FMH.UnforbidCorpses".Translate(), ref _selected.UnforbidCorpses); cur.y += _entryHeight; // hunting grounds (4) var huntingGroundsTitleRect = new Rect(cur.x, cur.y, colWidth - 2 * _margin, _entryHeight); Utilities.Label(huntingGroundsTitleRect, "FMH.HuntingGrounds".Translate(), anchor: TextAnchor.MiddleLeft, lrMargin: _margin); cur.y += _entryHeight; var huntingGroundsRect = new Rect(cur.x + _margin, cur.y, colWidth - 2 * _margin, _entryHeight); AreaAllowedGUI.DoAllowedAreaSelectors(huntingGroundsRect, ref _selected.HuntingGrounds, manager, AllowedAreaMode.Humanlike); cur.y += _entryHeight; GUI.EndGroup(); // animals. Utilities.Label(colTitleRects[1], "FMH.Animals".Translate(), anchor: TextAnchor.LowerLeft, lrMargin: _margin * 2, font: GameFont.Tiny); GUI.DrawTexture(colRects[1], Resources.SlightlyDarkBackground); GUI.BeginGroup(colRects[1]); cur = Vector2.zero; Rect outRect = colRects[1].AtZero().ContractedBy(1f); var viewRect = new Rect(0f, 0f, outRect.width, _selected.AllowedAnimals.Count * _entryHeight); if (viewRect.height > outRect.height) { viewRect.width -= 16f; } // start scrolling view Widgets.BeginScrollView(outRect, ref _animalsScrollPosition, viewRect); // list of keys in allowed animals list (all animals in biome, static) var PawnKinds = new List <PawnKindDef>(_selected.AllowedAnimals.Keys); // toggle all var toggleAllRect = new Rect(cur.x, cur.y, colWidth, _entryHeight); Widgets.DrawAltRect(toggleAllRect); Dictionary <PawnKindDef, bool> .ValueCollection test = _selected.AllowedAnimals.Values; Utilities.DrawToggle(toggleAllRect, "<i>" + "FM.All".Translate() + "</i>", _selected.AllowedAnimals.Values.All(v => v), delegate { foreach ( PawnKindDef def in PawnKinds) { _selected.AllowedAnimals[ def ] = true; } }, delegate { foreach ( PawnKindDef def in PawnKinds) { _selected .AllowedAnimals[ def ] = false; } }); cur.y += _entryHeight; // toggle for each animal var i = 1; foreach (PawnKindDef kind in PawnKinds) { var toggleRect = new Rect(cur.x, cur.y, colWidth, _entryHeight); // highlight alternate rows if (i++ % 2 == 0) { Widgets.DrawAltRect(toggleRect); } // draw the toggle Utilities.DrawToggle(toggleRect, kind.LabelCap, _selected.AllowedAnimals[kind], delegate { _selected.AllowedAnimals[kind] = !_selected.AllowedAnimals[kind]; }); // update current position cur.y += _entryHeight; } // close scrolling view Widgets.EndScrollView(); // close animal list GUI.EndGroup(); // do the button if (!_selected.Managed) { if (Widgets.ButtonText(buttonRect, "FM.Manage".Translate())) { // activate job, add it to the stack _selected.Managed = true; Manager.For(manager).JobStack.Add(_selected); // refresh source list Refresh(); } } else { if (Widgets.ButtonText(buttonRect, "FM.Delete".Translate())) { // inactivate job, remove from the stack. Manager.For(manager).JobStack.Delete(_selected); // remove content from UI _selected = null; // refresh source list Refresh(); } } // close window GUI.EndGroup(); }
public override void DoWindowContents(Rect canvas) { // zooming in seems to cause Text.Font to start at Tiny, make sure it's set to Small for our panels. Text.Font = GameFont.Small; // three areas of icons for tabs, left middle and right. var leftIcons = new Rect(0f, 0f, _margin + Manager.For(Find.VisibleMap).ManagerTabsLeft.Count *(_iconSize + _margin), _iconSize); var middleIcons = new Rect(0f, 0f, _margin + Manager.For(Find.VisibleMap).ManagerTabsMiddle.Count *(_iconSize + _margin), _iconSize); var rightIcons = new Rect(0f, 0f, _margin + Manager.For(Find.VisibleMap).ManagerTabsRight.Count *(_iconSize + _margin), _iconSize); // finetune rects middleIcons = middleIcons.CenteredOnXIn(canvas); rightIcons.x += canvas.width - rightIcons.width; // left icons (probably only overview, but hey...) GUI.BeginGroup(leftIcons); var cur = new Vector2(_margin, 0f); foreach (ManagerTab tab in Manager.For(Find.VisibleMap).ManagerTabsLeft) { var iconRect = new Rect(cur.x, cur.y, _iconSize, _iconSize); DrawTabIcon(iconRect, tab); cur.x += _iconSize + _margin; } GUI.EndGroup(); // middle icons (the bulk of icons) GUI.BeginGroup(middleIcons); cur = new Vector2(_margin, 0f); foreach (ManagerTab tab in Manager.For(Find.VisibleMap).ManagerTabsMiddle) { var iconRect = new Rect(cur.x, cur.y, _iconSize, _iconSize); DrawTabIcon(iconRect, tab); cur.x += _iconSize + _margin; } GUI.EndGroup(); // right icons (probably only import/export, possbile settings?) GUI.BeginGroup(rightIcons); cur = new Vector2(_margin, 0f); foreach (ManagerTab tab in Manager.For(Find.VisibleMap).ManagerTabsRight) { var iconRect = new Rect(cur.x, cur.y, _iconSize, _iconSize); DrawTabIcon(iconRect, tab); cur.x += _iconSize + _margin; } GUI.EndGroup(); // delegate actual content to the specific manager. var contentCanvas = new Rect(0f, _iconSize + _margin, canvas.width, canvas.height - _iconSize - _margin); GUI.BeginGroup(contentCanvas); CurrentTab.DoWindowContents(contentCanvas); GUI.EndGroup(); }
public void Refresh() { Jobs = Manager.For(manager).JobStack.FullStack <ManagerJob_Hunting>(); }
public void DrawOverview(Rect rect) { if (Jobs.NullOrEmpty()) { Text.Anchor = TextAnchor.MiddleCenter; GUI.color = Color.grey; Widgets.Label(rect, "FM.NoJobs".Translate()); Text.Anchor = TextAnchor.UpperLeft; GUI.color = Color.white; } else { Rect viewRect = rect; Rect contentRect = viewRect.AtZero(); contentRect.height = OverviewHeight; if (OverviewHeight > viewRect.height) { contentRect.width -= 16f; } GUI.BeginGroup(viewRect); Widgets.BeginScrollView(viewRect, ref _overviewScrollPosition, contentRect); Vector2 cur = Vector2.zero; for (var i = 0; i < Jobs.Count; i++) { var row = new Rect(cur.x, cur.y, contentRect.width, 50f); // highlights if (i % 2 == 1) { Widgets.DrawAltRect(row); } if (Jobs[i] == Selected) { Widgets.DrawHighlightSelected(row); } // go to job icon var iconRect = new Rect(Margin, row.yMin + (RowHeight - IconSize) / 2, IconSize, IconSize); if (Widgets.ButtonImage(iconRect, Jobs[i].Tab.Icon)) { MainTabWindow_Manager.GoTo(Jobs[i].Tab, Jobs[i]); } // order buttons DrawOrderButtons(new Rect(row.xMax - 50f, row.yMin, 50f, 50f), Manager.For(manager), Jobs[i]); // job specific overview. Rect jobRect = row; jobRect.width -= RowHeight + IconSize + 2 * Margin; // - (a + b)? jobRect.x += IconSize + 2 * Margin; Jobs[i].DrawListEntry(jobRect, true, true); Widgets.DrawHighlightIfMouseover(row); if (Widgets.ButtonInvisible(jobRect)) { Selected = Jobs[i]; } cur.y += 50f; } GUI.EndScrollView(); GUI.EndGroup(); OverviewHeight = cur.y; } }
private void DoContent(Rect rect) { // cop out if nothing is selected. if (_selectedCurrent == null) { return; } // background Widgets.DrawMenuSection(rect); // begin window GUI.BeginGroup(rect); rect = rect.AtZero(); // rects var optionsColumnRect = new Rect(Utilities.Margin / 2, _topAreaHeight, rect.width / 2 - Utilities.Margin, rect.height - _topAreaHeight - Utilities.Margin - Utilities.ButtonSize.y); var animalsRect = new Rect(optionsColumnRect.xMax + Utilities.Margin, _topAreaHeight, rect.width / 2 - Utilities.Margin, rect.height - _topAreaHeight - Utilities.Margin - Utilities.ButtonSize.y); var optionsColumnTitle = new Rect(optionsColumnRect.xMin, 0f, optionsColumnRect.width, _topAreaHeight); var animalsColumnTitle = new Rect(animalsRect.xMin, 0f, animalsRect.width, _topAreaHeight); // backgrounds GUI.DrawTexture(optionsColumnRect, Resources.SlightlyDarkBackground); GUI.DrawTexture(animalsRect, Resources.SlightlyDarkBackground); // titles Utilities.Label(optionsColumnTitle, "FMP.Options".Translate(), anchor: TextAnchor.LowerLeft, lrMargin: Utilities.Margin * 2, font: GameFont.Tiny); Utilities.Label(animalsColumnTitle, "FML.Animals".Translate(), anchor: TextAnchor.LowerLeft, lrMargin: Utilities.Margin * 2, font: GameFont.Tiny); // options GUI.BeginGroup(optionsColumnRect); Vector2 cur = Vector2.zero; var optionIndex = 1; // counts header Utilities.Label(ref cur, optionsColumnRect.width, _entryHeight, "FML.TargetCounts".Translate(), alt: optionIndex % 2 == 0); // counts table var cols = 3; float fifth = optionsColumnRect.width / 5; float[] widths = { fifth, fifth * 2, fifth * 2 }; float[] heights = { _entryHeight / 3 * 2, _entryHeight, _entryHeight }; // set up a 3x3 table of rects var countRects = new Rect[cols, cols]; for (var x = 0; x < cols; x++) { for (var y = 0; y < cols; y++) { // kindof overkill for a 3x3 table, but ok. countRects[x, y] = new Rect(widths.Take(x).Sum(), cur.y + heights.Take(y).Sum(), widths[x], heights[y]); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(countRects[x, y]); } } } optionIndex++; // headers Utilities.Label(countRects[1, 0], Gender.Female.ToString(), null, TextAnchor.LowerCenter, font: GameFont.Tiny); Utilities.Label(countRects[2, 0], Gender.Male.ToString(), null, TextAnchor.LowerCenter, font: GameFont.Tiny); Utilities.Label(countRects[0, 1], "FML.Adult".Translate(), null, TextAnchor.MiddleRight, font: GameFont.Tiny); Utilities.Label(countRects[0, 2], "FML.Juvenile".Translate(), null, TextAnchor.MiddleRight, font: GameFont.Tiny); // fields DoCountField(countRects[1, 1], Utilities_Livestock.AgeAndSex.AdultFemale); DoCountField(countRects[2, 1], Utilities_Livestock.AgeAndSex.AdultMale); DoCountField(countRects[1, 2], Utilities_Livestock.AgeAndSex.JuvenileFemale); DoCountField(countRects[2, 2], Utilities_Livestock.AgeAndSex.JuvenileMale); cur.y += 3 * _entryHeight; // restrict to area var restrictAreaRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(restrictAreaRect); } Utilities.DrawToggle(restrictAreaRect, "FML.RestrictToArea".Translate(), ref _selectedCurrent.RestrictToArea); cur.y += _entryHeight; if (_selectedCurrent.RestrictToArea) { // area selectors table // set up a 3x3 table of rects var areaRects = new Rect[cols, cols]; for (var x = 0; x < cols; x++) { for (var y = 0; y < cols; y++) { // kindof overkill for a 3x3 table, but ok. areaRects[x, y] = new Rect(widths.Take(x).Sum(), cur.y + heights.Take(y).Sum(), widths[x], heights[y]); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(areaRects[x, y]); } } } // headers Utilities.Label(areaRects[1, 0], Gender.Female.ToString(), null, TextAnchor.LowerCenter, font: GameFont.Tiny); Utilities.Label(areaRects[2, 0], Gender.Male.ToString(), null, TextAnchor.LowerCenter, font: GameFont.Tiny); Utilities.Label(areaRects[0, 1], "FML.Adult".Translate(), null, TextAnchor.MiddleRight, font: GameFont.Tiny); Utilities.Label(areaRects[0, 2], "FML.Juvenile".Translate(), null, TextAnchor.MiddleRight, font: GameFont.Tiny); // do the selectors _selectedCurrent.RestrictArea[0] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[1, 1], _selectedCurrent.RestrictArea[ 0 ], manager, AllowedAreaMode.Animal, Utilities.Margin); _selectedCurrent.RestrictArea[1] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[2, 1], _selectedCurrent.RestrictArea[ 1 ], manager, AllowedAreaMode.Animal, Utilities.Margin); _selectedCurrent.RestrictArea[2] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[1, 2], _selectedCurrent.RestrictArea[ 2 ], manager, AllowedAreaMode.Animal, Utilities.Margin); _selectedCurrent.RestrictArea[3] = AreaAllowedGUI.DoAllowedAreaSelectors(areaRects[2, 2], _selectedCurrent.RestrictArea[ 3 ], manager, AllowedAreaMode.Animal, Utilities.Margin); cur.y += 3 * _entryHeight; } optionIndex++; // train Utilities.Label(ref cur, optionsColumnRect.width, _entryHeight, "FML.Training".Translate(), alt: optionIndex % 2 == 0); var trainingRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex++ % 2 == 0) { Widgets.DrawAltRect(trainingRect); } _selectedCurrent.DrawTrainingSelector(trainingRect, Utilities.Margin); cur.y += _entryHeight; if (_selectedCurrent.Training.Any) { var trainYoungRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex++ % 2 == 0) { Widgets.DrawAltRect(trainYoungRect); } Utilities.DrawToggle(trainYoungRect, "FML.TrainYoung".Translate(), ref _selectedCurrent.Training.TrainYoung); cur.y += _entryHeight; } // butchery stuff var butcherExcessRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex++ % 2 == 0) { Widgets.DrawAltRect(butcherExcessRect); } Utilities.DrawToggle(butcherExcessRect, "FML.ButcherExcess".Translate(), ref _selectedCurrent.ButcherExcess); cur.y += _entryHeight; var butcherTrainedRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex++ % 2 == 0) { Widgets.DrawAltRect(butcherTrainedRect); } Utilities.DrawToggle(butcherTrainedRect, "FML.ButcherTrained".Translate(), ref _selectedCurrent.ButcherTrained); cur.y += _entryHeight; // try tame more? var tameMoreRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); cur.y += _entryHeight; Utilities.DrawToggle(tameMoreRect, "FML.TameMore".Translate(), ref _selectedCurrent.TryTameMore); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(tameMoreRect); } // area to train from (if taming more); if (_selectedCurrent.TryTameMore) { var tameAreaRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(tameAreaRect); } cur.y += _entryHeight; var tameAreaSelectorRect = new Rect(cur.x, cur.y, optionsColumnRect.width, _entryHeight); if (optionIndex % 2 == 0) { Widgets.DrawAltRect(tameAreaSelectorRect); } cur.y += _entryHeight; Utilities.Label(tameAreaRect, "FML.TameArea".Translate()); AreaAllowedGUI.DoAllowedAreaSelectors(tameAreaSelectorRect, ref _selectedCurrent.TameArea, manager, AllowedAreaMode.Any, Utilities.Margin); // why am I getting an error for not being at upperleft? Oh well, force it. Text.Anchor = TextAnchor.UpperLeft; } optionIndex++; GUI.EndGroup(); // options // Start animals list // get our pawnkind PawnKindDef pawnKind = _onCurrentTab ? _selectedCurrent.Trigger.pawnKind : _selectedAvailable; if (pawnKind != null) { Rect viewRect = animalsRect; viewRect.height = _actualHeight; if (_actualHeight > animalsRect.height) { viewRect.width -= 16f; } Widgets.BeginScrollView(animalsRect, ref _animalsScrollPosition, viewRect); GUI.BeginGroup(viewRect); cur = Vector2.zero; // tamed animals DrawAnimalListheader(ref cur, new Vector2(viewRect.width, _entryHeight / 3 * 2), pawnKind, "FML.Tame".Translate().CapitalizeFirst()); List <Pawn> tame = pawnKind.GetTame(manager); if (tame.Count == 0) { Utilities.Label(ref cur, viewRect.width, _entryHeight, "FML.NoAnimals".Translate("FML.Tame".Translate()), anchor: TextAnchor.MiddleCenter, color: Color.grey); } for (var i = 0; i < tame.Count; i++) { DrawAnimalRow(ref cur, new Vector2(viewRect.width, _entryHeight), tame[i], i % 2 == 0); } cur.y += _entryHeight; // wild animals DrawAnimalListheader(ref cur, new Vector2(viewRect.width, _entryHeight / 3 * 2), pawnKind, "FML.Wild".Translate().CapitalizeFirst()); List <Pawn> wild = pawnKind.GetWild(manager); if (wild.Count == 0) { Utilities.Label(ref cur, viewRect.width, _entryHeight, "FML.NoAnimals".Translate("FML.Wild".Translate()), null, TextAnchor.MiddleCenter, color: Color.grey); } for (var i = 0; i < wild.Count; i++) { DrawAnimalRow(ref cur, new Vector2(animalsRect.width, _entryHeight), wild[i], i % 2 == 0); } // update list height _actualHeight = cur.y; GUI.EndGroup(); // animals Widgets.EndScrollView(); } // bottom button var buttonRect = new Rect(rect.xMax - Utilities.ButtonSize.x, rect.yMax - Utilities.ButtonSize.y, Utilities.ButtonSize.x - Utilities.Margin, Utilities.ButtonSize.y - Utilities.Margin); // add / remove to the stack if (_selectedCurrent.Managed) { if (Widgets.ButtonText(buttonRect, "FM.Delete".Translate())) { _selectedCurrent.Delete(); _selectedCurrent = null; _onCurrentTab = false; Refresh(); return; // just skip to the next tick to avoid null reference errors. } TooltipHandler.TipRegion(buttonRect, "FMP.DeleteBillTooltip".Translate()); } else { if (Widgets.ButtonText(buttonRect, "FM.Manage".Translate())) { _selectedCurrent.Managed = true; _onCurrentTab = true; Manager.For(manager).JobStack.Add(_selectedCurrent); Refresh(); } TooltipHandler.TipRegion(buttonRect, "FMP.ManageBillTooltip".Translate()); } GUI.EndGroup(); // window }
/// <summary> /// Sorting of bills /// </summary> public void GlobalWork() { #if DEBUG_JOBS var watch = Stopwatch.StartNew(); debug = new StringBuilder(); debug.AppendLine("Manager :: Starting global priority check"); #endif // get a list of all assigned bills, their worktables, and the priority of the job they belong to. var all = new List <BillTablePriority>(); foreach (ManagerJob_Production job in Manager.For(manager).JobStack.FullStack <ManagerJob_Production>()) { var dump = false; job.CleanBillgivers(ref dump); all.AddRange( job.BillGivers.AssignedBillGiversAndBillsDictionary.Select( pair => new BillTablePriority( pair.Key, pair.Value, job.Priority))); } // no assigned bills, nothing to do. if (all.Count == 0) { return; } #if DEBUG_JOBS debug.AppendLine("All currently managed bills:"); foreach (BillTablePriority entry in all) { debug.AppendLine(" - " + entry.ToString()); } #endif // loop through distinct worktables that have more than one bill foreach ( Building_WorkTable table in all.Select(v => v.table).Distinct().Where(table => table.BillStack.Count > 1)) { // get all bills (assigned by us) for this table, pre-ordered. List <Bill> managerBills = all.Where(v => v.table == table).OrderBy(v => v.priority).Select(v => v.bill as Bill).ToList(); // get all actual bills on the table (private field) object rawBillsOnTable; if ( !Utilities.TryGetPrivateField(table.billStack.GetType(), table.billStack, "bills", out rawBillsOnTable)) { Log.Warning("Failed to get real billstack for " + table); continue; } // give it it's type back. var billsOnTable = rawBillsOnTable as List <Bill>; if (billsOnTable == null) { Log.Warning("Failed to convert real billstack for " + table); continue; } #if DEBUG_JOBS debug.AppendLine(); debug.AppendLine("Bills for table " + table.GetUniqueLoadID() + " (managed):"); foreach (Bill bill in managerBills) { debug.AppendLine(" - " + bill.GetUniqueLoadID()); } debug.AppendLine("Bills for table " + table.GetUniqueLoadID() + " (on table):"); foreach (Bill bill in billsOnTable) { debug.AppendLine(" - " + bill.GetUniqueLoadID()); } #endif // get the set difference of the two lists - these are external/manual bills List <Bill> manualBills = billsOnTable.Except(managerBills).ToList(); // create a new list of bills, by pasting the two lists together in the right order var result = new List <Bill>(); if (prioritizeManual) { result.AddRange(manualBills); result.AddRange(managerBills); } else { result.AddRange(managerBills); result.AddRange(manualBills); } // feed it back to the table. if (!Utilities.TrySetPrivateField(table.billStack.GetType(), table.billStack, "bills", result)) { Log.Warning("Failed to set billstack for " + table); } #if DEBUG_JOBS // fetch the list again to see what happened. // get all actual bills on the table (private field) if (!Utilities.TryGetPrivateField(table.billStack.GetType(), table.billStack, "bills", out rawBillsOnTable)) { Log.Warning("Failed to get real billstack for " + table); continue; } // give it it's type back. billsOnTable = rawBillsOnTable as List <Bill>; if (billsOnTable == null) { Log.Warning("Failed to convert real billstack for " + table); continue; } debug.AppendLine("Bills for table " + table.GetUniqueLoadID() + " (after priority sort):"); foreach (Bill bill in billsOnTable) { debug.AppendLine(" - " + bill.GetUniqueLoadID()); } #endif } #if DEBUG_JOBS watch.Stop(); debug.AppendLine("Execution time: " + watch.ElapsedMilliseconds + "ms"); Log.Message(debug.ToString()); #endif }
private void DoContent(Rect rect) { // background Widgets.DrawMenuSection(rect); // cop out if nothing is selected. if (_selectedCurrent == null) { Label(rect, "FM.Livestock.SelectPawnKind".Translate(), TextAnchor.MiddleCenter); return; } // rects var optionsColumnRect = new Rect( rect.xMin, rect.yMin, rect.width * 3 / 5f, rect.height - Margin - ButtonSize.y); var animalsColumnRect = new Rect( optionsColumnRect.xMax, rect.yMin, rect.width * 2 / 5f, rect.height - Margin - ButtonSize.y); var buttonRect = new Rect( rect.xMax - ButtonSize.x, rect.yMax - ButtonSize.y, ButtonSize.x - Margin, ButtonSize.y - Margin); Vector2 position; float width; Widgets_Section.BeginSectionColumn(optionsColumnRect, "Livestock.Options", out position, out width); Widgets_Section.Section(ref position, width, DrawTargetCountsSection, "FM.Livestock.TargetCountsHeader".Translate()); Widgets_Section.Section(ref position, width, DrawTamingSection, "FM.Livestock.TamingHeader".Translate()); Widgets_Section.Section(ref position, width, DrawButcherSection, "FM.Livestock.ButcherHeader".Translate()); Widgets_Section.Section(ref position, width, DrawTrainingSection, "FM.Livestock.TrainingHeader".Translate()); Widgets_Section.Section(ref position, width, DrawAreaRestrictionsSection, "FM.Livestock.AreaRestrictionsHeader".Translate()); Widgets_Section.Section(ref position, width, DrawFollowSection, "FM.Livestock.FollowHeader".Translate()); Widgets_Section.EndSectionColumn("Livestock.Options", position); // Start animals list // get our pawnkind Widgets_Section.BeginSectionColumn(animalsColumnRect, "Livestock.Animals", out position, out width); Widgets_Section.Section(ref position, width, DrawTamedAnimalSection, "FM.Livestock.AnimalsHeader".Translate("FML.Tame".Translate(), _selectedCurrent.Trigger.pawnKind.GetLabelPlural()).CapitalizeFirst()); Widgets_Section.Section(ref position, width, DrawWildAnimalSection, "FM.Livestock.AnimalsHeader".Translate("FML.Wild".Translate(), _selectedCurrent.Trigger.pawnKind.GetLabelPlural()).CapitalizeFirst()); Widgets_Section.EndSectionColumn("Livestock.Animals", position); // add / remove to the stack if (_selectedCurrent.Managed) { if (Widgets.ButtonText(buttonRect, "FM.Delete".Translate())) { _selectedCurrent.Delete(); _selectedCurrent = null; _onCurrentTab = false; Refresh(); return; // just skip to the next tick to avoid null reference errors. } TooltipHandler.TipRegion(buttonRect, "FMP.DeleteBillTooltip".Translate()); } else { if (Widgets.ButtonText(buttonRect, "FM.Manage".Translate())) { _selectedCurrent.Managed = true; _onCurrentTab = true; Manager.For(manager).JobStack.Add(_selectedCurrent); Refresh(); } TooltipHandler.TipRegion(buttonRect, "FMP.ManageBillTooltip".Translate()); } }
public void DoContent(Rect rect) { // layout: settings | animals // draw background Widgets.DrawMenuSection(rect); // rects var optionsColumnRect = new Rect( rect.xMin, rect.yMin, rect.width * 3 / 5f, rect.height - Margin - ButtonSize.y); var animalsColumnRect = new Rect( optionsColumnRect.xMax, rect.yMin, rect.width * 2 / 5f, rect.height - Margin - ButtonSize.y); var buttonRect = new Rect( rect.xMax - ButtonSize.x, rect.yMax - ButtonSize.y, ButtonSize.x - Margin, ButtonSize.y - Margin); Vector2 position; float width; // options Widgets_Section.BeginSectionColumn(optionsColumnRect, "Hunting.Options", out position, out width); Widgets_Section.Section(ref position, width, DrawThresholdSettings, "FM.Threshold".Translate()); Widgets_Section.Section(ref position, width, DrawUnforbidCorpses); Widgets_Section.Section(ref position, width, DrawHuntingGrounds, "FM.Hunting.AreaRestriction".Translate()); Widgets_Section.EndSectionColumn("Hunting.Options", position); // animals Widgets_Section.BeginSectionColumn(animalsColumnRect, "Hunting.Animals", out position, out width); var refreshRect = new Rect( position.x + width - SmallIconSize - 2 * Margin, position.y + Margin, SmallIconSize, SmallIconSize); if (Widgets.ButtonImage(refreshRect, Resources.Refresh, Color.grey)) { _selected.RefreshAllowedAnimals(); } Widgets_Section.Section(ref position, width, DrawAnimalShortcuts, "FMH.Animals".Translate()); Widgets_Section.Section(ref position, width, DrawAnimalList); Widgets_Section.EndSectionColumn("Hunting.Animals", position); // do the button if (!_selected.Managed) { if (Widgets.ButtonText(buttonRect, "FM.Manage".Translate())) { // activate job, add it to the stack _selected.Managed = true; Manager.For(manager).JobStack.Add(_selected); // refresh source list Refresh(); } } else { if (Widgets.ButtonText(buttonRect, "FM.Delete".Translate())) { // inactivate job, remove from the stack. Manager.For(manager).JobStack.Delete(_selected); // remove content from UI _selected = null; // refresh source list Refresh(); } } }
/// <summary> /// Returns true if the recipe has prerequisite ingredients, and those ingredients can currently be crafted. /// </summary> /// <param name="recipe"></param> /// <returns></returns> public static bool HasPrerequisiteChoices(Map map, RecipeDef recipe) { return (recipe.ingredients.Select(ing => new IngredientSelector(Manager.For(map), ing, 1, recipe)) .Any(ins => IngredientSelector.HasRecipeChoices(map, ins))); }