protected override void OnSpawn() { base.OnSpawn(); oxygenOutputCell = building.GetUtilityOutputCell(); int cell = Grid.PosToCell(transform.GetPosition()); CellOffset rotatedOffset = building.GetRotatedOffset(portInfo.offset); hydrogenOutputCell = Grid.OffsetCell(cell, rotatedOffset); IUtilityNetworkMgr networkManager = Conduit.GetNetworkManager(portInfo.conduitType); hydrogenOutputItem = new FlowUtilityNetwork.NetworkItem(portInfo.conduitType, Endpoint.Source, hydrogenOutputCell, gameObject); networkManager.AddToNetworks(hydrogenOutputCell, hydrogenOutputItem, true); WaterAccumulator = Game.Instance.accumulators.Add("ElementsConsumed", this); OxygenAccumulator = Game.Instance.accumulators.Add("OutputElements", this); HydrogenAccumulator = Game.Instance.accumulators.Add("OutputElements", this); KBatchedAnimController batchedAnimController = GetComponent <KBatchedAnimController>(); if (hasMeter) { meter = new MeterController(batchedAnimController, "U2H_meter_target", "meter", Meter.Offset.Behind, Grid.SceneLayer.NoLayer, new Vector3(-0.4f, 0.5f, -0.1f), "U2H_meter_target", "U2H_meter_tank", "U2H_meter_waterbody", "U2H_meter_level"); } smi.StartSM(); UpdateMeter(); Tutorial.Instance.oxygenGenerators.Add(gameObject); }
private void RefreshReachableCells() { ListPool <int, LogicDuplicantSensor> .PooledList pooledList = ListPool <int, LogicDuplicantSensor> .Allocate(reachableCells); reachableCells.Clear(); Grid.CellToXY(this.NaturalBuildingCell(), out int x, out int y); int num = x - pickupRange / 2; for (int i = y; i < y + pickupRange + 1; i++) { for (int j = num; j < num + pickupRange + 1; j++) { int num2 = Grid.XYToCell(j, i); CellOffset offset = new CellOffset(j - x, i - y); if ((bool)rotatable) { offset = rotatable.GetRotatedCellOffset(offset); if (Grid.IsCellOffsetValid(this.NaturalBuildingCell(), offset)) { num2 = Grid.OffsetCell(this.NaturalBuildingCell(), offset); Vector2I vector2I = Grid.CellToXY(num2); if (Grid.IsValidCell(num2) && Grid.IsPhysicallyAccessible(x, y, vector2I.x, vector2I.y, true)) { reachableCells.Add(num2); } } } else if (Grid.IsValidCell(num2) && Grid.IsPhysicallyAccessible(x, y, j, i, true)) { reachableCells.Add(num2); } } } pooledList.Recycle(); }
/// <summary> /// Creates an inert output port that does not automatically handle Conduit Update behavior. The building must define its own behavior for the output port. /// </summary> /// <param name="conduitType">The type of conduit this port should attach to.</param> /// <param name="offset">The offset (left-right, down-up) of where this port is located. Offsets begin bottom-left.</param> /// <returns></returns> public OutputPort AddOutputPortInert(ConduitType conduitType, CellOffset offset) { OutputPort port = AddOutputPort(conduitType, offset); port.UseConduitUpdater = false; return(port); }
public bool TestAreaAbove(int rootCell, object data, Func <int, object, bool> testDelegate) { if (AboveOccupiedCellOffsets == null) { List <CellOffset> list = new List <CellOffset>(); for (int i = 0; i < OccupiedCellsOffsets.Length; i++) { CellOffset cellOffset = new CellOffset(OccupiedCellsOffsets[i].x, OccupiedCellsOffsets[i].y + 1); if (Array.IndexOf(OccupiedCellsOffsets, cellOffset) == -1) { list.Add(cellOffset); } } AboveOccupiedCellOffsets = list.ToArray(); } for (int j = 0; j < AboveOccupiedCellOffsets.Length; j++) { int arg = Grid.OffsetCell(rootCell, AboveOccupiedCellOffsets[j]); if (!testDelegate(arg, data)) { return(false); } } return(true); }
public void UpdateOccupiedArea() { if (objectLayers.Length != 0) { if (occupiedGridCells == null) { occupiedGridCells = new int[OccupiedCellsOffsets.Length]; } ClearOccupiedArea(); int cell = Grid.PosToCell(base.gameObject); ObjectLayer[] array = objectLayers; foreach (ObjectLayer objectLayer in array) { if (objectLayer != ObjectLayer.NumLayers) { for (int j = 0; j < OccupiedCellsOffsets.Length; j++) { CellOffset offset = OccupiedCellsOffsets[j]; int num = Grid.OffsetCell(cell, offset); Grid.Objects[num, (int)objectLayer] = base.gameObject; occupiedGridCells[j] = num; } } } } }
public void Update(bool update = true) { if (!updating) { updating = true; int num = 0; for (int i = 0; i < choreOffsets.Length; i++) { CellOffset offset = choreOffsets[i]; Chore chore = chores[i]; if (update && num < choreCount && IsOffsetValid(offset)) { num++; if (chore == null || chore.isComplete) { chores[i] = ((CreateChoreCB == null) ? null : CreateChoreCB(i)); } } else if (chore != null) { chore.Cancel("locator invalidated"); chores[i] = null; } } updating = false; } }
public void AddTemplate(TemplateContainer template, Vector2I position) { CellOffset[] array = new CellOffset[template.cells.Count]; for (int i = 0; i < template.cells.Count; i++) { array[i] = new CellOffset(template.cells[i].location_x, template.cells[i].location_y); } ClearTemplatesInArea(Grid.XYToCell(position.x, position.y), array); for (int j = 0; j < template.buildings.Count; j++) { buildings.Add((Prefab)template.buildings[j].Clone(position)); } for (int k = 0; k < template.pickupables.Count; k++) { pickupables.Add((Prefab)template.pickupables[k].Clone(position)); } for (int l = 0; l < template.elementalOres.Count; l++) { elementalOres.Add((Prefab)template.elementalOres[l].Clone(position)); } for (int m = 0; m < template.otherEntities.Count; m++) { otherEntities.Add((Prefab)template.otherEntities[m].Clone(position)); } for (int n = 0; n < template.cells.Count; n++) { preventFoWReveal.Add(new KeyValuePair <Vector2I, bool>(new Vector2I(position.x + template.cells[n].location_x, position.y + template.cells[n].location_y), template.cells[n].preventFoWReveal)); } }
public static List <LogicPorts.Port> CreateSingleInputPortList(CellOffset offset) { return(new List <LogicPorts.Port>() { LogicPorts.Port.InputPort(Door.OPEN_CLOSE_PORT_ID, offset, (string)STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN, (string)STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN_ACTIVE, (string)STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN_INACTIVE, false, false) }); }
private static HashedString CustomIdleAnim_Drecko(IdleStates.Instance smi, ref HashedString pre_anim) { CellOffset offset = new CellOffset(0, -1); bool facing = smi.GetComponent <Facing>().GetFacing(); NavType currentNavType = smi.GetComponent <Navigator>().CurrentNavType; if (currentNavType != NavType.Floor) { if (currentNavType == NavType.Ceiling) { offset = (facing ? new CellOffset(1, 1) : new CellOffset(-1, 1)); } } else { offset = (facing ? new CellOffset(1, -1) : new CellOffset(-1, -1)); } HashedString result = "idle_loop"; int num = Grid.OffsetCell(Grid.PosToCell(smi), offset); if (Grid.IsValidCell(num) && !Grid.Solid[num]) { pre_anim = "idle_loop_hang_pre"; result = "idle_loop_hang"; } return(result); }
/// <summary> /// Creates an inert input port that does not automatically handle Conduit Update behavior. The building must define its own behavior for the input port. /// </summary> /// <param name="conduitType">The type of conduit this port should attach to.</param> /// <param name="offset">The offset (left-right, down-up) of where this port is located. Offsets begin bottom-left.</param> /// <param name="iconColor">The color the port icon will appear as.</param> /// <returns></returns> public InputPort AddInputPortInert(ConduitType conduitType, CellOffset offset, Color iconColor) { InputPort port = AddInputPort(conduitType, offset, GameTags.Any, iconColor); port.UseConduitUpdater = false; return(port); }
private int GetTargetPoopCell() { CreatureCalorieMonitor.Instance sMI = base.smi.GetSMI <CreatureCalorieMonitor.Instance>(); currentlyPoopingElement = sMI.stomach.GetNextPoopEntry(); int num = GameUtil.FloodFillFind <object>(start_cell: (!(currentlyPoopingElement == base.smi.def.nestingPoopElement) || !(base.smi.def.nestingPoopElement != Tag.Invalid) || lastPoopCell == -1) ? Grid.PosToCell(this) : lastPoopCell, fn: IsValidNestingCell, arg: null, max_depth: 8, stop_at_solid: false, stop_at_liquid: true); if (num == -1) { CellOffset[] array = new CellOffset[5] { new CellOffset(0, 0), new CellOffset(-1, 0), new CellOffset(1, 0), new CellOffset(-1, -1), new CellOffset(1, -1) }; num = Grid.OffsetCell(lastPoopCell, array[UnityEngine.Random.Range(0, array.Length)]); int num2 = Grid.CellAbove(num); while (Grid.IsValidCell(num2) && Grid.Solid[num2]) { num = num2; num2 = Grid.CellAbove(num); } } return(num); }
public Extents(int cell, CellOffset[] offsets, Orientation orientation) { int num = 0; int num2 = 0; Grid.CellToXY(cell, out num, out num2); int num3 = num; int num4 = num2; for (int i = 0; i < offsets.Length; i++) { CellOffset rotatedCellOffset = Rotatable.GetRotatedCellOffset(offsets[i], orientation); int val = 0; int val2 = 0; int cell2 = Grid.OffsetCell(cell, rotatedCellOffset); Grid.CellToXY(cell2, out val, out val2); num = Math.Min(num, val); num2 = Math.Min(num2, val2); num3 = Math.Max(num3, val); num4 = Math.Max(num4, val2); } x = num; y = num2; width = num3 - num + 1; height = num4 - num2 + 1; }
private unsafe void UpdateOffsets(int cell, CellOffset[][] table) { Debug.Assert(table.Length <= 192, $"validRowIndices[{192}] isn't big enough < {table.Length}"); int *ptr = stackalloc int[192]; int num = 0; if (Grid.IsValidCell(cell)) { for (int i = 0; i < table.Length; i++) { CellOffset[] array = table[i]; int cell2 = Grid.OffsetCell(cell, array[0]); for (int j = 0; j < navGrid.ValidNavTypes.Length; j++) { NavType navType = navGrid.ValidNavTypes[j]; if (navType != NavType.Tube && navGrid.NavTable.IsValid(cell2, navType) && IsValidRow(cell, array)) { ptr[num] = i; num++; break; } } } } if (offsets == null || offsets.Length != num) { offsets = new CellOffset[num]; } for (int k = 0; k != num; k++) { offsets[k] = table[ptr[k]][0]; } }
private static HashedString CustomIdleAnim(IdleStates.Instance smi, ref HashedString pre_anim) { CellOffset offset = new CellOffset(0, -1); bool facing = smi.GetComponent <Facing>().GetFacing(); switch (smi.GetComponent <Navigator>().CurrentNavType) { case NavType.Floor: offset = ((!facing) ? new CellOffset(-1, -1) : new CellOffset(1, -1)); break; case NavType.Ceiling: offset = ((!facing) ? new CellOffset(-1, 1) : new CellOffset(1, 1)); break; } HashedString result = "idle_loop"; int num = Grid.OffsetCell(Grid.PosToCell(smi), offset); if (Grid.IsValidCell(num) && !Grid.Solid[num]) { pre_anim = "idle_loop_hang_pre"; result = "idle_loop_hang"; } return(result); }
private void RefreshVisualCells() { this.choreRangeVisualizer.x = -this.pickupRange / 2; this.choreRangeVisualizer.y = 0; this.choreRangeVisualizer.width = this.pickupRange; this.choreRangeVisualizer.height = this.pickupRange; if (selectable.IsSelected) { Traverse.Create(choreRangeVisualizer).Method("UpdateVisualizers").GetValue(); } Vector2I xy = Grid.CellToXY(this.NaturalBuildingCell()); int cell = Grid.XYToCell(xy.x, xy.y + this.pickupRange / 2); CellOffset offset = new CellOffset(0, this.pickupRange / 2); if ((bool)(UnityEngine.Object) this.rotatable) { CellOffset rotatedCellOffset = this.rotatable.GetRotatedCellOffset(offset); if (Grid.IsCellOffsetValid(this.NaturalBuildingCell(), rotatedCellOffset)) { cell = Grid.OffsetCell(this.NaturalBuildingCell(), rotatedCellOffset); } } this.pickupableExtents = new Extents(cell, this.pickupRange / 2); GameScenePartitioner.Instance.Free(ref this.pickupablesChangedEntry); this.pickupablesChangedEntry = GameScenePartitioner.Instance.Add("CreatureSensor.PickupablesChanged", (object)this.gameObject, this.pickupableExtents, GameScenePartitioner.Instance.pickupablesChangedLayer, new System.Action <object>(this.OnPickupablesChanged)); this.pickupablesDirty = true; }
private int GetVisualizerCell(Building building, CellOffset offset) { CellOffset rotatedOffset = building.GetRotatedOffset(offset); int cell = building.GetCell(); return(Grid.OffsetCell(cell, rotatedOffset)); }
public CellOffset Combine(CellOffset cel) { int newXOffset = this.xOffset + cel.xOffset; int newYOffset = this.yOffset + cel.yOffset; return(new CellOffset(newXOffset, newYOffset)); }
protected override void OnCleanUp() { if (smi != null) { smi.StopSM("cleanup"); } int cell = Grid.PosToCell(this); CellOffset[] tileOffsets = TileOffsets; foreach (CellOffset offset in tileOffsets) { CellOffset rotatedOffset = building.GetRotatedOffset(offset); int num = Grid.OffsetCell(cell, rotatedOffset); SimMessages.ReplaceAndDisplaceElement(num, SimHashes.Vacuum, CellEventLogger.Instance.SimCellOccupierOnSpawn, 0f, -1f, byte.MaxValue, 0, -1); Grid.Objects[num, 1] = null; Grid.Objects[num, 9] = null; Grid.Foundation[num] = false; Grid.SetSolid(num, false, CellEventLogger.Instance.SimCellOccupierDestroy); Grid.RenderedByWorld[num] = true; World.Instance.OnSolidChanged(num); GameScenePartitioner.Instance.TriggerEvent(num, GameScenePartitioner.Instance.solidChangedLayer, null); } CellOffset[] retractableOffsets = RetractableOffsets; foreach (CellOffset offset2 in retractableOffsets) { CellOffset rotatedOffset2 = building.GetRotatedOffset(offset2); int num2 = Grid.OffsetCell(cell, rotatedOffset2); Grid.FakeFloor[num2] = false; Pathfinding.Instance.AddDirtyNavGridCell(num2); } base.OnCleanUp(); }
protected override void OnSpawn() { base.OnSpawn(); if (infoStatusItem == null) { infoStatusItem = new StatusItem("GantryAutomationInfo", "BUILDING", string.Empty, StatusItem.IconType.Info, NotificationType.Neutral, false, OverlayModes.None.ID, true, 129022); infoStatusItem.resolveStringCallback = ResolveInfoStatusItemString; } GetComponent <KAnimControllerBase>().PlaySpeedMultiplier = 0.5f; int cell = Grid.PosToCell(this); PrimaryElement component = GetComponent <PrimaryElement>(); for (int i = 0; i < TileOffsets.Length; i++) { CellOffset rotatedOffset = building.GetRotatedOffset(TileOffsets[i]); int num = Grid.OffsetCell(cell, rotatedOffset); SimMessages.ReplaceAndDisplaceElement(num, component.ElementID, CellEventLogger.Instance.SimCellOccupierOnSpawn, component.Mass, component.Temperature, byte.MaxValue, 0, -1); Grid.Objects[num, 1] = base.gameObject; Grid.Foundation[num] = true; Grid.Objects[num, 9] = base.gameObject; Grid.SetSolid(num, true, CellEventLogger.Instance.SimCellOccupierForceSolid); Grid.RenderedByWorld[num] = false; World.Instance.OnSolidChanged(num); GameScenePartitioner.Instance.TriggerEvent(num, GameScenePartitioner.Instance.solidChangedLayer, null); } smi = new Instance(this, base.IsSwitchedOn); smi.StartSM(); GetComponent <KSelectable>().ToggleStatusItem(infoStatusItem, true, smi); }
protected override void OnSpawn() { base.OnSpawn(); fuel_tag = SimHashes.Petroleum.CreateTag(); fuel_consumer = base.gameObject.AddComponent <ConduitConsumer>(); fuel_consumer.conduitType = portInfo.conduitType; fuel_consumer.consumptionRate = 10f; fuel_consumer.capacityTag = fuel_tag; fuel_consumer.wrongElementResult = ConduitConsumer.WrongElementResult.Dump; fuel_consumer.forceAlwaysSatisfied = true; fuel_consumer.capacityKG = 100f; fuel_consumer.useSecondaryInput = true; RequireInputs requireInputs = base.gameObject.AddComponent <RequireInputs>(); requireInputs.conduitConsumer = fuel_consumer; requireInputs.SetRequirements(false, true); int cell = Grid.PosToCell(base.transform.GetPosition()); CellOffset rotatedOffset = building.GetRotatedOffset(portInfo.offset); secondaryInputCell = Grid.OffsetCell(cell, rotatedOffset); IUtilityNetworkMgr networkManager = Conduit.GetNetworkManager(portInfo.conduitType); flowNetworkItem = new FlowUtilityNetwork.NetworkItem(portInfo.conduitType, Endpoint.Sink, secondaryInputCell, base.gameObject); networkManager.AddToNetworks(secondaryInputCell, flowNetworkItem, true); fuel_meter = new MeterController(GetComponent <KBatchedAnimController>(), "meter_target_1", "meter_petrol", Meter.Offset.Infront, Grid.SceneLayer.NoLayer, Vector3.zero, "meter_target_1"); o2_meter = new MeterController(GetComponent <KBatchedAnimController>(), "meter_target_2", "meter_oxygen", Meter.Offset.Infront, Grid.SceneLayer.NoLayer, Vector3.zero, "meter_target_2"); base.smi.StartSM(); }
/// <summary> /// Creates a new element consumer range finder. /// </summary> /// <param name="template">The parent game object.</param> /// <param name="offset">The offset from the object's home cell where elements are /// consumed.</param> /// <param name="radius">The element consumer's radius.</param> /// <param name="color">The color to use when displaying the range.</param> public static void Create(GameObject template, CellOffset offset, int radius, Color color = default) { if (color == default) { color = Color.white; } if (template == null) { throw new ArgumentNullException("template"); } if (radius > 0) { var prefabID = template.GetComponent <KPrefabID>(); if (prefabID != null) { // Only when instantiated, not on the template prefabID.instantiateFn += (obj) => { var visualizer = obj.AddComponent <ElementConsumerVisualizer>(); visualizer.color = color; visualizer.offset = offset; visualizer.radius = radius; } } ; } }
public static void Postfix(ref bool __result, BuildingDef __instance, GameObject source_go, int cell, Orientation orientation, ref string fail_reason) { if (!__result || source_go == null) { return; } List <ConduitIO> portList = MultiIOExtensions.GetAllPortsFromObject(source_go); if (portList.Count == 0) { return; } foreach (ConduitIO port in portList) { CellOffset rotatedCellOffset = Rotatable.GetRotatedCellOffset(port.CellOffset, orientation); int portCell = Grid.OffsetCell(cell, rotatedCellOffset); //fail_reason is ref, Invoke will modify this array if fail_reason is used object[] parameters = new object[] { source_go, port.ConduitType, portCell, fail_reason }; //Debug.Log($"[MultiIO] Are Conduit Ports in Valid Positions?"); __result = (bool)areConduitPortsInValidPositionsMethod.Invoke(__instance, parameters); fail_reason = (string)parameters[3]; if (!__result) { return; } } }
/// <summary> /// Creates a logic port, in a method compatible with both the new and old Automation /// updates. The port will have the default strings which fit well with the /// LogicOperationalController. /// </summary> /// <returns>A logic port compatible with both editions.</returns> public static LogicPorts.Port CompatLogicPort(LogicPortSpriteType type, CellOffset offset) { return(new LogicPorts.Port(LogicOperationalController.PORT_ID, offset, STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL, STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL_ACTIVE, STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL_INACTIVE, false, type)); }
//This preview input can constantly change positions, while a standard InputPort is not expected to change. public override int GetPortCell() { CellOffset roatedOffset = building.GetRotatedOffset(CellOffset); int bottomLeftCell = Grid.PosToCell(building.transform.GetPosition()); portCell = Grid.OffsetCell(bottomLeftCell, roatedOffset); return(portCell); }
private bool IsOffsetValid(CellOffset offset) { int cell = Grid.PosToCell(owner); int cell2 = Grid.OffsetCell(cell, offset); int anchor_cell = Grid.CellBelow(cell2); return(GameNavGrids.FloorValidator.IsWalkableCell(cell2, anchor_cell, true)); }
/// <summary> /// Calculates the offset cell from the specified starting point, including the /// rotation of this object. /// </summary> /// <param name="baseCell">The starting cell.</param> /// <param name="offset">The offset if the building had its default rotation.</param> /// <returns>The computed destination cell.</returns> protected int RotateOffsetCell(int baseCell, CellOffset offset) { if (rotatable != null) { offset = rotatable.GetRotatedCellOffset(offset); } return(Grid.OffsetCell(baseCell, offset)); }
public OutputItem(SimHashes element, float creation_rate, bool store, CellOffset emit_offset, float min_temperature = 0f) { this.element = element; this.creationRate = creation_rate; this.store = store; this.emitOffset = emit_offset; this.minTemperature = min_temperature; }
/// <summary> /// Add a cell offset value to a list object, checking for uniqueness /// </summary> /// <param name="listCellIds"></param> /// <param name="rowOffset"></param> /// <param name="columnOffset"></param> /// <remarks></remarks> private static void AddCellOffsetToList(ref List <CellOffset> listCellIds, int rowOffset, int columnOffset) { CellOffset coord = new CellOffset(rowOffset, columnOffset); if (!listCellIds.Contains(coord)) { listCellIds.Add(coord); } }
public PowerRequirement(float wattage, CellOffset plugLocation) { if (wattage.IsNaNOrInfinity() || wattage < 0.0f) { throw new ArgumentException("wattage"); } MaxWattage = wattage; PlugLocation = plugLocation; }
internal void AssignPort(DisplayConduitPortInfo port) { this.type = port.type; this.offset = port.offset; this.offsetFlipped = port.offsetFlipped; this.input = port.input; this.color = port.color; this.sprite = GetSprite(); }