public void propagatePulse(PulseToken iPT) { if (iPT.speed == 0) { // Reset PT speed iPT.speed = wire.pulse_speed; pulse_bag.Add(iPT); pulse_color(); return; // Stop propagation } if (successors.Count == 0) { foreach (ActivableObject target in targets) { this.activated_this_cycle = target.listen(iPT); } iPT.deletion_flag = true; reset_color(); } else { foreach (Vector3Int succ_coord in successors) { WireChunk wc = wire.getWChunkFromCoord(succ_coord); wc.propagatePulse(iPT.getPropagated()); // decrement speed as we propagate iPT.deletion_flag = true; reset_color(); } } }
} //! findPath public bool findActivableTarget(WireChunk iChunk) { Vector3Int up = iChunk.coord + new Vector3Int(0, 1, 0); Vector3Int down = iChunk.coord + new Vector3Int(0, -1, 0); Vector3Int left = iChunk.coord + new Vector3Int(-1, 0, 0); Vector3Int right = iChunk.coord + new Vector3Int(1, 0, 0); // switch to woorld coordinate Vector3 worldcoord_up = GL.CellToWorld(up); Vector3 worldcoord_down = GL.CellToWorld(down); Vector3 worldcoord_left = GL.CellToWorld(left); Vector3 worldcoord_right = GL.CellToWorld(right); // ALT solution : Make a cache with activable objects pos and compare distance with woorldcoord_x // check if there is an activable object in current radius Vector2 up_center = new Vector2(worldcoord_up.x, worldcoord_up.y); Vector2 down_center = new Vector2(worldcoord_down.x, worldcoord_down.y); Vector2 left_center = new Vector2(worldcoord_left.x, worldcoord_left.y); Vector2 right_center = new Vector2(worldcoord_right.x, worldcoord_right.y); float radius = 1.0f; ContactFilter2D filter = new ContactFilter2D(); filter.NoFilter(); List <Collider2D> up_col = new List <Collider2D>(5), down_col = new List <Collider2D>(5), left_col = new List <Collider2D>(5), right_col = new List <Collider2D>(5); int res_up = Physics2D.OverlapCircle(up_center, radius, filter, up_col); int res_down = Physics2D.OverlapCircle(down_center, radius, filter, down_col); int res_left = Physics2D.OverlapCircle(left_center, radius, filter, left_col); int res_right = Physics2D.OverlapCircle(right_center, radius, filter, right_col); if (res_up > 0) { iChunk.AddTargets(LookForActivables(up_col)); } if (res_down > 0) { iChunk.AddTargets(LookForActivables(down_col)); } if (res_left > 0) { iChunk.AddTargets(LookForActivables(left_col)); } if (res_right > 0) { iChunk.AddTargets(LookForActivables(right_col)); } return(iChunk.targets.Count > 0); }
public void delete_chunk(WireChunk iChunk) { foreach (Vector3Int succ in iChunk.successors) { WireChunk wc_succ = getWChunkFromCoord(succ); wc_succ.predecessors.Remove(iChunk.coord); } foreach (Vector3Int pred in iChunk.predecessors) { WireChunk wc_pred = getWChunkFromCoord(pred); wc_pred.successors.Remove(iChunk.coord); } chunks.Remove(iChunk); }
public void update_pulses() { // inf wire if (is_infinite) { return; } // propagation of pulses int n_chunks = chunks.Count; for (int i = n_chunks - 1; i >= 0; i--) { WireChunk wc = chunks[i]; if (wc == null) { Debug.LogError("Missing WireChunk."); continue; } // reset activated state wc.activated_this_cycle = false; // propagate impulses if needed if (wc.hasImpulse()) { wc.propagateAll(); } } // If no activation of chunks carrying targets, we deactivate targets. foreach (WireChunk wc in chunks) { if (wc.targets.Count != 0) { if (!wc.activated_this_cycle) { foreach (ActivableObject ao in wc.targets) { ao.deactivate(); } } } } pulses_got_updated = true; // TEMP OnPostTick }
public Wire(ActivatorObject iEmitter, SIGNAL_KEYS iSigType, ConnectorGraph iCG) { CG = iCG; chunks = new List <WireChunk>(1); if (iEmitter == null) { Debug.LogError("Missing Emitter in Wire."); emitter = null; } emitter = iEmitter; sig_key = iEmitter.signalKey; pulse_speed = emitter.pulse_speed; root_chunk = null; is_infinite = (pulse_speed <= 0) ? true : false; has_TL_obs = false; }
void findPath(ref Wire ioCurrWire, WireChunk iChunkToExpand) { if (iChunkToExpand == null) { return; } // Find neighbors and set successors/predecessors List <Vector3Int> neighbors = findNeighbors(iChunkToExpand.coord); foreach (Vector3Int neighbor in neighbors) { if (iChunkToExpand.predecessors.Contains(neighbor)) { continue; } if (iChunkToExpand.coord == neighbor) { iChunkToExpand.predecessors.Add(neighbor); continue; } iChunkToExpand.successors.Add(neighbor); WireChunk new_chunk = new WireChunk(neighbor, ioCurrWire, this); new_chunk.predecessors.Add(iChunkToExpand.coord); ioCurrWire.chunks.Add(new_chunk); } // recurse to explore path in deepness if (iChunkToExpand.successors.Count > 0) { foreach (Vector3Int coord_chunk_to_explore in iChunkToExpand.successors) { findPath(ref ioCurrWire, ioCurrWire.getWChunkFromCoord(coord_chunk_to_explore)); } } else { // try to find an activable target if no successors if (findActivableTarget(iChunkToExpand)) { Debug.Log(" Found an activable target for current wire path."); //ioCurrWire.targets.Add( iChunkToExpand.target.gameObject ); } } } //! findPath
public void cut_dead_branches(ref Wire ioWire) { List <WireChunk> to_cut = new List <WireChunk>(); foreach (WireChunk wc in ioWire.chunks) { if ((wc.successors.Count == 0) && (wc.targets.Count == 0)) { // Dead branch WireChunk cut_wc = wc; int n_pred = cut_wc.predecessors.Count; int n_succ = cut_wc.successors.Count; int n_neighbors = n_pred + n_succ; to_cut.Add(cut_wc); while (n_pred == 1) // dangerous? { WireChunk predec = ioWire.getWChunkFromCoord(cut_wc.predecessors[0]); n_pred = predec.predecessors.Count; n_succ = predec.successors.Count; n_neighbors = n_pred + n_succ; if (n_neighbors > 2) { break; } to_cut.Add(predec); cut_wc = predec; } //!while // got out of while if >1 precessor (junc) or solo (0 p) // thus we add this last WC to cut and we'll remove links to it afterwards //to_cut.Add(cut_wc); } }//! for wc // Actual cut foreach (WireChunk wc_to_cut in to_cut) { ioWire.delete_chunk(wc_to_cut); } }
public void addRootChunk(Vector3Int iRootPosition) { root_chunk = new WireChunk(iRootPosition, this, CG); chunks.Add(root_chunk); }