/// <summary>Attempt to claim this node for the specified segment.</summary> /// <param name="segment">The segment attempting to claim the node.</param> /// <returns>Whether or not the claim was successful.</returns> public bool claim(Segment segment) { bool claimed = false; int relSegIndex = -1; int lane = segment.getNodeIndex(this); int oppLane = 1 - lane; Node oppNode = segment.Nodes[oppLane]; // Determine whether or not the claim is successful if (Destroyed || Owner != segment.Owner) { // can't claim destroyed nodes or nodes owned by someone else } else if (!Active) // if the node is inactive... { if (InWorld.Collision.nodeCollision(Pos, Radius, new List<SegmentSkel>(1) { segment }, new List<NodeSkel>(1) { this }) || InWorld.Collision.nodeCollNodeSpacing(Pos, Radius, Spacing, Owner, new List<NodeSkel>(1) { this }, false)) destroy(); else claimed = true; } else if ((relSegIndex = relatedSeg(oppNode)) != -1) // if the node is related { claimed = true; // make sure the connection is more than one segment away foreach (Segment seg in Segments) { if (seg != null && seg.getOppNode(this) == oppNode) { claimed = false; break; } } if (claimed) severSegment(relSegIndex); } else if (NumSegments < Segments.Length) // if same owner, but unrelated { claimed = true; } if (!claimed) { segment.State[oppLane] = Segment.SegState.Retracting; } else { // complete the segment segment.State[oppLane] = Segment.SegState.Complete; // prepare to invalidate visibility for old owner // and apply new visibility to new owner Player invalOwner = (Active && Owner != segment.Owner && Owner.Type == Player.PlayerType.Human) ? Owner : null; bool applyVisibility = (!Active || Owner != segment.Owner) && segment.Owner.Type == Player.PlayerType.Human; Active = true; addSegment(segment, true); Owner = segment.Owner; // exchange parentage and density if (segment.State[lane] == Segment.SegState.Complete) { // exchange density int peopleToSend = 0; FInt capacityToSend = FInt.F0; for (int i = 0; i < Segments.Length; i++) { if (Segments[i] != null) { peopleToSend += SegNumPeople[i]; capacityToSend += SegCapacity[i]; } } int peopleToReceive = oppNode.PeopleToSort; FInt capacityToReceive = FInt.F0; for (int i = 0; i < oppNode.Segments.Length; i++) { if (oppNode.Segments[i] != null) { peopleToReceive += oppNode.SegNumPeople[i]; capacityToReceive += oppNode.SegCapacity[i]; } } alterDensity(peopleToReceive, capacityToReceive, segment); oppNode.alterDensity(peopleToSend, capacityToSend, segment); // exchange parentage Node[] parentsToSend = null; if (Parents.Count > 0 || IsParent) { parentsToSend = new Node[Parents.Count + (IsParent ? 1 : 0)]; Parents.CopyTo(parentsToSend); if (IsParent) parentsToSend[parentsToSend.Length - 1] = this; } if (oppNode.Parents.Count > 0 || oppNode.IsParent) { if (!oppNode.IsParent) { addParents(segment, oppNode.Parents); } else { List<Node> parentsToReceive = new List<Node>(oppNode.Parents.Count + 1); parentsToReceive.AddRange(oppNode.Parents); parentsToReceive.Add(oppNode); addParents(segment, parentsToReceive); } } if (parentsToSend != null) oppNode.addParents(segment, parentsToSend); } else // get segment's density { int peopleToReceive = segment.NumPeople; FInt capacityToReceive = (segment.State[lane] != Segment.SegState.Retracting) ? segment.Capacity : FInt.F0; alterDensity(peopleToReceive, capacityToReceive, segment); } // update visibility if (invalOwner != null) { invalOwner.Fog.invalidate(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + SightDistance, Y + SightDistance)); InWorld.refreshVisibility(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + Radius, Y + Radius)); } if (applyVisibility) { Owner.Fog.applyVisibility(this); InWorld.refreshVisibility(new VectorF(X - SightDistance, Y - SightDistance), new VectorF(X + SightDistance, Y + SightDistance)); } Visible = Owner.Type == Player.PlayerType.Human || (Active && InWorld.HumanPlayer.Fog.isVisible(this)); // add event InWorld.addEvent(ID, WorldEvent.EventType.NodeChangeState); // run script if on hotspot if (OwnsHotspot != null && !string.IsNullOrWhiteSpace(OwnsHotspot.Script)) InWorld.Script.runScript(OwnsHotspot.Script); } // add event if (!Destroyed) InWorld.addEvent(segment.ID, WorldEvent.EventType.SegChangeState); return claimed; }