public static int times_killed(CharacterInstance ch, CharacterInstance mob) { if (ch.IsNpc()) { return(0); } if (!mob.IsNpc()) { return(0); } var templateId = (mob.Parent as MobileTemplate).ID; var track = Macros.URANGE(2, ((ch.Level + 3) * GetMaxKillTrack()) / GetLevelAvatar(), GetMaxKillTrack()); var pc = (PlayerInstance)ch; var killedData = pc.PlayerData.Killed.FirstOrDefault(y => y.ID == templateId); if (killedData != null) { return(killedData.Count); } return(0); }
public static ObjectInstance RawKill(this CharacterInstance ch, CharacterInstance victim) { var victimPc = (PlayerInstance)victim; if (victim.IsNotAuthorized()) { LogManager.Instance.Bug("Killing unauthorized"); return(null); } victim.StopFighting(true); if (victim.CurrentMorph != null) { UnmorphChar.do_unmorph_char(victim, string.Empty); return(ch.RawKill(victim)); } MudProgHandler.ExecuteMobileProg(MudProgTypes.Death, ch, victim); if (victim.CharDied()) { return(null); } MudProgHandler.ExecuteRoomProg(MudProgTypes.Death, victim); if (victim.CharDied()) { return(null); } var corpse = ObjectFactory.CreateCorpse(victim, ch); switch (victim.CurrentRoom.SectorType) { case SectorTypes.OceanFloor: case SectorTypes.Underwater: case SectorTypes.ShallowWater: case SectorTypes.DeepWater: comm.act(ATTypes.AT_BLOOD, "$n's blood slowly clouds the surrounding water.", victim, null, null, ToTypes.Room); break; case SectorTypes.Air: comm.act(ATTypes.AT_BLOOD, "$n's blood sprays wildly through the air.", victim, null, null, ToTypes.Room); break; default: ObjectFactory.CreateBlood(victim); break; } if (victim.IsNpc()) { ((MobileInstance)victim).MobIndex.TimesKilled++; victim.Extract(true); victim = null; return(corpse); } victim.SetColor(ATTypes.AT_DIEMSG); Help.do_help(victim, ((PlayerInstance)victim).PlayerData.PvEDeaths + ((PlayerInstance)victim).PlayerData.PvPDeaths < 3 ? "new_death" : "_DIEMSG_"); victim.Extract(false); while (victim.Affects.Count > 0) { victim.RemoveAffect(victim.Affects.First()); } var victimRace = RepositoryManager.Instance.GetRace(victim.CurrentRace); victim.AffectedBy = victimRace.AffectedBy; victim.Resistance = 0; victim.Susceptibility = 0; victim.Immunity = 0; victim.CarryWeight = 0; victim.ArmorClass = 100 + victimRace.ArmorClassBonus; victim.Attacks = victimRace.Attacks; victim.Defenses = victimRace.Defenses; victim.ModStrength = 0; victim.ModDexterity = 0; victim.ModWisdom = 0; victim.ModIntelligence = 0; victim.ModConstitution = 0; victim.ModCharisma = 0; victim.ModLuck = 0; victim.DamageRoll = new DiceData(); victim.HitRoll = new DiceData(); victim.MentalState = -10; victim.CurrentAlignment = Macros.URANGE(-1000, victim.CurrentAlignment, 1000); victim.SavingThrows = victimRace.SavingThrows; victim.CurrentPosition = PositionTypes.Resting; victim.CurrentHealth = Macros.UMAX(1, victim.CurrentHealth); victim.CurrentMana = victim.Level < GetLevelAvatar() ? Macros.UMAX(1, victim.CurrentMana) : 1; victim.CurrentMovement = Macros.UMAX(1, victim.CurrentMovement); if (victim.Act.IsSet((int)PlayerFlags.Killer)) { victim.Act.RemoveBit((int)PlayerFlags.Killer); victim.SendTo("The gods have pardoned you for your murderous acts."); } if (victim.Act.IsSet((int)PlayerFlags.Thief)) { victim.Act.RemoveBit((int)PlayerFlags.Thief); victim.SendTo("The gods have pardoned you for your thievery."); } victimPc.PlayerData.SetConditionValue(ConditionTypes.Full, 12); victimPc.PlayerData.SetConditionValue(ConditionTypes.Thirsty, 12); if (victimPc.IsVampire()) { victimPc.PlayerData.SetConditionValue(ConditionTypes.Bloodthirsty, victim.Level / 2); } // TODO if (IS_SET(sysdata.save_flags, SV_DEATH)) // save_char_obj(victim); return(corpse); }
/// <summary> /// /// </summary> /// <param name="gch"></param> /// <param name="victim"></param> /// <returns></returns> public static int CalculateXP(this CharacterInstance gch, CharacterInstance victim) { int xp = victim.GetExperienceWorth() * Macros.URANGE(0, victim.Level - gch.Level + 10, 13) / 10; int align = gch.CurrentAlignment - victim.CurrentAlignment; // Bonus for opposite alignment if (align > 990 || align < -990) { xp = (xp * 5) >> 2; } else { // Penalty for good attacking same alignment if (gch.CurrentAlignment > 300 && align < 250) { xp = (xp * 3) >> 2; } } xp = SmaugRandom.Between((xp * 3) >> 2, (xp * 5) >> 2); // 1/4 XP for players if (!victim.IsNpc()) { xp /= 4; } else { // Reduce XP for killing the same mob repeatedly if (!gch.IsNpc()) { int times = handler.times_killed(gch, victim); if (times >= 20) { xp = 0; } else if (times > 0) { xp = (xp * (20 - times)) / 20; if (times > 15) { xp /= 3; } else if (times > 10) { xp >>= 1; } } } } // Semi-intelligent experienced player vs notice player if (!gch.IsNpc() && gch.Level > 5) { var xp_ratio = (int)((PlayerInstance)gch).TotalPlayedTime / gch.Level; if (xp_ratio > 20000) { xp = (xp * 5) >> 2; } else if (xp_ratio > 16000) { xp = (xp * 3) >> 2; } else if (xp_ratio > 10000) { xp >>= 1; } else if (xp_ratio > 5000) { xp >>= 2; } else if (xp_ratio > 3500) { xp >>= 3; } else if (xp_ratio > 2000) { xp >>= 4; } } // Level based xp gain cap return(Macros.URANGE(0, xp, handler.exp_level(gch, gch.Level + 1) - handler.exp_level(gch, gch.Level))); }