public override void Load(int mapId) { if (Field.bPauseSpawn) { return; } var aMobInfo = new Dictionary <int, int>(); // mobId, mobCount var life = Field.Template.Life.Where(l => l.Type.EqualsIgnoreCase("m")).ToList(); if (life.Count <= 0) { return; // not a natural mob map } var bHasFlyMobs = false; var bHasNonBossMob = false; foreach (var mob in life) { var template = MasterManager.MobTemplates[mob.TemplateId]; if (template is null) { Log.Error($"null mob template {mob.TemplateId} in field {Field.MapId}"); continue; } var pmg = new MOBGEN { dwTemplateID = mob.TemplateId, X = mob.X, F = mob.F, tRegenInterval = mob.MobTime * 1000, }; if (mob.MobTime > 180) // seconds { bHasIntervalMobs = true; } if (template.MoveAbility == MobMoveType.Fly) { pmg.Y = mob.Y; pmg.FH = 0; } else { pmg.FH = mob.Foothold; pmg.Y = mob.CY; } if (pmg.tRegenInterval > 0) { var tBaseInterval = pmg.tRegenInterval / 10; var tRandAddedInterval = 6 * tBaseInterval + 1; // add one to eliminate DBZ exception pmg.tRegenAfter = DateTime.Now.AddMilliseconds(tBaseInterval + Constants.Rand.Next() % tRandAddedInterval); } aMobGen.Add(pmg); nInitMobGenCount += 1; if (template.MoveAbility == MobMoveType.Fly) { bHasFlyMobs = true; } if (!template.Boss) { bHasNonBossMob = true; } } // if (false) if (bHasNonBossMob && !bHasFlyMobs && Constants.CustomSpawn_Enabled && Field.Template.FieldType == 0 && !Field.IsInstanced) { foreach (var mob in aMobGen) { var pTemplate = MasterManager.MobTemplates[mob.dwTemplateID]; // we don't want to spawn bosses or standing mobs if (pTemplate.Boss || pTemplate.MoveAbility == MobMoveType.Stop) { continue; } if (aMobInfo.ContainsKey(mob.dwTemplateID)) { aMobInfo[mob.dwTemplateID] += 1; } else { aMobInfo.Add(mob.dwTemplateID, 1); } } GenerateSpawnPointsFromFH(aMobInfo); } nMobGenCount = nInitMobGenCount; TryCreateMob(true); }
public bool CreateMob(int dwTemplateID, MOBGEN pmg, int ptX, int ptY, int nFH, byte nAppearType, int dwOption, int nDir, MobType nMobType, Character c) { // TODO check control count and set null if control count >= 50 if (pmg != null && pmg.tRegenInterval < 0) { c = null; } else if (c is null) { c = Field.Users.Random(); // todo } var template = MasterManager.MobTemplates[dwTemplateID]; if (template != null) //&& c != null) // bms uses controller objects and checks for them to be non-null but we dont do that so.. { var mob = new CMob(dwTemplateID); mob.Init(pmg, nFH); MoveActionType nMoveAction; if (mob.Template.MoveAbility == MobMoveType.Fly) { nMoveAction = MoveActionType.MA_FLY1; } else { nMoveAction = mob.Template.MoveAbility == MobMoveType.Stop ? MoveActionType.MA_STAND : MoveActionType.MA_MOVE; } mob.SetMovePos(ptX, ptY, nDir & 1 | 2 * (int)nMoveAction, nFH); if (nMobType == MobType.SubMob) { if (m_nSubMobCount < 0) { m_nSubMobCount = 1; } else { m_nSubMobCount += 1; } } if (nAppearType == 0) { nAppearType = 0xFE; // regular animation } mob.m_nMobType = nMobType; mob.m_nSummonType = nAppearType; // theres an enum for this but the values can be outside of the enum so we skip using it mob.m_dwSummonOption = dwOption; Add(mob); // add to pool, assign field and id if (mob.m_nSummonType != 0xFC) // suspended { mob.m_nSummonType = 0xFF; // normal mob.m_dwSummonOption = 0; } // controller has to be set after mob has been inserted in pool mob.SetController(c, MobCtrlType.Active_Int); mob.BroadcastHP(); // sends boss hp bar if (Field.nVelocityControllerdwId > 0 && !mob.Template.Boss) { var user = Field.Users[Field.nVelocityControllerdwId]; if (user != null) { var skill = user.Skills.Get((int)Skills.MECHANIC_VELOCITY_CONTROLER); mob.TryApplySkillDamageStatus(user, skill.nSkillID, skill.nSLV, 0); } } return(true); } return(false); }