// Dispatches a guard to hunt down the player that has committed a crime and // has the guard capture them. static void DispatchGuard(CharData ch) { CharData mob = Database.CreateMobile(Database.GetMobTemplate(ch.InRoom.Area.DefenderTemplateNumber)); mob.AddToRoom(Room.GetRoom(ch.InRoom.Area.BarracksRoom)); if (!mob.HasActionBit(MobTemplate.ACT_MEMORY)) { mob.SetActionBit(MobTemplate.ACT_MEMORY); } if (!mob.HasActionBit(MobTemplate.ACT_HUNTER)) { if (mob.HasActionBit(MobTemplate.ACT_SENTINEL)) { mob.RemoveActionBit(MobTemplate.ACT_SENTINEL); } } mob.SetAffectBit(Affect.AFFECT_JUSTICE_TRACKER); mob.MobileTemplate.AddSpecFun("spec_justice_guard"); Combat.StartGrudge(mob, ch, false); return; }
/// <summary> /// Resets a room, reloading according to resets. /// </summary> /// <param name="notInitial"></param> /// <returns></returns> public bool ResetRoom(int notInitial) { Exit exit = null; CharData mobile; CharData lastMob = null; int level = 0; bool last = true; // Added for debugging. string text = String.Empty; foreach (Reset reset in Area.Resets) { if (!reset.IsRoomReset(this)) { continue; } Object obj; Object lastObj; MobTemplate mobIndex; ObjTemplate objTemplate; Room room; switch (reset.Command) { default: Log.Error("RoomIndex.Reset(): bad command %c.", reset.Command); break; case 'M': mobIndex = Database.GetMobTemplate(reset.Arg1); if (!mobIndex) { Log.Error("RoomIndex.Reset(): 'M': bad mob index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'R': bad room index number {0} for arg3.", reset.Arg3); continue; } if ((mobIndex.HasSpecFun("spec_cast_ghost")) && (Database.SystemData.WeatherData.Sunlight > SunType.night) && (Database.SystemData.WeatherData.Sunlight < SunType.moonrise)) { last = false; continue; } level = Macros.Range(0, mobIndex.Level - 2, Limits.LEVEL_HERO); if (mobIndex.NumActive >= reset.Arg2) { last = false; break; } mobile = Database.CreateMobile(mobIndex); // Check for pet shop. Room prevRoom = GetRoom(room.IndexNumber - 1); if (prevRoom && prevRoom.HasFlag(ROOM_PET_SHOP)) { mobile.SetActionBit(MobTemplate.ACT_PET); } if (room.IsDark()) { mobile.SetAffectBit(Affect.AFFECT_INFRAVISION); } mobile.AddToRoom(room); mobile.LoadRoomIndexNumber = room.IndexNumber; // This code makes mounts make their mounters mount them. if (reset.Arg0 == -1 && lastMob) { // If set to be mounted. String[] keywords = mobile.Name.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); Command.Mount(lastMob, keywords); } lastMob = mobile; level = Macros.Range(0, mobile.Level - 2, Limits.LEVEL_HERO); last = true; break; case 'F': mobIndex = Database.GetMobTemplate(reset.Arg1); if (!mobIndex) { Log.Error("RoomIndex.Reset(): 'F': bad mob index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'F': bad room index number {0} for arg3.", reset.Arg3); continue; } if (mobIndex.HasSpecFun("spec_cast_ghost") && (Database.SystemData.WeatherData.Sunlight > SunType.night) && (Database.SystemData.WeatherData.Sunlight < SunType.moonrise)) { last = false; continue; } level = Macros.Range(0, mobIndex.Level - 2, Limits.LEVEL_HERO); if (mobIndex.NumActive >= reset.Arg2) { last = false; break; } mobile = Database.CreateMobile(mobIndex); Room prev = GetRoom(room.IndexNumber - 1); if (prev && prev.HasFlag(ROOM_PET_SHOP)) { mobile.SetActionBit(MobTemplate.ACT_PET); } if (room.IsDark()) { mobile.SetAffectBit(Affect.AFFECT_INFRAVISION); } // Set following bit. Can't have a message sent because // there is no valid room number (causes a segmentation fault) CharData.AddFollowerWithoutMessage(mobile, lastMob); lastMob = mobile; mobile.AddToRoom(room); mobile.LoadRoomIndexNumber = room.IndexNumber; level = Macros.Range(0, mobile.Level - 2, Limits.LEVEL_HERO); last = true; break; case 'O': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'O': bad obj index number {0} for arg1.", reset.Arg1); continue; } room = GetRoom(reset.Arg3); if (!room) { Log.Error("RoomIndex.Reset(): 'O': bad room index number {0} for arg3.", reset.Arg3); continue; } if (Area.NumPlayers > 0 || room._contents.Count != 0 && (Object.CountObjectInList(objTemplate, room._contents) > 0)) { last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artiact obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(level)); if (obj != null) { obj.Cost = 0; obj.AddToRoom(this); last = true; } else { Log.Error("RoomIndex.Reset(): Unable to Database.CreateObject {0}", reset.Arg3); } break; case 'P': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'P': bad obj index number {0} for arg3.", reset.Arg1); continue; } ObjTemplate targetObjTemplate = Database.GetObjTemplate(reset.Arg3); if (!targetObjTemplate) { Log.Error("RoomIndex.Reset(): 'P': bad obj index number {0} for arg3.", reset.Arg3); continue; } if (Area.NumPlayers > 0 || !(lastObj = Object.GetFirstObjectOfTemplateType(targetObjTemplate)) || lastObj.Contains.Count != 0 && (Object.CountObjectInList(objTemplate, lastObj.Contains) > 0)) { last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artifact obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(lastObj.Level)); lastObj.AddToObject(obj); last = true; // Ensure that the container gets Reset. if ((lastObj.ItemType == ObjTemplate.ObjectType.container) || (lastObj.ItemType == ObjTemplate.ObjectType.drink_container)) { lastObj.Values[1] = lastObj.ObjIndexData.Values[1]; } break; case 'G': case 'E': if (notInitial != 0) { last = false; continue; } objTemplate = Database.GetObjTemplate(reset.Arg1); if (!objTemplate) { Log.Error("RoomIndex.Reset(): 'E' or 'G': bad obj index number {0} for arg1.", reset.Arg1); continue; } if (!last) { break; } if (!lastMob) { Log.Error("RoomIndex.Reset(): 'E' or 'G': null mob for index number {0} for arg1.", reset.Arg1); last = false; break; } // check if is unique/arti if (Database.IsArtifact(objTemplate.IndexNumber)) { text += "RoomIndex.Reset(): Artifact found: " + objTemplate.Name + " (" + objTemplate.IndexNumber + ")"; Log.Trace(text); } //end if artifact if (lastMob.MobileTemplate.ShopData) /* Shop-keeper? */ { int olevel; switch (objTemplate.ItemType) { default: olevel = 0; break; case ObjTemplate.ObjectType.pill: olevel = MUDMath.NumberRange(0, 10); break; case ObjTemplate.ObjectType.potion: olevel = MUDMath.NumberRange(0, 10); break; case ObjTemplate.ObjectType.scroll: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.wand: olevel = MUDMath.NumberRange(10, 20); break; case ObjTemplate.ObjectType.staff: olevel = MUDMath.NumberRange(15, 25); break; case ObjTemplate.ObjectType.armor: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.other: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.clothing: olevel = MUDMath.NumberRange(5, 15); break; case ObjTemplate.ObjectType.weapon: if (reset.Command == 'G') { olevel = MUDMath.NumberRange(5, 15); } else { olevel = MUDMath.FuzzyNumber(level); } break; } obj = Database.CreateObject(objTemplate, olevel); if (reset.Command == 'G') { obj.AddFlag(ObjTemplate.ITEM_INVENTORY); } } else { obj = Database.CreateObject(objTemplate, MUDMath.FuzzyNumber(level)); } obj.ObjToChar(lastMob); if (reset.Command == 'E') { lastMob.EquipObject(ref obj, (ObjTemplate.WearLocation)reset.Arg3); } last = true; break; case 'D': if (reset.Arg2 < 0 || reset.Arg2 >= Limits.MAX_DIRECTION || !(exit = ExitData[reset.Arg2]) || !exit.HasFlag(Exit.ExitFlag.is_door)) { Log.Error("RoomIndex.Reset(): 'D': exit {0} not door for arg2.", reset.Arg2); } switch (reset.Arg3) { default: Log.Error("RoomIndex.Reset(): 'D': bad 'locks': {0} for arg3.", reset.Arg3); break; case 0: break; case 1: exit.AddFlag(Exit.ExitFlag.closed); break; case 2: exit.AddFlag(Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 4: exit.AddFlag(Exit.ExitFlag.secret); break; case 5: exit.AddFlag(Exit.ExitFlag.secret | Exit.ExitFlag.closed); break; case 6: exit.AddFlag(Exit.ExitFlag.secret | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 8: exit.AddFlag(Exit.ExitFlag.blocked); break; case 9: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.closed); break; case 10: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; case 12: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret); break; case 13: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret | Exit.ExitFlag.closed); break; case 14: exit.AddFlag(Exit.ExitFlag.blocked | Exit.ExitFlag.secret | Exit.ExitFlag.closed | Exit.ExitFlag.locked); break; } break; case 'R': Log.Trace("Unsupported randomize room exits call. Please implement this."); break; } } return(true); }
/// <summary> /// Alert and dispatch the guards when an enemy has entered the area. /// </summary> /// <param name="ch"></param> static void StartInvasion(CharData ch) { SocketConnection socket; int count; CharData mob; string lbuf; // if there are no protector mobs, who cares if someone walks in. if (ch.InRoom.Area.DefenderTemplateNumber == 0 || ch.InRoom.Area.DefendersPerSquad == 0) { lbuf = String.Format("Start_invasion: no defender mobs"); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf); return; } // any town can only dispatch 5 batches of guards. if (ch.InRoom.Area.NumDefendersDispatched >= (ch.InRoom.Area.DefendersPerSquad * 5)) { // if( ch.in_room.area.dispatched >= (ch.in_room.area.defender_num * // ch.in_room.area.squads )) { lbuf = String.Format("Start_invasion: dispatched all defender mobs, disregarding"); ImmortalChat.SendImmortalChat(null, ImmortalChat.IMMTALK_SPAM, 0, lbuf); // return; } // warn of invasion foreach (SocketConnection it in Database.SocketList) { socket = it; if (socket.ConnectionStatus == SocketConnection.ConnectionState.playing && socket.Character.InRoom.Area == ch.InRoom.Area) { socket.Character.SendText("&+RYou hear the guards sound the invasion alarm!\r\n"); } } // create and dispatch defenders for (count = 0; count < ch.InRoom.Area.DefendersPerSquad; ++count) { if (ch.InRoom.Area.NumDefendersDispatched >= ch.InRoom.Area.DefendersPerSquad * 5) { break; } mob = Database.CreateMobile(Database.GetMobTemplate(ch.InRoom.Area.DefenderTemplateNumber)); mob.AddToRoom(Room.GetRoom(ch.InRoom.Area.BarracksRoom)); if (!mob.HasActionBit(MobTemplate.ACT_MEMORY)) { mob.SetActionBit(MobTemplate.ACT_MEMORY); } if (!mob.HasActionBit(MobTemplate.ACT_HUNTER)) { mob.SetActionBit(MobTemplate.ACT_HUNTER); } if (mob.HasActionBit(MobTemplate.ACT_SENTINEL)) { mob.RemoveActionBit(MobTemplate.ACT_SENTINEL); } mob.MobileTemplate.AddSpecFun("spec_justice_guard"); Combat.StartGrudge(mob, ch, false); ch.InRoom.Area.NumDefendersDispatched++; } ch.InRoom.Area.DefenderSquads++; return; }
/// <summary> /// Summoning an elemental. /// </summary> /// <param name="ch"></param> /// <param name="spell"></param> /// <param name="level"></param> /// <param name="indexNumber"></param> public static void SummonElem(CharData ch, Spell spell, int level, int indexNumber) { int numpets = 0; foreach (CharData petChar in Database.CharList) { if (petChar != ch && petChar.Master == ch && petChar.IsNPC() && petChar.HasActionBit(MobTemplate.ACT_PET)) { numpets++; } } //just a WAG as far as number...check for some consistency with necro int maxpets = ch.Level / 20 + ch.GetCurrCha() / 35; if (ch.Level >= Limits.LEVEL_AVATAR) { string text = String.Format("You can summon at most {0} pets.\r\n", maxpets); ch.SendText(text); } if (numpets >= maxpets) { ch.SendText("You cannot handle any more pets!\r\n"); return; } CharData elemental = Database.CreateMobile(Database.GetMobTemplate(indexNumber)); elemental.AddToRoom(ch.InRoom); elemental.SetCoins(0, 0, 0, 0); elemental.Level = 27 + MUDMath.Dice(2, 5); elemental.MaxHitpoints = 150 + MUDMath.Dice(16, level / 2); elemental.Hitpoints = elemental.MaxHitpoints; elemental.ArmorPoints -= (ch.Level * 3 / 2); elemental.SetActionBit(MobTemplate.ACT_NOEXP); switch (indexNumber) { case StaticMobs.MOB_NUMBER_EARTH_PECH: SocketConnection.Act("$n&n rises from the ground before your eyes.", elemental, null, null, SocketConnection.MessageTarget.room); break; case StaticMobs.MOB_NUMBER_AIR_SLYPH: elemental.ArmorPoints = -130; elemental.PermAgility = 100; SocketConnection.Act("$n&n appears out of thin air.", elemental, null, null, SocketConnection.MessageTarget.room); break; case StaticMobs.MOB_NUMBER_FIRE_SERPENT: SocketConnection.Act("$n&n bursts into existence in a roaring ball of flame.", elemental, null, null, SocketConnection.MessageTarget.room); break; case StaticMobs.MOB_NUMBER_WATER_NEREID: SocketConnection.Act("$n&n coalesces into existence.", elemental, null, null, SocketConnection.MessageTarget.room); elemental.MaxHitpoints += 100; elemental.Hitpoints = elemental.MaxHitpoints; break; default: Log.Error("SummonElem: bad indexNumber in switch: " + indexNumber); ch.SendText("You managed to summon a bad indexNumber! Shame on you.\r\n"); break; } SocketConnection.Act("$N&n says 'Your wish is my command $n&n.'", ch, null, elemental, SocketConnection.MessageTarget.room); SocketConnection.Act("$N&n tells you 'Your wish is my command.'", ch, null, elemental, SocketConnection.MessageTarget.character); CharData.AddFollower(elemental, ch); elemental.Master = ch; Affect af = new Affect(Affect.AffectType.spell, spell.Name, level / 2 + MUDMath.Dice(4, level / 2), Affect.Apply.none, 0, Affect.AFFECT_CHARM); elemental.AddAffect(af); // Set the MobIndex.ACT_PET bit as well elemental.SetActionBit(MobTemplate.ACT_PET); elemental.FlightLevel = ch.FlightLevel; if (ch.Fighting) { Combat.SetFighting(elemental, ch.Fighting); } return; }