private void TeleportPets(Character chr, GameWorld.Cell destinationCell) { if (chr.Pets != null) { foreach (NPC pet in chr.Pets) { // No sounds... SendPortalEntranceEmote(pet); pet.CurrentCell = destinationCell; SendPortalExitEmote(pet); ResetRecallRings(pet); // in case phantasms have been commanded to wear a recall ring?? } } }
public static void Shuffle(ref List <GameWorld.Cell> list) { Random rng = new Random(); int n = list.Count; while (n > 1) { n--; int k = rng.Next(n + 1); GameWorld.Cell value = list[k]; list[k] = list[n]; list[n] = value; } }
/// <summary> /// Dump Corpse.Contents into Cell.Items. /// </summary> /// <param name="corpse">The Corpse to be dumped.</param> /// <param name="cell">The Cell to place the contents of the corpse.</param> public static void DumpCorpse(Corpse corpse, GameWorld.Cell cell) { try { int z = 0; int i = 0; z = corpse.Contents.Count - 1; if (corpse.Contents.Count > 0) { System.Collections.ArrayList templist = new System.Collections.ArrayList(); Item[] contents = new Item[corpse.Contents.Count]; corpse.Contents.CopyTo(contents); foreach (Item item in contents) { templist.Add(item); } z = templist.Count - 1; while (z >= 0) { Item item = (Item)templist[z]; for (i = templist.Count - 1; i > -1; i--) { Item tmpitem = (Item)templist[i]; if (tmpitem.name == item.name) { templist.RemoveAt(i); corpse.Contents.RemoveAt(i); cell.Add(tmpitem); z = templist.Count; } } z--; } } } catch (Exception e) { Utils.LogException(e); } }
public static bool CellMeetsTeleportRequirements(GameWorld.Cell cell) { if (cell == null) { return(false); } if (cell.IsOutOfBounds) { return(false); // out of bounds } if (GameWorld.Map.IsSpellPathBlocked(cell)) { return(false); // spell path is blocked } //if (cell.IsNoRecall) return false; // no recall if (cell.Map.ZPlanes[cell.Z].zAutonomy != null && !cell.Map.ZPlanes[cell.Z].zAutonomy.allowChaosPortal) { return(false); // z plane does not allow chaos portal } return(true); }
public bool OnCast(Character caster, string args) { // Determine map with args. if (args == null || args == "") { caster.WriteToDisplay("You must determine where you will teleport to."); return(false); } // Basically planes of existence are offlimits, for now, or perhaps there will be a planar projection spell in the future. string[] offlimitMaps = new string[] { "eridu", "praetoseba", "hell" }; if (Array.IndexOf(offlimitMaps, args.ToLower()) > -1 && !caster.IsImmortal) { caster.WriteToDisplay("You cannot travel to some planes of existence with the " + ReferenceSpell.Name + " spell."); return(false); } GameWorld.Map destinationMap = null; foreach (GameWorld.Land land in GameWorld.World.GetFacetByID(caster.FacetID).Lands) { foreach (GameWorld.Map map in land.Maps) { if (map.Name.ToLower() == args.ToLower()) { destinationMap = map; break; } } if (destinationMap != null) { break; } } if (destinationMap == null) { caster.WriteToDisplay("There is no such place in this reality."); return(false); } // Get a random cell. Must not be lair, out of bounds, or path blocked. List <Tuple <int, int, int> > cellsList = new List <Tuple <int, int, int> >(destinationMap.cells.Keys); GameWorld.Cell destinationCell = null; do { destinationCell = destinationMap.cells[cellsList[Rules.Dice.Next(cellsList.Count)]]; }while (!CellMeetsTeleportRequirements(destinationCell)); ReferenceSpell.SendGenericCastMessage(caster, null, true); caster.SendToAllInSight("A portal of chaotic energy opens up before you and " + caster.GetNameForActionResult(true) + " steps inside."); caster.WriteToDisplay("A portal of chaotic energy opens up before you and you step inside."); // Whirlwind sound... //caster.CurrentCell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.Whirlwind)); // fail to teleport if holding a corpse or drop it // check caster first, nobody teleports if (!CharacterMeetsTeleportRequirements(caster)) { caster.SendToAllInSight("The chaos portal immediately collapses and " + caster.GetNameForActionResult(true) + " is slammed into the ground."); AreaEffect knockdown = new AreaEffect(Effect.EffectTypes.Concussion, "", 50 + Rules.Dice.Next(-5, +5), 0, caster, caster.CurrentCell); NPC.AIRandomlyMoveCharacter(caster); return(false); } List <Character> teleportedCharacters = null; if (caster.Group != null && caster.Group.GroupMemberIDList != null) { teleportedCharacters = new List <Character>(); foreach (int uniqueID in caster.Group.GroupMemberIDList) { if (uniqueID != caster.UniqueID) { PC pc = PC.GetOnline(uniqueID); if (CharacterMeetsTeleportRequirements(pc)) { teleportedCharacters.Add(pc); pc.WriteToDisplay("You follow " + caster.GetNameForActionResult(true) + " through the chaos portal. You are now in " + pc.Map.Name + "."); } else { pc.WriteToDisplay("You are thrown back out of the chaos portal!"); NPC.AIRandomlyMoveCharacter(pc); } } } } // make the move, clear recall rings. possible stun or blindness and/or damage? GameWorld.Cell chaosPortalCell = caster.CurrentCell; // stored for emote and sound upon portal collapse destinationCell.EmitSound(ReferenceSpell.SoundFile); //destinationCell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.Whirlwind)); SendPortalEntranceEmote(caster); //caster.SendSoundToAllInRange(Sound.GetCommonSound(Sound.CommonSound.MapPortal)); caster.CurrentCell = destinationCell; SendPortalExitEmote(caster); ResetRecallRings(caster); TeleportPets(caster, destinationCell); if (caster.Group != null && teleportedCharacters != null) { foreach (Character chr in teleportedCharacters) { SendPortalEntranceEmote(chr); //chr.SendSoundToAllInRange(Sound.GetCommonSound(Sound.CommonSound.MapPortal)); chr.CurrentCell = destinationCell; SendPortalExitEmote(chr); ResetRecallRings(chr); TeleportPets(chr, destinationCell); } } chaosPortalCell.SendToAllInSight("With a thunder clap, the chaos portal winks out of existence."); chaosPortalCell.EmitSound(Sound.GetCommonSound(Sound.CommonSound.ThunderClap)); return(true); }
public bool OnPerform(Character chr, string args) { string[] sArgs = args.Split(" ".ToCharArray()); GameWorld.Cell cell = GameWorld.Map.GetCellRelevantToCell(chr.CurrentCell, sArgs[0], true); if (cell == null || (!cell.IsLockedHorizontalDoor && !cell.IsLockedVerticalDoor)) { chr.WriteToDisplay("There is no locked door there."); return(false); } if (cell.cellLock != null && cell.cellLock.key != "") { chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.UnlockingDoor)); chr.WriteToDisplay("You have failed to pick the lock."); if (!Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity)) { Rules.BreakHideSpell(chr); } return(true); } Item lockpick = chr.FindHeldItem("lockpick"); if (lockpick == null || (lockpick != null && lockpick.skillType != Globals.eSkillType.Thievery)) { chr.WriteToDisplay("You are not holding a lockpick."); return(false); } Skills.GiveSkillExp(chr, Skills.GetSkillLevel(chr.thievery) * 50, Globals.eSkillType.Thievery); // 50 percent base chance to steal int successChance = 50; // this is the 100 sided die roll plus the character's thievery skill level int roll = Rules.RollD(1, 100); // you successfully steal when the roll plus thievery skill level x 2 is greater than the chance if (roll + (Skills.GetSkillLevel(chr.thievery) * 2) > successChance) { chr.WriteToDisplay("You have successfully picked the lock."); chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.UnlockingDoor)); // give more experience Skills.GiveSkillExp(chr, Skills.GetSkillLevel(chr.thievery) * 50, Globals.eSkillType.Thievery); GameWorld.Map.UnlockDoor(cell, cell.cellLock.key); if (!Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity)) { chr.WriteToDisplay("You have failed to remain hidden."); Rules.BreakHideSpell(chr); } } else { chr.EmitSound(Sound.GetCommonSound(Sound.CommonSound.UnlockingDoor)); chr.WriteToDisplay("You have failed to pick the lock."); if (!Rules.FullStatCheck(chr, Globals.eAbilityStat.Dexterity)) { chr.WriteToDisplay("You have failed to remain hidden."); Rules.BreakHideSpell(chr); } } return(true); }