/// <summary> /// Creates a new djinn. /// </summary> public AncientBoundDjinn(DjinnStone djinnStone) : base() { NpcTemplate npcTemplate = NpcTemplateMgr.GetTemplate(NpcTemplateId); if (npcTemplate == null) { throw new ArgumentNullException("Can't find NPC template for ancient bound djinn"); } LoadTemplate(npcTemplate); CurrentRegion = djinnStone.CurrentRegion; Heading = djinnStone.Heading; Realm = eRealm.None; Flags ^= GameNPC.eFlags.FLYING | GameNPC.eFlags.PEACE; Position = djinnStone.Position + Vector3.UnitZ * HoverHeight; base.Size = Size; }
/// <summary> /// Create an add from the specified template. /// </summary> /// <param name="templateID"></param> /// <param name="level"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="uptime"></param> /// <returns></returns> protected GameNPC SpawnTimedAdd(int templateID, int level, int x, int y, int uptime, bool isRetriever) { GameNPC add = null; try { if (m_addTemplate == null || m_addTemplate.TemplateId != templateID) { m_addTemplate = NpcTemplateMgr.GetTemplate(templateID); } // Create add from template. // The add will automatically despawn after 30 seconds. if (m_addTemplate != null) { add = new GameNPC(m_addTemplate); if (isRetriever) { add.SetOwnBrain(new RetrieverMobBrain()); } add.CurrentRegion = CurrentRegion; add.Heading = (ushort)Util.Random(0, 4095); add.Realm = 0; add.X = x; add.Y = y; add.Z = Z; add.CurrentSpeed = 0; add.Level = (byte)level; add.RespawnInterval = -1; add.AddToWorld(); new DespawnTimer(this, add, uptime * 1000); } } catch { log.Warn(string.Format("Unable to get template for {0}", Name)); } return(add); }
/// <summary> /// Called when the living is about to get an item from someone /// else /// </summary> /// <param name="source">Source from where to get the item</param> /// <param name="item">Item to get</param> /// <returns>true if the item was successfully received</returns> public override bool ReceiveItem(GameLiving source, InventoryItem item) { if (source == null || item == null) { return(false); } if (source is GamePlayer) { GamePlayer player = (GamePlayer)source; if (item.Item_Type == 40 && isItemInMerchantList(item)) { PathPoint path = MovementMgr.LoadPath(item.Id_nb); if ((path != null) && ((Math.Abs(path.X - this.X)) < 500) && ((Math.Abs(path.Y - this.Y)) < 500)) { player.Inventory.RemoveCountFromStack(item, 1); InventoryLogging.LogInventoryAction(player, this, eInventoryActionType.Merchant, item.Template); GameTaxi mount; // item.Color of ticket is used for npctemplate. defaults to standard horse if item.color is 0 if (item.Color > 0) { mount = new GameTaxi(NpcTemplateMgr.GetTemplate(item.Color)); } else { mount = new GameTaxi(); foreach (GameNPC npc in GetNPCsInRadius(400)) { if (npc.Name == LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE, "GameStableMaster.ReceiveItem.HorseName")) { mount.Model = npc.Model; mount.Name = npc.Name; break; } } } switch ((eRace)player.Race) { case eRace.Lurikeen: mount.Size = 31; break; case eRace.Kobold: mount.Size = 38; break; case eRace.Dwarf: mount.Size = 42; break; case eRace.Inconnu: mount.Size = 45; break; case eRace.Frostalf: case eRace.Shar: mount.Size = 48; break; case eRace.Briton: case eRace.Saracen: case eRace.Celt: mount.Size = 50; break; case eRace.Valkyn: mount.Size = 52; break; case eRace.Avalonian: case eRace.Highlander: case eRace.Norseman: case eRace.Elf: case eRace.Sylvan: mount.Size = 55; break; case eRace.Firbolg: mount.Size = 62; break; case eRace.HalfOgre: case eRace.AlbionMinotaur: case eRace.MidgardMinotaur: case eRace.HiberniaMinotaur: mount.Size = 65; break; case eRace.Troll: mount.Size = 67; break; default: mount.Size = 55; break; } mount.Realm = source.Realm; mount.X = path.X; mount.Y = path.Y; mount.Z = path.Z; mount.CurrentRegion = CurrentRegion; mount.Heading = path.GetHeading(path.Next); mount.AddToWorld(); mount.CurrentWayPoint = path; GameEventMgr.AddHandler(mount, GameNPCEvent.PathMoveEnds, new DOLEventHandler(OnHorseAtPathEnd)); new MountHorseAction(player, mount).Start(400); new HorseRideAction(mount).Start(4000); return(true); } } else { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "GameStableMaster.Receive.UnknownWay"), eChatType.CT_System, eChatLoc.CL_SystemWindow); } } return(false); }
/// <summary> /// Loads elements relating to the given instance keyname from the database and populates the instance. /// </summary> /// <param name="instanceName"></param> public virtual void LoadFromDatabase(string instanceName) { var objects = GameServer.Database.SelectObjects <DBInstanceXElement>("`InstanceID` = @InstanceID", new QueryParameter("@InstanceID", instanceName)); if (objects.Count == 0) { return; } int count = 0; //Now we have a list of DBElements, lets create the various entries //associated with them and populate the instance. foreach (DBInstanceXElement entry in objects) { if (entry == null) { continue; //an odd error, but experience knows best. } GameObject obj = null; string theType = "DOL.GS.GameNPC"; //Switch the classtype to see what we are making. switch (entry.ClassType) { case "entrance": { //create the entrance, then move to the next. m_entranceLocation = new GameLocation(instanceName + "entranceRegion" + ID, ID, entry.X, entry.Y, entry.Z, entry.Heading); //move to the next entry, nothing more to do here... continue; } case "region": continue; //This is used to save the regionID as NPCTemplate. case "DOL.GS.GameNPC": break; default: theType = entry.ClassType; break; } //Now we have the classtype to create, create it thus! //This is required to ensure we check scripts for the space aswell, such as quests! foreach (Assembly asm in ScriptMgr.GameServerScripts) { obj = (GameObject)(asm.CreateInstance(theType, false)); if (obj != null) { break; } } if (obj == null) { continue; } //We now have an object that isnt null. Lets place it at the location, in this region. obj.X = entry.X; obj.Y = entry.Y; obj.Z = entry.Z; obj.Heading = entry.Heading; obj.CurrentRegionID = ID; //If its an npc, load from the npc template about now. //By default, we ignore npctemplate if its set to 0. if ((GameNPC)obj != null && !Util.IsEmpty(entry.NPCTemplate, true)) { var listTemplate = Util.SplitCSV(entry.NPCTemplate, true); int template = 0; if (int.TryParse(listTemplate[Util.Random(listTemplate.Count - 1)], out template) && template > 0) { INpcTemplate npcTemplate = NpcTemplateMgr.GetTemplate(template); //we only want to load the template if one actually exists, or there could be trouble! if (npcTemplate != null) { ((GameNPC)obj).LoadTemplate(npcTemplate); } } } //Finally, add it to the world! obj.AddToWorld(); //Keep track of numbers. count++; } log.Info("Successfully loaded a db entry to " + Description + " - Region ID " + ID + ". Loaded Entities: " + count); }
/// <summary> /// Load from Database override to clone objects from original Region. /// Loads Objects, Mobs, Areas from Database using "SkinID" /// </summary> public override void LoadFromDatabase(Mob[] mobObjs, ref long mobCount, ref long merchantCount, ref long itemCount, ref long bindCount) { if (!LoadObjects) { return; } Assembly gasm = Assembly.GetAssembly(typeof(GameServer)); var staticObjs = GameServer.Database.SelectObjects <WorldObject>("`Region` = @Region", new QueryParameter("@Region", Skin)); var areaObjs = GameServer.Database.SelectObjects <DBArea>("`Region` = @Region", new QueryParameter("@Region", Skin)); int count = mobObjs.Length + staticObjs.Count; if (count > 0) { PreAllocateRegionSpace(count + 100); } int myItemCount = staticObjs.Count; int myMobCount = 0; int myMerchantCount = 0; string allErrors = string.Empty; if (mobObjs.Length > 0) { foreach (Mob mob in mobObjs) { GameNPC myMob = null; string error = string.Empty; // Default Classtype string classtype = ServerProperties.Properties.GAMENPC_DEFAULT_CLASSTYPE; // load template if any INpcTemplate template = null; if (mob.NPCTemplateID != -1) { template = NpcTemplateMgr.GetTemplate(mob.NPCTemplateID); } if (mob.Guild.Length > 0 && mob.Realm >= 0 && mob.Realm <= (int)eRealm._Last) { Type type = ScriptMgr.FindNPCGuildScriptClass(mob.Guild, (eRealm)mob.Realm); if (type != null) { try { myMob = (GameNPC)type.Assembly.CreateInstance(type.FullName); } catch (Exception e) { if (log.IsErrorEnabled) { log.Error("LoadFromDatabase", e); } } } } if (myMob == null) { if (template != null && template.ClassType != null && template.ClassType.Length > 0 && template.ClassType != Mob.DEFAULT_NPC_CLASSTYPE && template.ReplaceMobValues) { classtype = template.ClassType; } else if (!string.IsNullOrWhiteSpace(mob.ClassType) && mob.ClassType != Mob.DEFAULT_NPC_CLASSTYPE) { classtype = mob.ClassType; } try { myMob = (GameNPC)gasm.CreateInstance(classtype, false); } catch { error = classtype; } if (myMob == null) { foreach (Assembly asm in ScriptMgr.Scripts) { try { myMob = (GameNPC)asm.CreateInstance(classtype, false); error = string.Empty; } catch { error = classtype; } if (myMob != null) { break; } } if (myMob == null) { myMob = new GameNPC(); error = classtype; } } } if (!allErrors.Contains(error)) { allErrors += $" {error},"; } if (myMob != null) { try { Mob clone = (Mob)mob.Clone(); clone.AllowAdd = false; clone.AllowDelete = false; clone.Region = ID; myMob.LoadFromDatabase(clone); if (myMob is GameMerchant) { myMerchantCount++; } else { myMobCount++; } } catch (Exception e) { if (log.IsErrorEnabled) { log.Error($"Failed: {myMob.GetType().FullName}:LoadFromDatabase({mob.GetType().FullName});", e); } throw; } myMob.AddToWorld(); } } } if (staticObjs.Count > 0) { foreach (WorldObject item in staticObjs) { WorldObject itemclone = (WorldObject)item.Clone(); itemclone.AllowAdd = false; itemclone.AllowDelete = false; itemclone.Region = ID; GameStaticItem myItem; if (!string.IsNullOrEmpty(itemclone.ClassType)) { myItem = gasm.CreateInstance(itemclone.ClassType, false) as GameStaticItem; if (myItem == null) { foreach (Assembly asm in ScriptMgr.Scripts) { try { myItem = (GameStaticItem)asm.CreateInstance(itemclone.ClassType, false); } catch { } if (myItem != null) { break; } } if (myItem == null) { myItem = new GameStaticItem(); } } } else { myItem = new GameStaticItem(); } myItem.AddToWorld(); } } int areaCnt = 0; // Add missing area foreach (DBArea area in areaObjs) { // Don't bind in instance. if (area.ClassType.Equals("DOL.GS.Area+BindArea")) { continue; } // clone DB object. DBArea newDBArea = (DBArea)area.Clone(); newDBArea.AllowAdd = false; newDBArea.Region = ID; // Instantiate Area with cloned DB object and add to region try { AbstractArea newArea = (AbstractArea)gasm.CreateInstance(newDBArea.ClassType, false); newArea.LoadFromDatabase(newDBArea); newArea.Sound = newDBArea.Sound; newArea.CanBroadcast = newDBArea.CanBroadcast; newArea.CheckLOS = newDBArea.CheckLOS; AddArea(newArea); areaCnt++; } catch { log.Warn($"area type {area.ClassType} cannot be created, skipping"); continue; } } if (myMobCount + myItemCount + myMerchantCount > 0) { if (log.IsInfoEnabled) { log.Info($"AdventureWingInstance: {Description} ({ID}) loaded {myMobCount} mobs, {myMerchantCount} merchants, {myItemCount} items, {areaCnt}/{areaObjs.Count} areas from DB ({TimeManager.Name})"); } log.Debug($"Used Memory: {GC.GetTotalMemory(false) / 1024 / 1024}MB"); if (allErrors != string.Empty) { log.Error($"Error loading the following NPC ClassType(s), GameNPC used instead:{allErrors.TrimEnd(',')}"); } Thread.Sleep(0); // give up remaining thread time to other resources } mobCount += myMobCount; merchantCount += myMerchantCount; itemCount += myItemCount; }