public void Use(IActor actor) { //set up needed Variables IGameServer Server = actor.State as IGameServer; IBiomeSystem currentSystem = ((IGameServer)actor.State).Biomes.GetSystems()[actor.InstanceID]; //Permission Check, is the Player allowed to use the Teleporter? if (currentSystem.Nation != string.Empty && currentSystem.Nation != actor.Nation) { Server.ChatManager.SendActorMessage("You must be in the Nation that claimed this System to use the Teleporter.", actor); return; } //Set up ChunkDictionary so we can access the Chunks in System (We need the Chunk to Teleport the player to later) Dictionary <Point3D, IChunk> ChunkDictionary = SNScriptUtils._Utils.CreateChunkDictionary(currentSystem); //create offset List (the 4 Positions around our Activator where we expect at least one Teleporter) List <Point3D> offsetList = new List <Point3D>(); offsetList.Add(new Point3D(0, -1, -1)); offsetList.Add(new Point3D(0, -1, 1)); offsetList.Add(new Point3D(1, -1, 0)); offsetList.Add(new Point3D(-1, -1, 0)); List <Object[, ]> SpecialBlockList = null; Teleporter nearbyTeleporter = new Object() as Teleporter; //Get List of Teleporters in vicinity to the Activator based on offsetList (expected Teleporter locations) if (SNScriptUtils._Utils.FindCustomSpecialBlocksAround(this.Position, this.Chunk, offsetList, (uint)7100, ChunkDictionary, out SpecialBlockList)) { //just take the first one found for now IChunk tmpChunk = SpecialBlockList[0][0, 1] as IChunk; Point3D TeleporterLocalPos = (Point3D)SpecialBlockList[0][0, 0]; ISpecialBlock targetSpecialBlock = tmpChunk.GetSpecialBlocks().FirstOrDefault(item => (item is Teleporter) && ((item as Teleporter).Position == TeleporterLocalPos)); nearbyTeleporter = targetSpecialBlock as Teleporter; } else { Server.ChatManager.SendActorMessage("There is no Teleporter around the Activator!", actor); return; } //Check if Player is standing on the Teleporter right now Point3D teleporterPadFakeGlobalPos = new Point3D( nearbyTeleporter.Position.X + (int)((IChunk)SpecialBlockList[0][0, 1]).Position.X, nearbyTeleporter.Position.Y + (int)((IChunk)SpecialBlockList[0][0, 1]).Position.Y + 1, nearbyTeleporter.Position.Z + (int)((IChunk)SpecialBlockList[0][0, 1]).Position.Z ); Point3D actorPos = _Utils.GetActorFakeGlobalPos(actor, new Point3D(0, -1, 0)); if (teleporterPadFakeGlobalPos != actorPos) { Server.ChatManager.SendActorMessage("You have to stand on the Teleporter platform to use the Teleporter!", actor); return; } //Get TargetTeleporterPos Point3D TargetTeleporterFakeGlobalPos = nearbyTeleporter.GetTargetTeleporter(); //Check if TargetTeleporter exists //Get Chunk where the TargetTeleporter is in IChunk targetChunk = new Object() as IChunk; if (SNScriptUtils._Utils.getChunkObjFromFakeGlobalPos(TargetTeleporterFakeGlobalPos, ChunkDictionary, out targetChunk)) { Point3D TargetTeleporterLocalPos = new Point3D( TargetTeleporterFakeGlobalPos.X - (int)targetChunk.Position.X, TargetTeleporterFakeGlobalPos.Y - (int)targetChunk.Position.Y, TargetTeleporterFakeGlobalPos.Z - (int)targetChunk.Position.Z ); ushort targetBlockID = new ushort(); targetBlockID = targetChunk.Blocks[targetChunk.GetBlockIndex(TargetTeleporterLocalPos.X, TargetTeleporterLocalPos.Y, TargetTeleporterLocalPos.Z)]; if ((targetBlockID) == (ushort)7100) //TargetTeleporter still exists! { ISpecialBlock targetSpecialBlock = targetChunk.GetSpecialBlocks().FirstOrDefault(item => (item is Teleporter) && ((item as Teleporter).Position == TargetTeleporterLocalPos)); Teleporter targetTeleporter = targetSpecialBlock as Teleporter; //Teleport Player to TargetTeleporterPos + Offset (2.1 Blocks Up (Y)) or he'd get stuck in the Teleporter double playerTeleportLocalPosY = (double)targetTeleporter.Position.Y + 2.1; DoubleVector3 playerTeleportLocalPos = new DoubleVector3((double)targetTeleporter.Position.X, playerTeleportLocalPosY, (double)targetTeleporter.Position.Z); actor.SetLocalPosition(targetChunk.ID, targetChunk.World, playerTeleportLocalPos); } else { if (debug) { Console.WriteLine("TargetTeleporter does not exist anymore, other block ID found: " + ((int)targetBlockID).ToString()); } ; if (debug) { Console.WriteLine("I've been looking at Position: " + TargetTeleporterLocalPos.ToString()); } ; Server.ChatManager.SendActorMessage("The Teleporter you wanted to teleport to, does not exist anymore!", actor); nearbyTeleporter.DeleteTargetTeleporter(); return; } } else { if (debug) { Console.WriteLine("Chunk does not exist! Pos: " + TargetTeleporterFakeGlobalPos.ToString()); } ; Server.ChatManager.SendActorMessage("The Teleporter you wanted to teleport to, does not exist anymore!", actor); nearbyTeleporter.DeleteTargetTeleporter(); return; } }
public void Use(IActor targetActor) { //get variables IChunk chunk = this.Chunk; int x = this.Position.X; int y = this.Position.Y; int z = this.Position.Z; IActor actor = targetActor as IActor; IGameServer Server = actor.State as IGameServer; IBiomeManager biomeManager = Server.Biomes; var SystemsCollection = biomeManager.GetSystems(); uint currentSystemID = actor.InstanceID; IBiomeSystem currentSystem; SystemsCollection.TryGetValue(currentSystemID, out currentSystem); this.ChunkDictionary = SNScriptUtils._Utils.CreateChunkDictionary(currentSystem); if (!chunk.IsStaticChunk) { Server.ChatManager.SendActorMessage("A Teleporter cannot be used on a ship.", actor); } else if (currentSystem.Nation != string.Empty && currentSystem.Nation != actor.Nation) { Server.ChatManager.SendActorMessage("You must be in the Nation that claimed this System to use the Teleporter.", actor); } else { //save global position of Block which has just been clicked on Point3D posA = new Point3D((int)chunk.Position.X + x, (int)chunk.Position.Y + y, (int)chunk.Position.Z + z); //if there already is a stored Variable .. if (actor.SessionVariables.ContainsKey("Teleporter")) { // .. get the saved point (a previously clicked teleporter) Point3D posB = (Point3D)actor.SessionVariables["Teleporter"]; // and delete it from the sessionVariables, we have it in posA and posB now actor.SessionVariables.Remove("Teleporter"); // obvious check if (posA == posB) { Server.ChatManager.SendActorMessage("A Teleporter can not link with itself.", actor); } //if they differ we have two points: The two Teleporters, the player wants to link! else { ushort blockID; //check if previously clicked Teleporter still exists if (!SNScriptUtils._Utils.GetBlockIdAtFakeGlobalPos(this.ChunkDictionary, posB, out blockID) || (int)blockID != 7100) { if (debug) { Console.WriteLine("blockID=" + ((int)blockID).ToString()); } Server.ChatManager.SendActorMessage("The previous Teleporter you clicked has been destroyed", actor); } else { //now we can link the two teleporters //get the ChunkKey of the Chunk where the SourceTeleporter is in Point3D staticChunkKey = SNScriptUtils._Utils.GetChunkKeyFromFakeGlobalPos(posB.ToDoubleVector3); //Get SourceChunk Object IChunk sourceChunk = this.ChunkDictionary[staticChunkKey]; //Get all SpecialBlocks in the SourceChunk (our Teleporter is in there) List <ISpecialBlock> specialblockslist = sourceChunk.GetSpecialBlocks(); //calculate position of SourceTeleporter within its Chunk Point3D posSourceTelePorter = new Point3D(posB.X - staticChunkKey.X, posB.Y - staticChunkKey.Y, posB.Z - staticChunkKey.Z); //get the SourceTeleporter by the Position we just calculated ISpecialBlock SpecialBlock = specialblockslist.First(item => (item is Teleporter) && ((item as Teleporter).Position == posSourceTelePorter)); //Now we have the previously clicked Teleporter as accesible Object Teleporter sourceTeleporter = SpecialBlock as Teleporter; //Set the Teleporter, the SourceTeleporter is linked to sourceTeleporter.SetTargetTeleporter(posA); //Inform the Player what happened: The two Teleporters are linked Server.ChatManager.SendActorMessage("You can now Teleport from the first Teleporter to the one you clicked last.", actor); } } } else { actor.SessionVariables.Add("Teleporter", (object)posA); Server.ChatManager.SendActorMessage("Right click a second Teleporter to link it with this one.", actor); } } //get the index for the Block array from the given x, y and z int index = chunk.GetBlockIndex(x, y, z); //get the specific Block data by its index ushort currentBlock = chunk.Blocks[index]; }