public List<MabiCreature> GetIceSpearLOSChain(MabiCreature attacker, MabiCreature target, uint range) { var aPos = attacker.GetPosition(); var tPos = target.GetPosition(); var minX = Math.Min(aPos.X, tPos.X) - range; var maxX = Math.Max(aPos.X, tPos.X) + range; var m = ((double)tPos.Y - aPos.Y) / ((double)tPos.X - aPos.X); var bL = (double)aPos.Y - aPos.X * m - (range / 2); var bH = bL + range; var targets = WorldManager.Instance.GetCreaturesInRange(attacker, maxX - minX); // Rough filter targets = targets.FindAll((c) => { var pos = c.GetPosition(); return !c.IsDead && c.IsAttackableBy(attacker) && (minX < pos.X && pos.X < maxX) && ((m * pos.X + bL) < pos.Y && pos.Y < (m * pos.X + bH)); }); if (!targets.Contains(target)) targets.Add(target); return targets; }
public void OnCreatureKilled(MabiCreature victim, MabiCreature killer) { if((victim is MabiPC && players) || (victim is MabiNPC && npcs)) { var pos = victim.GetPosition(); var prop = new MabiProp(50, victim.Region, pos.X, pos.Y, (float)Math.PI * 2 / 255 * victim.Direction); if(!permanent) prop.DisappearTime = DateTime.Now.AddMinutes(duration); WorldManager.Instance.AddProp(prop); } }
public override SkillResults Start(MabiCreature creature, MabiSkill skill) { creature.Activate(CreatureConditionB.Demigod); creature.StopMove(); // Spawn eruption { var pos = creature.GetPosition(); var targets = WorldManager.Instance.GetAttackableCreaturesInRange(creature, EruptionRadius); var cap = new CombatActionPack(creature, skill.Id); var aAction = new AttackerAction(CombatActionType.SpecialHit, creature, skill.Id, SkillHelper.GetAreaTargetID(creature.Region, pos.X, pos.Y)); aAction.Options |= AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect; cap.Add(aAction); foreach (var target in targets) { target.StopMove(); // Officials use CM skill id. var tAction = new TargetAction(CombatActionType.TakeHit, target, creature, skill.Id); tAction.StunTime = EruptionStun; tAction.Delay = 1000; // Supposedly it's magic damage tAction.Damage = creature.GetMagicDamage(null, EruptionDamage); target.TakeDamage(tAction.Damage); tAction.OldPosition = CombatHelper.KnockBack(target, creature, EruptionKnockBack); if (target.IsDead) tAction.Options |= TargetOptions.FinishingKnockDown; cap.Add(tAction); } WorldManager.Instance.HandleCombatActionPack(cap); } Send.EffectDelayed(Effect.AwakeningOfLight1, 800, creature); Send.EffectDelayed(Effect.AwakeningOfLight2, 800, creature); Send.UseMotion(creature, 67, 3, false, false); creature.StatRegens.Add(creature.Temp.DemiHpRegen = new MabiStatRegen(Stat.Life, skill.RankInfo.Var3, creature.LifeMax)); creature.StatRegens.Add(creature.Temp.DemiMpRegen = new MabiStatRegen(Stat.Mana, skill.RankInfo.Var4, creature.ManaMax)); creature.StatRegens.Add(creature.Temp.DemiStmRegen = new MabiStatRegen(Stat.Stamina, skill.RankInfo.Var5, creature.StaminaMax)); WorldManager.Instance.CreatureStatsUpdate(creature); return SkillResults.Okay; }
public override SkillResults Start(MabiCreature creature, MabiSkill skill, MabiTags tags) { ulong chairOId = 0; if (tags.Has("ITEMID")) chairOId = (ulong)tags.Get("ITEMID"); if (chairOId > 0) { // Check item var item = creature.GetItem(chairOId); if (item != null && item.Type == ItemType.Misc) { // Get chair prop id var propId = 0u; var chairInfo = MabiData.ChairDb.Find(item.Info.Class); if (chairInfo != null) propId = (!creature.IsGiant ? chairInfo.PropId : chairInfo.GiantPropId); var pos = creature.GetPosition(); // Effect if (chairInfo.Effect != 0) Send.Effect(chairInfo.Effect, creature, true); // Chair prop var prop = new MabiProp(propId, creature.Region, pos.X, pos.Y, MabiMath.DirToRad(creature.Direction)); prop.State = "stand"; WorldManager.Instance.AddProp(prop); // Move char Send.AssignChair(creature, prop.Id, 1); // Update chair prop.ExtraData = string.Format("<xml OWNER='{0}' SITCHAR='{0}'/>", creature.Id); Send.PropUpdate(prop); creature.Temp.CurrentChair = chairInfo; creature.Temp.SittingProp = prop; } } creature.State |= CreatureStates.SitDown; Send.SitDown(creature); SkillHelper.GiveSkillExp(creature, skill, 20); return SkillResults.Okay; }
private CommandResult Command_spawn(WorldClient client, MabiCreature creature, string[] args, string msg) { if (args.Length < 2) return CommandResult.WrongParameter; uint raceId = 0; if (!uint.TryParse(args[1], out raceId)) return CommandResult.Fail; byte amount = 1; if (args.Length > 2) { if (!byte.TryParse(args[2], out amount)) return CommandResult.Fail; if (amount < 1) amount = 1; else if (amount > 100) amount = 100; } uint radius = 300; radius += (uint)(amount / 10 * 50); WorldManager.Instance.SpawnCreature(raceId, amount, creature.Region, creature.GetPosition(), radius, true); return CommandResult.Okay; }
/// <summary> /// Test. Combination of public and private creature data. /// </summary> /// <param name="packet"></param> /// <param name="creature"></param> /// <param name="type"></param> public static void AddCreatureInfo(this MabiPacket packet, MabiCreature creature, CreaturePacketType type) { // Check for MabiPC for private data. var character = creature as MabiPC; if (type == CreaturePacketType.Private && character == null) throw new Exception("MabiPC required for private creature packet."); // Get incomplete quests only once, if we need them. IEnumerable<MabiQuest> incompleteQuests = null; int incompleteQuestsCount = 0; if (type == CreaturePacketType.Private && character != null) { incompleteQuests = character.Quests.Values.Where(quest => quest.State < MabiQuestState.Complete); incompleteQuestsCount = incompleteQuests.Count(); } var loc = creature.GetPosition(); // Start // -------------------------------------------------------------- packet.PutLong(creature.Id); packet.PutByte((byte)type); // Looks/Location // -------------------------------------------------------------- packet.PutString(creature.Name); packet.PutString(""); // Title packet.PutString(""); // Eng Title packet.PutInt(creature.Race); packet.PutByte(creature.SkinColor); packet.PutByte(creature.EyeType); packet.PutByte(creature.EyeColor); packet.PutByte(creature.Mouth); packet.PutInt((uint)creature.State); if (type == CreaturePacketType.Public) { packet.PutInt((uint)creature.StateEx); // [180300, NA166 (18.09.2013) { packet.PutInt(0); } } packet.PutFloat(creature.Height); packet.PutFloat(creature.Weight); packet.PutFloat(creature.Upper); packet.PutFloat(creature.Lower); packet.PutInt(creature.Region); packet.PutInt(loc.X); packet.PutInt(loc.Y); packet.PutByte(creature.Direction); packet.PutInt(creature.BattleState); packet.PutByte((byte)creature.Inventory.WeaponSet); packet.PutInt(creature.Color1); packet.PutInt(creature.Color2); packet.PutInt(creature.Color3); // Stats // -------------------------------------------------------------- packet.PutFloat(creature.CombatPower); packet.PutString(creature.StandStyle); if (type == CreaturePacketType.Private) { packet.PutFloat(creature.Life); packet.PutFloat(creature.LifeInjured); packet.PutFloat(creature.LifeMaxBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.LifeMaxMod)); packet.PutFloat(creature.Mana); packet.PutFloat(creature.ManaMaxBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.ManaMaxMod)); packet.PutFloat(creature.Stamina); packet.PutFloat(creature.StaminaMaxBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.StaminaMaxMod)); packet.PutFloat(creature.StaminaHunger); packet.PutFloat(0.5f); packet.PutShort(creature.Level); packet.PutInt(creature.LevelTotal); packet.PutShort(0); // Max Level packet.PutShort(0); // Rebirthes packet.PutShort(0); packet.PutLong(MabiData.ExpDb.CalculateRemaining(creature.Level, creature.Experience) * 1000); packet.PutShort(creature.Age); packet.PutFloat(creature.StrBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.StrMod)); packet.PutFloat(creature.DexBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.DexMod)); packet.PutFloat(creature.IntBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.IntMod)); packet.PutFloat(creature.WillBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.WillMod)); packet.PutFloat(creature.LuckBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.LuckMod)); packet.PutFloat(0); // LifeMaxByFood packet.PutFloat(0); // ManaMaxByFood packet.PutFloat(0); // StaminaMaxByFood packet.PutFloat(0); // StrengthByFood packet.PutFloat(0); // DexterityByFood packet.PutFloat(0); // IntelligenceByFood packet.PutFloat(0); // WillByFood packet.PutFloat(0); // LuckByFood packet.PutShort(creature.AbilityPoints); packet.PutShort(0); // AttackMinBase packet.PutShort(0); // AttackMinMod packet.PutShort(0); // AttackMaxBase packet.PutShort(0); // AttackMaxMod packet.PutShort(0); // WAttackMinBase packet.PutShort(0); // WAttackMinMod packet.PutShort(0); // WAttackMaxBase packet.PutShort(0); // WAttackMaxMod packet.PutShort(0); // LeftAttackMinMod packet.PutShort(0); // LeftAttackMaxMod packet.PutShort(0); // RightAttackMinMod packet.PutShort(0); // RightAttackMaxMod packet.PutShort(0); // LeftWAttackMinMod packet.PutShort(0); // LeftWAttackMaxMod packet.PutShort(0); // RightWAttackMinMod packet.PutShort(0); // RightWAttackMaxMod packet.PutFloat(0); // LeftCriticalMod packet.PutFloat(0); // RightCriticalMod packet.PutShort(0); // LeftRateMod packet.PutShort(0); // RightRateMod packet.PutFloat(0); // MagicDefenseMod // [180300, NA166 (18.09.2013)] New creature info { packet.PutFloat(0); // MagicProtectMod } packet.PutFloat(0); // MagicAttackMod packet.PutShort(15); // MeleeAttackRateMod packet.PutShort(15); // RangeAttackRateMod packet.PutFloat(0); // CriticalBase packet.PutFloat(0); // CriticalMod packet.PutFloat(0); // ProtectBase packet.PutFloat(creature.StatMods.GetMod(Stat.ProtectMod)); // ProtectMod packet.PutShort(0); // DefenseBase packet.PutShort((ushort)creature.StatMods.GetMod(Stat.DefenseMod)); // DefenseMod packet.PutShort(0); // RateBase packet.PutShort(0); // RateMod packet.PutShort(0); // Rank1 packet.PutShort(0); // Rank2 // [180300, NA166 (18.09.2013)] New creature info { // From a KR log I had float here, NA has a short... my mistake? packet.PutShort(0); // ArmorPierceMod } packet.PutLong(0); // Score packet.PutShort(0); // AttackMinBaseMod packet.PutShort(8); // AttackMaxBaseMod packet.PutShort(0); // WAttackMinBaseMod packet.PutShort(0); // WAttackMaxBaseMod packet.PutFloat(10); // CriticalBaseMod packet.PutFloat(creature.ProtectionPassive * 100); // ProtectBaseMod packet.PutShort((ushort)creature.DefensePassive); // DefenseBaseMod packet.PutShort(30); // RateBaseMod packet.PutShort(8); // MeleeAttackMinBaseMod packet.PutShort(18); // MeleeAttackMaxBaseMod packet.PutShort(0); // MeleeWAttackMinBaseMod packet.PutShort(0); // MeleeWAttackMaxBaseMod packet.PutShort(10); // RangeAttackMinBaseMod packet.PutShort(25); // RangeAttackMaxBaseMod packet.PutShort(0); // RangeWAttackMinBaseMod packet.PutShort(0); // RangeWAttackMaxBaseMod // [180100] New poison info? { packet.PutShort(0); // DualgunAttackMinBaseMod packet.PutShort(0); // DualgunAttackMaxBaseMod packet.PutShort(0); // DualgunWAttackMinBaseMod packet.PutShort(0); // DualgunWAttackMaxBaseMod } packet.PutShort(0); // PoisonBase packet.PutShort(0); // PoisonMod packet.PutShort(67); // PoisonImmuneBase packet.PutShort(0); // PoisonImmuneMod packet.PutFloat(0.5f); // PoisonDamageRatio1 packet.PutFloat(0); // PoisonDamageRatio2 packet.PutFloat(0); // toxicStr packet.PutFloat(0); // toxicInt packet.PutFloat(0); // toxicDex packet.PutFloat(0); // toxicWill packet.PutFloat(0); // toxicLuck packet.PutString("Uladh_main/town_TirChonaill/TirChonaill_Spawn_A"); // Last town packet.PutShort(1); // ExploLevel packet.PutShort(0); // ExploMaxKeyLevel packet.PutInt(0); // ExploCumLevel packet.PutLong(0); // ExploExp packet.PutInt(0); // DiscoverCount packet.PutFloat(0); // conditionStr packet.PutFloat(0); // conditionInt packet.PutFloat(0); // conditionDex packet.PutFloat(0); // conditionWill packet.PutFloat(0); // conditionLuck packet.PutByte(9); // ElementPhysical packet.PutByte(0); // ElementLightning packet.PutByte(0); // ElementFire packet.PutByte(0); // ElementIce packet.PutInt((uint)creature.StatRegens.Count); foreach (var mod in creature.StatRegens) mod.AddToPacket(packet); } else if (type == CreaturePacketType.Public || type == CreaturePacketType.Minimal) { packet.PutFloat(creature.Life); packet.PutFloat(creature.LifeMaxBaseTotal); packet.PutFloat(creature.StatMods.GetMod(Stat.LifeMaxMod)); packet.PutFloat(creature.LifeInjured); packet.PutInt((uint)creature.StatRegens.Count); foreach (var mod in creature.StatRegens) mod.AddToPacket(packet); // Another 6 elements list? packet.PutInt(0); } // Titles // -------------------------------------------------------------- packet.PutShort(creature.Title); packet.PutLong(creature.TitleApplied); if (type == CreaturePacketType.Private) { // List of available titles packet.PutShort((ushort)character.Titles.Count); foreach (var title in character.Titles) { packet.PutShort(title.Key); packet.PutByte(title.Value); packet.PutInt(0); } } if (type == CreaturePacketType.Private || type == CreaturePacketType.Public) { packet.PutShort(creature.OptionTitle); } // Items and expiring? (Last part of minimal) // -------------------------------------------------------------- if (type == CreaturePacketType.Minimal) { packet.PutString(""); packet.PutByte(0); var items = creature.Inventory.Equipment; packet.PutSInt(items.Count()); foreach (var item in items) { packet.PutLong(item.Id); packet.PutBin(item.Info); } packet.PutInt(0); // PetRemainingTime packet.PutLong(0); // PetLastTime packet.PutLong(0); // PetExpireTime return; } // Mate // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutLong(0); // MateID packet.PutString(""); // MateName packet.PutLong(0); // MarriageTime packet.PutShort(0); // MarriageCount } else if (type == CreaturePacketType.Public) { packet.PutString(""); // MateName } // Destiny // -------------------------------------------------------------- packet.PutByte(0); // (0:Venturer, 1:Knight, 2:Wizard, 3:Bard, 4:Merchant, 5:Alchemist) // Inventory // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutInt(creature.RaceInfo.InvWidth); packet.PutInt(creature.RaceInfo.InvHeight); // A little dirty, but better than actually saving and managing // the quest items imo... [exec] var items = creature.Inventory.Items; packet.PutSInt(items.Count() + incompleteQuestsCount); foreach (var item in items) packet.AddItemInfo(item, ItemPacketType.Private); foreach (var quest in incompleteQuests) packet.AddItemInfo(new MabiItem(quest), ItemPacketType.Private); } else if (type == CreaturePacketType.Public) { var items = creature.Inventory.Equipment; packet.PutSInt(items.Count()); foreach (var item in items) { packet.PutLong(item.Id); packet.PutBin(item.Info); } } // [180300, NA169 (23.10.2013)] ? // Strange one, it's in the logs, but stucks the char in // casting animation. Dependent on something? // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { //packet.PutInt(2); // Count? //packet.PutInt(36); //packet.PutInt(8); //packet.PutInt(38); //packet.PutInt(4); } // Keywords // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutShort((ushort)character.Keywords.Count); foreach (var keyword in character.Keywords) { packet.PutShort(keyword); } } // Skills // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutShort((ushort)creature.Skills.Count); foreach (var skill in creature.Skills.List.Values) packet.PutBin(skill.Info); packet.PutInt(0); // SkillVarBufferList // loop // packet.PutInt // packet.PutFloat } else if (type == CreaturePacketType.Public) { packet.PutShort(0); // CurrentSkill packet.PutByte(0); // SkillStackCount packet.PutInt(0); // SkillProgress packet.PutInt(0); // SkillSyncList // loop // packet.PutShort // packet.PutShort } // [150100] ? { packet.PutByte(0); // {PLGCNT} } // Party // -------------------------------------------------------------- if (creature.Party != null) { packet.PutByte(creature.Party.IsOpen && creature.Party.Leader == creature); packet.PutString(creature.Party.GetMemberWantedString()); } else { packet.PutByte(0); packet.PutString(""); } // PvP // -------------------------------------------------------------- packet.AddPvPInfo(creature); // Statuses // -------------------------------------------------------------- packet.PutLong((ulong)creature.Conditions.A); packet.PutLong((ulong)creature.Conditions.B); packet.PutLong((ulong)creature.Conditions.C); // [150100] New conditions list { packet.PutLong((ulong)creature.Conditions.D); } // [180300, NA169 (23.10.2013)] New conditions list? { packet.PutLong(0); } packet.PutInt(0); // condition event message list // loop // packet.PutInt // packet.PutString // [180100] Zero Talent { packet.PutLong(0); } // Guild // -------------------------------------------------------------- if (creature.Guild != null) { packet.PutLong(creature.Guild.Id); packet.PutString(creature.Guild.Name); packet.PutInt((uint)creature.GuildMember.MemberRank); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutInt(0); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutString(creature.Guild.Title); } else { packet.PutLong(0); packet.PutString(""); packet.PutInt(0); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutInt(0); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutByte(0); packet.PutString(""); } // PTJ // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutLong(0); // ArbeitID packet.PutInt(0); // ArbeitRecordList // loop // packet.PutShort // packet.PutShort // packet.PutShort } // Follower // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { if (creature.Owner != null) { packet.PutLong(creature.Owner.Id); packet.PutByte(2); // Type (1:RPCharacter, 2:Pet, 3:Transport, 4:PartnerVehicle) packet.PutByte(0); // SubType } else { packet.PutLong(0); packet.PutByte(0); packet.PutByte(0); } } // [170100] ? // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutFloat(1); packet.PutLong(0); } // Transformation // -------------------------------------------------------------- packet.PutByte(0); // Type (1:Paladin, 2:DarkKnight, 3:SubraceTransformed, 4:TransformedElf, 5:TransformedGiant) packet.PutShort(0); // Level packet.PutShort(0); // SubType // Pet // -------------------------------------------------------------- if (creature.Owner != null) { packet.PutString(creature.Owner.Name); if (type == CreaturePacketType.Private) { packet.PutInt(2000000000); // RemainingSummonTime packet.PutLong(0); // LastSummonTime packet.PutLong(0); // PetExpireTime packet.PutByte(0); // Loyalty packet.PutByte(0); // Favor packet.PutLong(DateTime.Now); // SummonTime packet.PutByte(0); // KeepingMode packet.PutLong(0); // KeepingProp packet.PutLong(creature.Owner.Id); packet.PutByte(0); // PetSealCount {PSCNT} } else if (type == CreaturePacketType.Public) { packet.PutLong(creature.Owner.Id); packet.PutByte(0); // KeepingMode packet.PutLong(0); // KeepingProp } } else { packet.PutString(""); if (type == CreaturePacketType.Private) { packet.PutInt(0); packet.PutLong(0); packet.PutLong(0); packet.PutByte(0); packet.PutByte(0); packet.PutLong(0); packet.PutByte(0); packet.PutLong(0); packet.PutLong(0); packet.PutByte(0); } else if (type == CreaturePacketType.Public) { packet.PutLong(0); packet.PutByte(0); packet.PutLong(0); } } // House // -------------------------------------------------------------- if (type == CreaturePacketType.Private) packet.PutLong(0); // HouseID // Taming // -------------------------------------------------------------- packet.PutLong(0); // MasterID packet.PutByte(0); // IsTamed packet.PutByte(0); // TamedType (1:DarkKnightTamed, 2:InstrumentTamed, 3:AnimalTraining, 4:MercenaryTamed, 5:Recalled, 6:SoulStoneTamed, 7:TamedFriend) packet.PutByte(1); // IsMasterMode packet.PutInt(0); // LimitTime // Vehicle // -------------------------------------------------------------- packet.PutInt(0); // Type packet.PutInt(0); // TypeFlag (0x1:Driver, 0x4:Owner) packet.PutLong(0); // VehicleId packet.PutInt(0); // SeatIndex packet.PutByte(0); // PassengerList // loop // packet.PutLong // Showdown // -------------------------------------------------------------- packet.PutInt(0); // unknown at 0x18 packet.PutLong(0); // unknown at 0x08 packet.PutLong(0); // unknown at 0x10 packet.PutByte(1); // IsPartyPvpDropout // Transport // -------------------------------------------------------------- packet.PutLong(0); // TransportID packet.PutInt(0); // HuntPoint // Aviation // -------------------------------------------------------------- packet.PutByte(creature.IsFlying); if (creature.IsFlying) { var pos = creature.GetPosition(); packet.PutFloat(pos.X); packet.PutFloat(pos.H); packet.PutFloat(pos.Y); packet.PutFloat(creature.Destination.X); packet.PutFloat(creature.Destination.H); packet.PutFloat(creature.Destination.Y); packet.PutFloat(creature.Direction); } // Skiing // -------------------------------------------------------------- packet.PutByte(0); // IsSkiing // loop // packet.PutFloat // packet.PutFloat // packet.PutFloat // packet.PutFloat // packet.PutInt // packet.PutInt // packet.PutByte // packet.PutByte // Farming // [150100-170400] Public too // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutLong(0); // FarmId // packet.PutLong // packet.PutLong // packet.PutLong // packet.PutShort // packet.PutShort // packet.PutShort // packet.PutShort // packet.PutShort // packet.PutShort // packet.PutByte // packet.PutLong // packet.PutByte // packet.PutLong } // Event (CaptureTheFlag, WaterBalloonBattle) // -------------------------------------------------------------- packet.PutByte(0); // EventFullSuitIndex packet.PutByte(0); // TeamId // packet.PutInt // HitPoint // packet.PutInt // MaxHitPoint // [170300] ? { packet.PutString(""); packet.PutByte(0); } // Heartstickers // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutShort(0); packet.PutShort(0); } // Joust // -------------------------------------------------------------- packet.PutInt(0); // JoustId if (type == CreaturePacketType.Private) { packet.PutInt(0); // JoustPoint packet.PutByte(0); // unknown at 0x1D packet.PutByte(0); // unknown at 0x1C packet.PutByte(0); // WeekWinCount packet.PutShort(0); // DailyWinCount packet.PutShort(0); // DailyLoseCount packet.PutShort(0); // ServerWinCount packet.PutShort(0); // ServerLoseCount } else if (type == CreaturePacketType.Public) { //packet.PutInt(0); // JoustId packet.PutLong(0); // HorseId packet.PutFloat(0); // Life packet.PutInt(100); // LifeMax packet.PutByte(9); // unknown at 0x6C packet.PutByte(0); // IsJousting } // Achievements // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutInt(0); // TotalScore packet.PutShort(0); // AchievementList // loop // packet.PutShort achievementId } // PrivateFarm // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutInt(0); // FavoriteFarmList // loop // packet.PutLong // FarmId // packet.PutInt // ZoneId // packet.PutShort // PosX // packet.PutShort // PoxY // packet.PutString // FarmName // packet.PutString // OwnerName } // Family // -------------------------------------------------------------- packet.PutLong(0); // FamilyId // if // packet.PutString // FamilyName // packet.PutShort // packet.PutShort // packet.PutShort // packet.PutString // FamilyTitle // Demigod // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutInt(0); // SupportType (0:None, 1:Neamhain, 2:Morrighan) } // [150100] NPC options // -------------------------------------------------------------- if (type == CreaturePacketType.Public && creature.EntityType == EntityType.NPC) { packet.PutShort(0); // OnlyShowFilter packet.PutShort(0); // HideFilter } // [150100] Commerce // -------------------------------------------------------------- { packet.PutByte(1); // IsInCommerceCombat packet.PutLong(0); // TransportCharacterId packet.PutFloat(1); // ScaleHeight } // [170100] Talents // -------------------------------------------------------------- { if (type == CreaturePacketType.Public) { packet.PutLong(0); packet.PutByte(0); packet.PutByte(0); packet.PutFloat(1); packet.PutLong(0); packet.PutShort((ushort)creature.Talents.SelectedTitle); packet.PutByte((byte)creature.Talents.Grandmaster); } else if (type == CreaturePacketType.Private) { packet.AddPrivateTalentInfo(creature); } } // [170300] Shamala // -------------------------------------------------------------- { if (type == CreaturePacketType.Private) { // Transformation Diary packet.PutSInt(character.Shamalas.Count); foreach (var trans in character.Shamalas) { packet.PutInt(trans.Id); packet.PutByte(trans.Counter); packet.PutByte((byte)trans.State); } } else if (type == CreaturePacketType.Public) { // Current transformation info if (creature.Shamala != null) { packet.PutInt(creature.Shamala.Id); packet.PutByte(0); packet.PutInt(creature.ShamalaRace.Id); packet.PutFloat(creature.Shamala.Size); packet.PutInt(creature.Shamala.Color1); packet.PutInt(creature.Shamala.Color2); packet.PutInt(creature.Shamala.Color3); } else { packet.PutInt(0); packet.PutByte(0); packet.PutInt(0); packet.PutFloat(1); packet.PutInt(0x808080); packet.PutInt(0x808080); packet.PutInt(0x808080); } packet.PutByte(0); packet.PutByte(0); } } // [180100] ? // -------------------------------------------------------------- if (type == CreaturePacketType.Private) { packet.PutInt(0); packet.PutInt(0); } // [NA170403, TW170300] ? // -------------------------------------------------------------- { packet.PutInt(0); packet.PutLong(0); packet.PutLong(0); // Rock/Paper/Scissors? packet.PutString(""); // Banner text? packet.PutByte(0); // Banner enabled? } // [180300, NA166 (18.09.2013)] ? // Required, even though it looks like a list. // -------------------------------------------------------------- { packet.PutInt(10); // Count? packet.PutLong(4194304); packet.PutInt(1347950097); packet.PutLong(34359771136); packet.PutInt(1346340501); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); packet.PutLong(0); packet.PutInt(0); } // Character // -------------------------------------------------------------- if (type == CreaturePacketType.Public) { packet.PutLong(0); // AimingTarget packet.PutLong(0); // Executor packet.PutShort(0); // ReviveTypeList // loop // packet.PutInt // < int g18 monsters? } packet.PutByte(0); // IsGhost // SittingProp if (creature.Temp.SittingProp == null) packet.PutLong(0); else packet.PutLong(creature.Temp.SittingProp.Id); packet.PutSInt(-1); // SittedSocialMotionId // ? (Last Part of public) // -------------------------------------------------------------- if (type == CreaturePacketType.Public) { packet.PutLong(0); // DoubleGoreTarget packet.PutInt(0); // DoubleGoreTargetType // [180300, NA169 (23.10.2013)] ? { packet.PutLong(0); } if (!creature.IsMoving) { packet.PutByte(0); } else { packet.PutByte((byte)(!creature.IsWalking ? 2 : 1)); packet.PutInt(creature.Destination.X); packet.PutInt(creature.Destination.Y); } if (creature.EntityType == EntityType.NPC) { packet.PutString(creature.StandStyleTalk); } // [150100] Bomb Event { packet.PutByte(0); // BombEventState } // [170400] ? { packet.PutByte(0); } // [180?00] ? { packet.PutByte(1); } return; } // private: // [JP] ? // This int is needed in the JP client (1704 log), // but doesn't appear in the NA 1704 or KR test 1801 log. { //packet.PutInt(4); } // Premium stuff // -------------------------------------------------------------- packet.PutByte(0); // IsUsingExtraStorage (old service) packet.PutByte(1); // IsUsingNaosSupport (old service) (Style tab in 1803?) packet.PutByte(0); // IsUsingAdvancedPlay (old service) packet.PutByte(0); // PremiumService 0 packet.PutByte(0); // PremiumService 1 packet.PutByte(1); // Premium Gestures packet.PutByte(1); // ? (Default 1 on NA?) packet.PutByte(0); // [170402, TW170300] New premium thing { packet.PutByte(1); // VIP inv? (since 1803?) } // [180300, NA166 (18.09.2013)] ? { packet.PutByte(0); packet.PutByte(0); } packet.PutInt(0); packet.PutByte(0); packet.PutInt(0); packet.PutInt(0); packet.PutInt(0); // Quests // -------------------------------------------------------------- packet.PutSInt(incompleteQuestsCount); foreach (var q in incompleteQuests) packet.AddQuest(q); // Char // -------------------------------------------------------------- packet.PutByte(0); // NaoDress (0:normal, 12:??, 13:??) packet.PutLong(character.CreationTime); packet.PutLong(character.LastRebirth); packet.PutString(""); packet.PutByte(0); packet.PutByte(2); // [150100] Pocket ExpireTime List // -------------------------------------------------------------- { // Style packet.PutLong(DateTime.Now.AddMonths(1)); packet.PutShort(72); // ? packet.PutLong(0); packet.PutShort(73); packet.PutLong(0); } }
/// <summary> /// Sends revive notice to creature's client. /// </summary> /// <param name="creature"></param> public static void Revived(MabiCreature creature) { var pos = creature.GetPosition(); var packet = new MabiPacket(Op.Revived, creature.Id); packet.PutInt(1); packet.PutInt(creature.Region); packet.PutInt(pos.X); packet.PutInt(pos.Y); creature.Client.Send(packet); }
/// <summary> /// Sends enter region permission, which kinda makes the client warp. /// </summary> /// <param name="client"></param> /// <param name="creature"></param> /// <param name="permission"></param> public static void EnterRegionPermission(WorldClient client, MabiCreature creature, bool permission = true) { var pos = creature.GetPosition(); var p = new MabiPacket(Op.EnterRegionPermission, Id.World); p.PutLong(creature.Id); p.PutByte(permission); if (permission) { p.PutInt(creature.Region); p.PutInt(pos.X); p.PutInt(pos.Y); } client.Send(p); }
/// <summary> /// Calculates and sets new position for creature, and returns a copy /// of the current coordinates, for later use. /// </summary> /// <param name="target">Creature to knock back</param> /// <param name="attacker">Creature that attacked</param> /// <param name="distance">Knock back distance</param> /// <returns>Position of creature, before the knock back</returns> public static MabiVertex KnockBack(MabiCreature target, MabiEntity attacker, int distance = 375) { var oldPos = target.GetPosition(); var pos = WorldManager.CalculatePosOnLine(attacker, target, distance); // Check for collision, set new pos 200 points before the // intersection, to prevent glitching through. MabiVertex intersection; if (WorldManager.Instance.FindCollision(attacker.Region, oldPos, pos, out intersection)) pos = WorldManager.CalculatePosOnLine(oldPos, intersection, -200); target.SetPosition(pos.X, pos.Y); return oldPos; }
/// <summary> /// Warps creature to the specified coordinates in the current region. /// If coordinates are ommited, a random location will be used. /// </summary> private CommandResult Command_jump(WorldClient client, MabiCreature creature, string[] args, string msg) { var pos = creature.GetPosition(); uint region = creature.Region; uint x = pos.X, y = pos.Y; if (args.Length > 1 && !uint.TryParse(args[1], out x)) return CommandResult.WrongParameter; if (args.Length > 2 && !uint.TryParse(args[2], out y)) return CommandResult.WrongParameter; if (args.Length == 1) { // Random coordinates. var rndc = MabiData.RegionInfoDb.RandomCoord(region); x = rndc.X; y = rndc.Y; } client.Warp(region, x, y); return CommandResult.Okay; }
protected void Explode(MabiCreature attacker, MabiCreature target, MabiSkill skill, MabiProp casterProp, float dmgModifier = 1f) { WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.IcespearFreeze).PutByte(1).PutInt(0), SendTargets.Range, target); // Cancel freeze var tPos = target.GetPosition(); var bombProp = new MabiProp(280, target.Region, tPos.X, tPos.Y, 0); //4 WorldManager.Instance.AddProp(bombProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, bombProp.Id).PutInts(Effect.IcespearBoom, target.Region, tPos.X, tPos.Y), SendTargets.Range, bombProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.Thunderbolt).PutByte(0), SendTargets.Range, target); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, SkillHelper.GetAreaTargetID(target.Region, tPos.X, tPos.Y)); sAction.PropId = casterProp.Id; sAction.Options = AttackerOptions.KnockBackHit1 | AttackerOptions.UseEffect; var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Id); tAction.Options = TargetOptions.Result; tAction.StunTime = target.Stun = 2000; var rnd = RandomProvider.Get(); var damage = attacker.GetMagicDamage(attacker.RightHand, rnd.Next((int)skill.RankInfo.Var1, (int)skill.RankInfo.Var2 + 1)) * dmgModifier; if (CombatHelper.TryAddCritical(target, ref damage, attacker.CriticalChanceAgainst(target))) tAction.Options |= TargetOptions.Critical; target.TakeDamage(tAction.Damage = damage); // Knock down if dead tAction.OldPosition = CombatHelper.KnockBack(target, bombProp); if (target.IsDead) { tAction.Options |= TargetOptions.FinishingKnockDown; } else { tAction.Options |= TargetOptions.KnockDown; CombatHelper.SetAggro(attacker, target); } var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction, tAction); WorldManager.Instance.HandleCombatActionPack(cap); sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, SkillHelper.GetAreaTargetID(target.Region, tPos.X, tPos.Y)); sAction.PropId = bombProp.Id; sAction.Options = AttackerOptions.UseEffect; cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); WorldManager.Instance.HandleCombatActionPack(cap); WorldManager.Instance.RemoveProp(bombProp); }
public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill) { var itarget = WorldManager.Instance.GetCreatureById(targetId); if (itarget == null) return SkillResults.InvalidTarget; if (!WorldManager.InRange(attacker, itarget, 2000)) return SkillResults.OutOfRange; var targets = this.GetIceSpearLOSChain(attacker, itarget, (uint)skill.RankInfo.Var5); foreach (var target in targets) { target.StopMove(); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, target.Id).PutInt(Effect.IcespearFreeze).PutByte(1).PutInt(13000), SendTargets.Range, target); } var aPos = attacker.GetPosition(); var casterProp = new MabiProp(280, attacker.Region, aPos.X, aPos.Y, 0); // 3 WorldManager.Instance.AddProp(casterProp); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("icespear").PutByte(1).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker); var charges = attacker.ActiveSkillStacks; Send.SkillUse(attacker.Client, attacker, skill.Id, targetId); SkillHelper.ClearStack(attacker, skill); // End the spear WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("icespear").PutBytes(0, 0), SendTargets.Range, attacker); var sAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Id, targetId); sAction.Options = AttackerOptions.Result; var cap = new CombatActionPack(attacker, skill.Id); cap.Add(sAction); foreach (var target in targets) { var tAction = new TargetAction(CombatActionType.None, target, attacker, skill.Id); cap.Add(tAction); } WorldManager.Instance.HandleCombatActionPack(cap); SkillHelper.GiveSkillExp(attacker, skill, 20); System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { this.IcespearProcessing(attacker, skill, targets, casterProp, 3500, charges); })); t.Start(); return SkillResults.Okay; }
/// <summary> /// Broadcasts WalkTo. If to is null, the creature's position is used. /// </summary> /// <param name="wm"></param> /// <param name="creature"></param> public static void WalkTo(MabiCreature creature, MabiVertex to = null) { var pos = creature.GetPosition(); var p = new MabiPacket(Op.WalkTo, creature.Id); p.PutInts(pos.X, pos.Y); // From p.PutInts(pos.X, pos.Y); // To p.PutBytes(1, 0); WorldManager.Instance.Broadcast(p, SendTargets.Range, creature); }
// Entity Management // ================================================================== /// <summary> /// Adds a creature to the world, and raises the EnterRegion event. /// </summary> /// <param name="creature"></param> public void AddCreature(MabiCreature creature) { lock (_creatures) { if (!_creatures.Contains(creature)) { _creatures.Add(creature); if (creature is MabiPC) this.ActivateMobs(creature, creature.GetPosition(), creature.GetPosition()); } } if (creature.Client is WorldClient) { lock (_clients) { if (!_clients.Contains(creature.Client as WorldClient)) _clients.Add(creature.Client as WorldClient); } } Send.EntityAppearsOthers(creature); EventManager.EntityEvents.OnEntityEntersRegion(creature); }
public override SkillResults UseCombat(MabiCreature attacker, ulong targetId, MabiSkill skill) { var target = WorldManager.Instance.GetCreatureById(targetId); if (target == null) return SkillResults.InvalidTarget; if (!WorldManager.InRange(attacker, target, 2000)) return SkillResults.OutOfRange; if (attacker.ActiveSkillStacks != 5) return SkillResults.Failure; attacker.StopMove(); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.UseMagic).PutString("fireball").PutByte(1).PutLong(targetId).PutShort((ushort)skill.Id), SendTargets.Range, attacker); WorldManager.Instance.Broadcast(PacketCreator.TurnTo(attacker, target).PutByte(1), SendTargets.Range, attacker); var pos = target.GetPosition(); var bomb = new MabiProp(280, target.Region, pos.X, pos.Y, 1f); WorldManager.Instance.AddProp(bomb); var frompos = attacker.GetPosition(); WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, bomb.Id).PutInts(Effect.FireballFly, bomb.Region).PutFloats(frompos.X, frompos.Y, pos.X, pos.Y).PutInt(4000).PutByte(0).PutInt((uint)skill.Id), SendTargets.Range, attacker); Send.SkillUse(attacker.Client, attacker, skill.Id, UseStun, 1); SkillHelper.ClearStack(attacker, skill); // End the fire bolts WorldManager.Instance.Broadcast(new MabiPacket(Op.Effect, attacker.Id).PutInt(Effect.StackUpdate).PutString("firebolt").PutBytes(0, 0), SendTargets.Range, attacker); SkillHelper.GiveSkillExp(attacker, skill, 20); var t = new Thread(new System.Threading.ThreadStart(() => { this.FireballProcessing(attacker, skill, bomb, targetId); })); t.Start(); return SkillResults.Okay; }
/// <summary> /// Warps creature to the specified region and coordinates. /// If coordinates are ommited, a random location will be used. /// </summary> private CommandResult Command_warp(WorldClient client, MabiCreature creature, string[] args, string msg) { if (args.Length < 2) return CommandResult.WrongParameter; var pos = creature.GetPosition(); uint region = 0; if (!uint.TryParse(args[1], out region)) { var mapInfo = MabiData.RegionDb.Find(args[1]); if (mapInfo != null) region = mapInfo.Id; else { Send.ServerMessage(client, creature, Localization.Get("gm.warp_region"), args[1]); // Region '{0}' not found. return CommandResult.Fail; } } uint x = pos.X, y = pos.Y; if (args.Length > 2 && !uint.TryParse(args[2], out x)) return CommandResult.WrongParameter; if (args.Length > 3 && !uint.TryParse(args[3], out y)) return CommandResult.WrongParameter; if (args.Length == 2) { // Random coordinates. var rndc = MabiData.RegionInfoDb.RandomCoord(region); x = rndc.X; y = rndc.Y; } client.Warp(region, x, y); return CommandResult.Okay; }
// Commands // ------------------------------------------------------------------ private CommandResult Command_where(WorldClient client, MabiCreature creature, string[] args, string msg) { var pos = creature.GetPosition(); var area = MabiData.RegionInfoDb.GetAreaId(creature.Region, pos.X, pos.Y); Send.ServerMessage(client, creature, Localization.Get("gm.where"), creature.Region, pos.X, pos.Y, area, creature.Direction); // Region: {0}, X: {1}, Y: {2}, Area: {3}, Direction: {4} return CommandResult.Okay; }
public void AddMemberPacket(MabiPacket packet, MabiCreature member) { if (!Members.Contains(member)) return; packet.PutInt(this.GetMemberNumber(member)); packet.PutLong(member.Id); packet.PutString(member.Name); packet.PutByte(1); // ? packet.PutInt(member.Region); MabiVertex loc = member.GetPosition(); packet.PutInt(loc.X); packet.PutInt(loc.Y); packet.PutByte(0); // ? packet.PutInt((uint)((member.Life * 100) / member.LifeMax)); packet.PutInt((uint)member.LifeMax); packet.PutLong(0); // ? }
private CommandResult Command_prop(WorldClient client, MabiCreature creature, string[] args, string msg) { if (args.Length < 2) return CommandResult.WrongParameter; uint propClass = 0; if (!uint.TryParse(args[1], out propClass)) return CommandResult.Fail; var pos = creature.GetPosition(); var area = MabiData.RegionInfoDb.GetAreaId(creature.Region, pos.X, pos.Y); var prop = new MabiProp(propClass, creature.Region, pos.X, pos.Y, creature.Direction); WorldManager.Instance.AddProp(prop); return CommandResult.Okay; }
public override SkillResults Prepare(MabiCreature creature, MabiSkill skill, MabiPacket packet, uint castTime) { var rnd = RandomProvider.Get(); // Check for instrument if (creature.RightHand == null || creature.RightHand.Type != ItemType.Instrument) return SkillResults.Failure; // Spawn chair for Cello if (creature.RightHand.DataInfo.Instrument == InstrumentType.Cello) { var pos = creature.GetPosition(); // Chair prop var prop = new MabiProp((!creature.IsGiant ? CelloChair : GiantCelloChair), creature.Region, pos.X, pos.Y, MabiMath.DirToRad(creature.Direction)); prop.State = "stand"; WorldManager.Instance.AddProp(prop); // Move char Send.AssignChair(creature, prop.Id, 1); // Update chair prop.ExtraData = string.Format("<xml OWNER='{0}' SITCHAR='{0}'/>", creature.Id); Send.PropUpdate(prop); creature.Temp.SittingProp = prop; } // Score scrolls go into the magazine pocket and need a SCORE tag. // XXX: Is it possbile to play random with a low durability scroll? bool hasScroll = (creature.Magazine != null && creature.Magazine.Tags.Has("SCORE") && creature.Magazine.OptionInfo.Durability >= DurabilityUse); // Random score if no usable scroll was found. uint rndScore = (!hasScroll ? (uint)rnd.Next(RandomScoreMin, RandomScoreMax + 1) : 0); // Quality seems to go from 0 (worst) to 3 (best). // Should be generated based on skills + random. var quality = (PlayingQuality)rnd.Next((int)PlayingQuality.VeryBad, (int)PlayingQuality.VeryGood + 1); // Up quality by chance, based on Musical Knowledge var knowledge = creature.Skills.Get(SkillConst.MusicalKnowledge); if (knowledge != null && rnd.Next(0, 100) < knowledge.RankInfo.Var2) quality++; if (quality > PlayingQuality.VeryGood) quality = PlayingQuality.VeryGood; // Save quality before checking perfect play option, // we want proper skill training. creature.Temp.PlayingInstrumentQuality = quality; if (WorldConf.PerfectPlay) { quality = PlayingQuality.VeryGood; Send.ServerMessage(creature.Client, creature, Localization.Get("skills.perfect_play")); // Regardless of the result, perfect play will let your performance sound perfect. } // Reduce scroll's durability. if (hasScroll) { creature.Magazine.ReduceDurability(DurabilityUse); creature.Client.Send( new MabiPacket(Op.ItemDurabilityUpdate, creature.Id) .PutLong(creature.Magazine.Id) .PutInt(creature.Magazine.OptionInfo.Durability) ); } // Music effect { var effect = hasScroll ? PacketCreator.PlayEffect(creature, creature.RightHand.DataInfo.Instrument, quality, creature.Magazine.Tags["SCORE"]) : PacketCreator.PlayEffect(creature, creature.RightHand.DataInfo.Instrument, quality, rndScore); WorldManager.Instance.Broadcast(effect, SendTargets.Range, creature); } // Use skill { var use = new MabiPacket(Op.SkillUse, creature.Id); use.PutShort(skill.Info.Id); use.PutLong(0); use.PutByte(hasScroll); if (!hasScroll) use.PutInt(rndScore); else use.PutString(creature.Magazine.Tags["SCORE"]); use.PutByte((byte)creature.RightHand.DataInfo.Instrument); use.PutByte(1); use.PutByte(0); creature.Client.Send(use); creature.ActiveSkillId = skill.Id; } // Change motion for Battle Mandolin (no idea if this official, but I like it =P) [exec] //if (creature.RightHand.Info.Class == 40367) // WorldManager.Instance.CreatureUseMotion(creature, 88, 2, true); return SkillResults.Okay; }