public void init() { Thing targetItem = job.targetA.Thing; _posting = HaulExplicitly.GetManager(targetItem.MapHeld).postings[posting_id]; _record = _posting.RecordWithItem(targetItem); }
public static void RegisterPosting(HaulExplicitlyPosting posting) { HaulExplicitlyJobManager manager = GetManager(posting.map); foreach (Thing i in posting.items) { { ThingWithComps twc = i as ThingWithComps; if (twc != null && twc.GetComp <CompForbiddable>() != null) { i.SetForbidden(false); } } if (i.IsAHaulableSetToHaulable()) { i.ToggleHaulDesignation(); } foreach (var p2 in manager.postings.Values) { p2.TryRemoveItem(i); } } if (manager.postings.Keys.Contains(posting.id)) { throw new ArgumentException("Posting ID " + posting.id + " already exists in this manager."); } manager.postings[posting.id] = posting; }
public static void DrawForItem(Thing item) { var mgr = HaulExplicitly.GetManager(item.Map); HaulExplicitlyPosting posting = mgr.PostingWithItem(item); if (posting == null) { return; } //draw line Vector3 start = item.Position.ToVector3ShiftedWithAltitude(alt); Vector3 circle_center = posting.center; circle_center.y = alt; Vector3 line_vector = circle_center - start; if (line_vector.magnitude > posting.visualization_radius) { line_vector = line_vector.normalized * (line_vector.magnitude - posting.visualization_radius); GenDraw.DrawLineBetween(start, start + line_vector); } if (postings_drawn_this_frame.Contains(posting.id)) { return; } postings_drawn_this_frame.Add(posting.id); //draw circle GenDraw.DrawCircleOutline(circle_center, posting.visualization_radius); }
public override void ProcessInput(Event ev) { base.ProcessInput(ev); HaulExplicitlyPosting posting = HaulExplicitly.GetManager(Find.CurrentMap).PostingWithItem(thing); if (posting != null) { posting.TryRemoveItem(thing, true); foreach (Pawn p in Find.CurrentMap.mapPawns.PawnsInFaction(Faction.OfPlayer)) { var jobs = new List <Job>(p.jobs.jobQueue.AsEnumerable().Select(j => j.job)); if (p.CurJob != null) { jobs.Add(p.CurJob); } foreach (var job in jobs) { if (job.def.driverClass == typeof(JobDriver_HaulExplicitly) && job.targetA.Thing == thing) { p.jobs.EndCurrentOrQueuedJob(job, JobCondition.Incompletable); } } } } }
public override void DesignateSingleCell(IntVec3 c) { HaulExplicitlyPosting posting = Designator_HaulExplicitly.prospective_job; posting.TryMakeDestinations(UI.MouseMapPosition(), false); HaulExplicitly.RegisterPosting(posting); ResetJob(); }
public static int AmountPawnWantsToPickUp(Pawn p, Thing t, HaulExplicitlyPosting posting) { return(Mathf.Min(new int[] { posting.RecordWithItem(t).RemainingToHaul(), p.carryTracker.AvailableStackSpace(t.def), t.stackCount })); }
public override AcceptanceReport CanDesignateCell(IntVec3 c) { HaulExplicitlyPosting posting = Designator_HaulExplicitly.prospective_job; if (posting == null) { return(false); } return(posting.TryMakeDestinations(UI.MouseMapPosition())); }
public HaulExplicitlyInventoryRecord(Thing initial, HaulExplicitlyPosting parentPosting) { _parentPosting = new System.WeakReference(parentPosting); items.Add(initial); itemDef = initial.def; itemStuff = initial.Stuff; miniDef = (initial as MinifiedThing)?.InnerThing.def; selectedQuantity = initial.stackCount; ResetMerge(); }
public static DeliverableDestinations For( Thing item, Pawn carrier, HaulExplicitlyPosting posting = null, Func <IntVec3, float> grader = null) { if (posting == null) //do the handholdy version of this function { posting = HaulExplicitly.GetManager(item.Map).PostingWithItem(item); if (posting == null) { throw new ArgumentException(); } } return(new DeliverableDestinations(item, carrier, posting, (grader != null) ? grader : DefaultGrader)); }
public override void ProcessInput(Event ev) { base.ProcessInput(ev); Selector selector = Find.Selector; List <object> selection = selector.SelectedObjects; Thing example = (Thing)selection.First(); HaulExplicitlyPosting posting = HaulExplicitly.GetManager(example.Map).PostingWithItem(example); foreach (object o in posting.items) { Thing t = o as Thing; if (!selection.Contains(o) && t != null && t.Spawned) { selector.Select(o); } } }
public static bool RelevantToThing(Thing t) { var mgr = HaulExplicitly.GetManager(t.Map); HaulExplicitlyPosting posting = mgr.PostingWithItem(t); if (posting == null) { return(false); } foreach (object o in Find.Selector.SelectedObjects) { Thing other = o as Thing; if (other == null || !posting.items.Contains(other)) { return(false); } } return(Find.Selector.SelectedObjects.Count < posting.items.Count(i => i.Spawned)); }
public override void SelectedUpdate() { HaulExplicitlyPosting posting = Designator_HaulExplicitly.prospective_job; if (posting == null) { return; } if (posting.TryMakeDestinations(UI.MouseMapPosition()) && posting.destinations != null) { float alt = AltitudeLayer.MetaOverlays.AltitudeFor(); foreach (IntVec3 d in posting.destinations) { Vector3 drawPos = d.ToVector3ShiftedWithAltitude(alt); Graphics.DrawMesh(MeshPool.plane10, drawPos, Quaternion.identity, DesignatorUtility.DragHighlightThingMat, 0); } } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnBurningImmobile(TargetIndex.B); //this.FailOnForbidden(TargetIndex.A); Toil gotoThing = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch); gotoThing.FailOnSomeonePhysicallyInteracting(TargetIndex.A); gotoThing.FailOn(delegate(Toil toil) { Job job = toil.actor.CurJob; Thing thing = job.GetTarget(TargetIndex.A).Thing; IntVec3 cell = job.GetTarget(TargetIndex.B).Cell; List <Thing> items_in_cell = HaulExplicitlyPosting.GetItemsIfValidItemSpot( toil.actor.Map, cell); if (items_in_cell == null) { return(true); } if (items_in_cell.Count == 0) { return(false); } if (items_in_cell.Count == 1 && thing.CanStackWith(items_in_cell.First())) { return(false); } return(true); }); yield return(gotoThing); yield return(Toils_HaulExplicitly.PickUpThing(TargetIndex.A, gotoThing)); Toil carryToDest = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToDest); yield return(Toils_HaulExplicitly.PlaceHauledThingAtDest(TargetIndex.B, carryToDest)); }
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) { if (!CanGetThing(pawn, t, forced)) { return(null); } //plan count and dests HaulExplicitlyPosting posting = HaulExplicitly.GetManager(t.Map).PostingWithItem(t); if (posting == null) { return(null); } int space_request = AmountPawnWantsToPickUp(pawn, t, posting); var destInfo = DeliverableDestinations.For(t, pawn, posting); List <IntVec3> dests = destInfo.RequestSpaceForItemAmount(space_request); int dest_space_available = destInfo.FreeSpaceInCells(dests); var count = Math.Min(space_request, dest_space_available); if (count < 1) { return(null); } //make job JobDef JobDefOfHaulExplicitly = (JobDef)(GenDefDatabase.GetDef(typeof(JobDef), "HaulExplicitlyHaul")); Job job = new Job(JobDefOfHaulExplicitly, t, dests.First()); //((JobDriver_HaulExplicitly)job.GetCachedDriver(pawn)).init(); job.count = count; job.targetQueueA = new List <LocalTargetInfo>( new LocalTargetInfo[] { new IntVec3(posting.id, dest_space_available, 0) }); job.targetQueueB = new List <LocalTargetInfo>(dests.Skip(1).Take(dests.Count - 1) .Select(c => new LocalTargetInfo(c))); job.haulOpportunisticDuplicates = true; return(job); }
public static void UpdateJob() { List <object> objects = Find.Selector.SelectedObjects; Designator_HaulExplicitly.prospective_job = new HaulExplicitlyPosting(objects); }
public static void ResetJob() { Designator_HaulExplicitly.prospective_job = null; }
public override void DoExtraGuiControls(float leftX, float bottomY) { HaulExplicitlyPosting posting = Designator_HaulExplicitly.prospective_job; var records = new List <HaulExplicitlyInventoryRecord>( posting.inventory.OrderBy(r => r.Label)); const float max_height = 450f; const float width = 268f; const float row_height = 28f; float height = Math.Min(gui_last_drawn_height + 20f, max_height); Rect winRect = new Rect(leftX, bottomY - height, width, height); Rect outerRect = new Rect(0f, 0f, width, height).ContractedBy(10f); Rect innerRect = new Rect(0f, 0f, outerRect.width - 16f, Math.Max(gui_last_drawn_height, outerRect.height)); Find.WindowStack.ImmediateWindow(622372, winRect, WindowLayer.GameUI, delegate { Widgets.BeginScrollView(outerRect, ref scrollPosition, innerRect, true); GUI.BeginGroup(innerRect); GUI.color = ITab_Pawn_Gear.ThingLabelColor; GameFont prev_font = Text.Font; Text.Font = GameFont.Small; float y = 0f; Widgets.ListSeparator(ref y, innerRect.width, "Items to haul"); foreach (var rec in records) { Rect rowRect = new Rect(0f, y, innerRect.width - 24f, 28f); if (rec.selectedQuantity > 1) { Rect buttonRect = new Rect(rowRect.x + rowRect.width, rowRect.y + (rowRect.height - 24f) / 2, 24f, 24f); if (Widgets.ButtonImage(buttonRect, RimWorld.Planet.CaravanThingsTabUtility.AbandonSpecificCountButtonTex)) { string txt = "HaulExplicitly.ItemHaulSetQuantity".Translate(new NamedArgument((rec.itemDef.label).CapitalizeFirst(), "ITEMTYPE")); var dialog = new Dialog_Slider(txt, 1, rec.selectedQuantity, delegate(int x) { rec.setQuantity = x; }, rec.setQuantity); dialog.layer = WindowLayer.GameUI; Find.WindowStack.Add(dialog); } } if (Mouse.IsOver(rowRect)) { GUI.color = ITab_Pawn_Gear.HighlightColor; GUI.DrawTexture(rowRect, TexUI.HighlightTex); } if (rec.itemDef.DrawMatSingle?.mainTexture != null) { Rect iconRect = new Rect(4f, y, 28f, 28f); if (rec.miniDef != null || rec.selectedQuantity == 1) { Widgets.ThingIcon(iconRect, rec.items[0]); } else { Widgets.ThingIcon(iconRect, rec.itemDef); } } Text.Anchor = TextAnchor.MiddleLeft; Text.WordWrap = false; Rect textRect = new Rect(36f, y, rowRect.width - 36f, rowRect.height); string str = rec.Label; Widgets.Label(textRect, str.Truncate(textRect.width)); y += row_height; } gui_last_drawn_height = y; Text.Font = prev_font; Text.Anchor = TextAnchor.UpperLeft; Text.WordWrap = true; GUI.EndGroup(); Widgets.EndScrollView(); }, true, false, 1f); }
private DeliverableDestinations(Thing item, Pawn carrier, HaulExplicitlyPosting posting, Func <IntVec3, float> grader) { this.grader = grader; this.posting = posting; record = posting.RecordWithItem(item); Map map = posting.map; thing = item; IntVec3 item_pos = (!item.SpawnedOrAnyParentSpawned) ? carrier.PositionHeld : item.PositionHeld; var traverseparms = TraverseParms.For(carrier, Danger.Deadly, TraverseMode.ByPawn, false); foreach (IntVec3 cell in posting.destinations) { List <Thing> items_in_cell = HaulExplicitlyPosting.GetItemsIfValidItemSpot(map, cell); bool valid_destination = items_in_cell != null; //see if this cell already has, or will have, an item of our item's stack type // (tests items in the cell, as well as reservations on the cell) bool cell_is_same_stack_type = false; if (valid_destination) { foreach (Thing i in items_in_cell) { if (record.CanMixWith(i)) { cell_is_same_stack_type = true; } } } Pawn claimant = map.reservationManager.FirstRespectedReserver(cell, carrier); if (claimant != null) { List <Job> jobs = new List <Job>(claimant.jobs.jobQueue.Select(x => x.job)); jobs.Add(claimant.jobs.curJob); foreach (Job job in jobs) { if (job.def.driverClass == typeof(JobDriver_HaulExplicitly) && (job.targetB == cell || job.targetQueueB.Contains(cell)) && (record.CanMixWith(job.targetA.Thing))) { cell_is_same_stack_type = true; break; } } } //finally, increment our counter of cells with our item's stack type if (cell_is_same_stack_type) { dests_with_this_stack_type++; } //check if cell is valid, reachable from item, unreserved, and pawn is allowed to go there bool reachable = map.reachability.CanReach(item_pos, cell, PathEndMode.ClosestTouch, traverseparms); if (!valid_destination || !reachable || claimant != null || cell.IsForbidden(carrier)) { continue; } // oh, just item things if (items_in_cell.Count == 0) { free_cells.Add(cell); } try { Thing item_in_cell = items_in_cell.Single(); int space_avail = item_in_cell.def.stackLimit - item_in_cell.stackCount; if (cell_is_same_stack_type && space_avail > 0) { partial_cells.Add(cell); partialCellSpaceAvailable.Add(space_avail); } } catch { } } }