public static void SoundHitBuildingPrefix(ref SoundDef __result, Verb_MeleeAttack __instance)
        {
            if (__instance.caster is Pawn pawn)
            {
                var pawn_EquipmentTracker = pawn.equipment;
                if (pawn_EquipmentTracker != null)
                {
                    //Log.Message("2");
                    var thingWithComps =
                        pawn_EquipmentTracker
                        .Primary;     // (ThingWithComps)AccessTools.Field(typeof(Pawn_EquipmentTracker), "primaryInt").GetValue(pawn_EquipmentTracker);

                    if (thingWithComps != null)
                    {
                        //Log.Message("3");
                        var CompExtraSounds = thingWithComps.GetComp <CompExtraSounds>();
                        if (CompExtraSounds != null)
                        {
                            if (CompExtraSounds.Props.soundHitBuilding != null)
                            {
                                __result = CompExtraSounds.Props.soundHitBuilding;
                            }
                        }
                    }
                }
            }
        }
 public static void Postfix(Verb_MeleeAttack __instance, ref float __result)
 {
     if (__instance.caster is Thing caster && caster.TryGetComp <CompTargetingMode>() is CompTargetingMode targetingComp && __result == caster.GetStatValue(StatDefOf.MeleeHitChance))
     {
         __result *= __result * targetingComp.GetTargetingMode().HitChanceFactor;
     }
 }
Esempio n. 3
0
        public static void SoundHitPawnPrefix(ref SoundDef __result, Verb_MeleeAttack __instance)
        {
            if (__instance.caster is Pawn pawn)
            {
                var pawn_EquipmentTracker = pawn.equipment;
                if (pawn_EquipmentTracker != null)
                {
                    //Log.Message("2");
                    var thingWithComps =
                        pawn_EquipmentTracker
                        .Primary;     // (ThingWithComps)AccessTools.Field(typeof(Pawn_EquipmentTracker), "primaryInt").GetValue(pawn_EquipmentTracker);

                    if (thingWithComps?.def?.defName == "RE_StunGun")
                    {
                        if (thingWithComps.TryGetComp <CompStunCharge>() is CompStunCharge charge)
                        {
                            if (charge.StoredEnergy == charge.StoredEnergyMax)
                            {
                                charge.DrainEnergy();
                                SoundDef.Named("RE_StunGun").PlayOneShot(pawn);
                                if (pawn.LastAttackedTarget.HasThing)
                                {
                                    if (pawn.LastAttackedTarget.Thing is Pawn targetPawn)
                                    {
                                        HealthUtility.AdjustSeverity(targetPawn, HediffDef.Named("RE_ShockBuildup"), 1.0f);
                                        MoteMaker.ThrowLightningGlow(targetPawn.DrawPos, pawn.Map, 5);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        private static void ApplyNormalDamageToTarget(Verb_MeleeAttack vMA, Pawn attacker, LocalTargetInfo target)
        {
            MRpawntoken token = MainController.GetPawnToken(attacker);
            Pawn        tpawn = target.Thing as Pawn;
            // Immobile targets receive full damage on normal hits (The only possible result against them) with independence of the Attack Mode selected
            bool immobile = (target.Thing.def.category != ThingCategory.Pawn) || tpawn.Downed || (tpawn.GetPosture() != PawnPosture.Standing);

            if (token.amode.solver == 3 && !immobile)
            {
                return;                                       // On Disarm Mode we do no damage at all
            }
            var DamageInfosToApply = Traverse.Create(vMA).Method("DamageInfosToApply", new Type[] { typeof(LocalTargetInfo) });

            foreach (DamageInfo current in (DamageInfosToApply.GetValue <IEnumerable <DamageInfo> >(target)))
            {
                if (target.ThingDestroyed)
                {
                    break;
                }
                if (!immobile && (token.amode.solver == 1 || token.amode.solver == 2))
                {
                    // On Capture & Stun we do half the damage on normal hits
                    current.SetAmount(Mathf.Max(1, Mathf.RoundToInt(current.Amount * 0.5f)));
                }
                target.Thing.TakeDamage(current);
            }
        }
Esempio n. 5
0
        private static void ApplyParryDamageToTarget(Verb_MeleeAttack vMA, Pawn attacker, LocalTargetInfo target)
        {
            // The main differences between a regular hit and a parried one regarding damage are the following:
            // - If the target has an active shield with energy it will absorb the FULL damage of the attack
            // - If the target is wielding a melee weapon it will absorb all the damage of the attack suffering
            //   Original Damage * ParryReduction * (1-Melee Skill) (minimum of 1) of damage
            // - If the target is unarmed, the damage received will be reduced by ParryReduction
            MRpawntoken token = MainController.GetPawnToken(attacker);

            if (token.amode.solver == 3)
            {
                return;                          // On Disarm Mode we do no damage at all on parried hits
            }
            bool rollback           = false;
            Pawn tpawn              = target.Thing as Pawn;
            var  DamageInfosToApply = Traverse.Create(vMA).Method("DamageInfosToApply", new Type[] { typeof(LocalTargetInfo) });

            foreach (DamageInfo current in (DamageInfosToApply.GetValue <IEnumerable <DamageInfo> >(target)))
            {
                if (target.ThingDestroyed)
                {
                    break;
                }
                if (token.amode.solver == 1 || token.amode.solver == 2)
                {
                    // On Capture & Stun we do half the damage on parry hits
                    current.SetAmount(Mathf.Max(1, Mathf.RoundToInt(current.Amount * 0.5f)));
                }
                rollback = current.Def.isExplosive;        // We briefly active isExplosive to make Vanilla Personal Shields able to intercept melee damage
                current.Def.isExplosive = true;
                if (PawnHasActiveAbsorber(current, tpawn)) // We have to do a double check so Apparel absorbers take precedence over wield weapon damage
                {
                    target.Thing.TakeDamage(current);
                }
                else if (tpawn.equipment != null && tpawn.equipment.Primary != null && tpawn.equipment.Primary.def.IsMeleeWeapon)
                {
                    // The target has an equiped melee weapon after a parry, it will deny any damage to the target but the weapon will suffer some damage itself
                    current.SetAmount(Mathf.Max(1, Mathf.RoundToInt(current.Amount * Constants.ParryReduction * (1f - tpawn.GetStatValue(StatDefOf.MeleeHitChance, true)))));
                    // If the current damage is enough to destroy the weapon we try to drop it instead. If there is not enough room nearby, it will be destroyed
                    if (tpawn.equipment.Primary.HitPoints <= current.Amount)
                    {
                        ThingWithComps thingwithcomps = new ThingWithComps();
                        if (tpawn.equipment.TryDropEquipment(tpawn.equipment.Primary, out thingwithcomps, tpawn.Position))
                        {
                            current.Def.isExplosive = rollback;
                            break;
                        }
                    }
                    tpawn.equipment.Primary.TakeDamage(current);
                }
                else
                {
                    // Unarmed defender, it just takes reduced damage
                    current.SetAmount(Mathf.Max(1, Mathf.RoundToInt(current.Amount * Constants.ParryReduction)));
                    target.Thing.TakeDamage(current);
                }
                current.Def.isExplosive = rollback;
            }
        }
 public static void SoundHitBuildingPostfix(ref SoundDef __result, Verb_MeleeAttack __instance)
 {
     if (__instance.caster is Pawn pawn)
     {
         if (pawn.equipment?.Primary?.GetCompExtraSounds()?.Props.soundHitBuilding is SoundDef soundHitBuilding)
         {
             __result = soundHitBuilding;
         }
     }
 }
Esempio n. 7
0
        static void Postfix(Verb_MeleeAttack __instance)
        {
            LocalTargetInfo currentTarget = Traverse.Create(__instance).Field("currentTarget").GetValue <LocalTargetInfo>();

            if (currentTarget != null && currentTarget.HasThing)
            {
                Thing t = currentTarget.Thing;
                MoteMaker.ThrowText(t.DrawPos, t.Map, "DM_MISS".Translate(), 3.65f);
            }
        }
Esempio n. 8
0
 public static void SoundHitPawnPrefix(ref SoundDef __result, Verb_MeleeAttack __instance)
 {
     if (__instance.caster is Pawn pawn && pawn.GetComp <CompHulk>() is CompHulk w && w.IsTransformed)
     {
         if (w.CurrentHulkForm.def.attackSound is SoundDef soundToPlay)
         {
             if (Rand.Value < 0.5f)
             {
                 soundToPlay.PlayOneShot(new TargetInfo(pawn));
             }
         }
     }
 }
Esempio n. 9
0
        private static void ApplyCriticalDamageToTarget(Verb_MeleeAttack vMA, Pawn attacker, LocalTargetInfo target)
        {
            Pawn        tpawn = target.Thing as Pawn;
            var         DamageInfosToApply = Traverse.Create(vMA).Method("DamageInfosToApply", new Type[] { typeof(LocalTargetInfo) });
            MRpawntoken token = MainController.GetPawnToken(attacker);

            switch (token.amode.solver)
            {
            case 0:     // Kill
                // Double damage on all applied damage
                foreach (DamageInfo current in (DamageInfosToApply.GetValue <IEnumerable <DamageInfo> >(target)))
                {
                    if (target.ThingDestroyed)
                    {
                        break;
                    }
                    current.SetAmount(Mathf.Max(1, Mathf.RoundToInt(current.Amount * 2f)));
                    target.Thing.TakeDamage(current);
                }
                break;

            case 1:     // Capture
                // We replace all damage by an anesthesize effect
                if (target.Thing.def.category == ThingCategory.Pawn)
                {
                    HealthUtility.TryAnesthesize(tpawn);
                }
                break;

            case 2:     // Stun
                // We replace ALL damage by a short stun effect instead
                target.Thing.TakeDamage(new DamageInfo(DamageDefOf.Stun, 20));
                break;

            case 3:     // Disarm
                // We replace ALL damage by removing currently equiped weapon
                if (tpawn.equipment != null && tpawn.equipment.Primary != null)
                {
                    ThingWithComps thingwithcomps = new ThingWithComps();
                    tpawn.equipment.TryDropEquipment(tpawn.equipment.Primary, out thingwithcomps, tpawn.Position);
                }
                break;

            default:
                Log.Warning(string.Concat(new object[]
                {
                    "Melee Rebalance: Critical Special effect not registered for ", attacker
                }));
                break;
            }
        }
Esempio n. 10
0
        public static void GetNonMissChance_PostFix(Verb_MeleeAttack __instance, LocalTargetInfo target, ref float __result)
        {
            //if (target.Thing != null && target.Thing is Pawn)
            //{
            Pawn attacker = __instance.CasterPawn;

            if (attacker != null)
            {
                Pawn_EquipmentTracker pawn_EquipmentTracker = attacker.equipment;
                if (pawn_EquipmentTracker != null)
                {
                    foreach (ThingWithComps thingWithComps in pawn_EquipmentTracker.AllEquipmentListForReading)
                    {
                        if (thingWithComps != null)
                        {
                            if (thingWithComps.def.IsMeleeWeapon)
                            {
                                if (thingWithComps.def.defName.Contains("SWSaber_"))
                                {
                                    CompForceUser compForce = attacker.TryGetComp <CompForceUser>();
                                    if (compForce == null)
                                    {
                                        __result = 0.5f;
                                    }
                                    else if (!compForce.IsForceUser)
                                    {
                                        __result = 0.5f;
                                    }
                                    else
                                    {
                                        float newAccuracy = (float)(__result / 2);

                                        int accuracyPoints = compForce.ForceSkillLevel("PJ_LightsaberAccuracy");
                                        if (accuracyPoints > 0)
                                        {
                                            for (int i = 0; i < accuracyPoints; i++)
                                            {
                                                newAccuracy += 0.2f;
                                            }
                                        }
                                        __result = newAccuracy;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //}
        }
Esempio n. 11
0
 public static void TryCastShot_Melee_PostFix(Verb_MeleeAttack __instance, bool __result)
 {
     if (!SettingsHelper.LatestVersion.npcdegrade)
     {
         if (!__instance.CasterPawn.IsColonistPlayerControlled)
         {
             return;
         }
     }
     if (SettingsHelper.LatestVersion.degradeMelee && Utility.Eligable(__instance))
     {
         Utility.Fire(__instance);
     }
 }
Esempio n. 12
0
        public static void SoundHitPawnPostfix(ref SoundDef __result, Verb_MeleeAttack __instance)
        {
            if (__instance.caster is Pawn pawn)
            {
                if (pawn.kindDef?.GetModExtensionExtraSounds()?.soundHitPawn is SoundDef modExtSoundHitPawn)
                {
                    __result = modExtSoundHitPawn;
                }

                if (pawn.equipment?.Primary?.GetCompExtraSounds()?.Props.soundHitPawn is SoundDef soundHitPawn)
                {
                    __result = soundHitPawn;
                }
            }
        }
Esempio n. 13
0
        public static void TryCastShot(Verb_MeleeAttack __instance)
        {
            BindingFlags bindFlags  = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
            FieldInfo    field      = (__instance.GetType()).GetField("currentTarget", bindFlags);
            object       fieldValue = field.GetValue(__instance);

            if (fieldValue != null && fieldValue is LocalTargetInfo)
            {
                Thing targetThing = ((LocalTargetInfo)fieldValue).Thing;
                if (__instance.CasterPawn != null && targetThing != null && targetThing is Pawn && !(targetThing as Pawn).Dead && (targetThing as Pawn).RaceProps.Humanlike && (targetThing as Pawn).equipment != null)
                {
                    WeaponAssingment.doCQC(targetThing as Pawn, __instance.CasterPawn);
                }
            }
        }
Esempio n. 14
0
 public static void Postfix(Verb_MeleeAttack __instance, ref float __result)
 {
     if (typeof(Thing).Equals(__instance.caster))
     {
         Thing caster = __instance.caster;
         if (caster != null)
         {
             if (typeof(CompTargetingMode).Equals(caster.TryGetComp <CompTargetingMode>()))
             {
                 CompTargetingMode targetingComp = caster.TryGetComp <CompTargetingMode>();
                 if (targetingComp != null && __result == caster.GetStatValue(StatDefOf.MeleeHitChance))
                 {
                     __result *= __result * targetingComp.GetTargetingMode().HitChanceFactor;
                 }
             }
         }
     }
 }
        //=================================== COMPEXTRASOUNDS
        public static void SoundHitPawnPrefix(ref SoundDef __result, Verb_MeleeAttack __instance)
        {
            if (__instance.caster is Pawn pawn)
            {
                var pawn_PawnKindDef = pawn.kindDef;
                if (pawn_PawnKindDef != null)
                {
                    var extraSoundsExtension = pawn_PawnKindDef.GetModExtension <DefModExtension_ExtraSounds>();
                    if (extraSoundsExtension != null)
                    {
                        if (extraSoundsExtension != null)
                        {
                            if (extraSoundsExtension.soundHitPawn != null)
                            {
                                __result = extraSoundsExtension.soundHitPawn;
                            }
                        }
                    }
                }

                var pawn_EquipmentTracker = pawn.equipment;
                if (pawn_EquipmentTracker != null)
                {
                    //Log.Message("2");
                    var thingWithComps =
                        pawn_EquipmentTracker
                        .Primary;     // (ThingWithComps)AccessTools.Field(typeof(Pawn_EquipmentTracker), "primaryInt").GetValue(pawn_EquipmentTracker);

                    if (thingWithComps != null)
                    {
                        //Log.Message("3");
                        var CompExtraSounds = thingWithComps.GetComp <CompExtraSounds>();

                        if (CompExtraSounds != null)
                        {
                            if (CompExtraSounds.Props.soundHitPawn != null)
                            {
                                __result = CompExtraSounds.Props.soundHitPawn;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 16
0
        public static void GetNonMissChance_PostFix(Verb_MeleeAttack __instance, ref float __result)
        {
            if (__instance.Caster is not Pawn attacker)
            {
                return;
            }

            var weapon = __instance.EquipmentSource;

            if (weapon == null || !IsSWSaber(weapon.def))
            {
                return;
            }

            var compForce = attacker.GetForceCompIfForceUser();

            if (compForce == null)
            {
                __result = 0.5f;
            }
            else
            {
                var newAccuracy = __result / 2;

                var accuracyPoints = compForce.ForceSkillLevel("PJ_LightsaberAccuracy");
                if (accuracyPoints > 0)
                {
                    for (var i = 0; i < accuracyPoints; i++)
                    {
                        newAccuracy += 0.2f;
                    }
                }

                __result = newAccuracy;
            }
        }
Esempio n. 17
0
        // RimWorld.Verb_MeleeAttack
        public static void DamageInfosToApply_PostFix(Verb_MeleeAttack __instance, ref IEnumerable <DamageInfo> __result,
                                                      LocalTargetInfo target)
        {
            var newList = new List <DamageInfo>();
            //__result = null;
            var EquipmentSource = __instance.EquipmentSource;

            if (EquipmentSource != null)
            {
                //Log.Message("1");
                var comp = EquipmentSource.AllComps.FirstOrDefault(x => x is OgsCompSlotLoadable.CompSlotLoadable);
                if (comp != null)
                {
                    //Log.Message("2");
                    var compSlotLoadable = comp as OgsCompSlotLoadable.CompSlotLoadable;
                    if (compSlotLoadable.Slots != null && compSlotLoadable.Slots.Count > 0)
                    {
                        //Log.Message("3");
                        var statSlots = compSlotLoadable.Slots.FindAll(z =>
                                                                       !z.IsEmpty() && ((OgsCompSlotLoadable.SlotLoadableDef)z.def).doesChangeStats);
                        if (statSlots != null && statSlots.Count > 0)
                        {
                            foreach (var slot in statSlots)
                            {
                                //Log.Message("5");
                                var slotBonus = slot.SlotOccupant.def.GetModExtension <SlottedBonusExtension>();
                                if (slotBonus != null)
                                {
                                    //Log.Message("6");
                                    var superClass = __instance.GetType().BaseType;
                                    if (slotBonus.damageDef != null)
                                    {
                                        //Log.Message("7");
                                        var num = __instance.verbProps.AdjustedMeleeDamageAmount(__instance,
                                                                                                 __instance.CasterPawn);
                                        var def = __instance.verbProps.meleeDamageDef;
                                        BodyPartGroupDef weaponBodyPartGroup = null;
                                        HediffDef        weaponHediff        = null;
                                        if (__instance.CasterIsPawn)
                                        {
                                            if (num >= 1f)
                                            {
                                                weaponBodyPartGroup = __instance.verbProps.linkedBodyPartsGroup;
                                                if (__instance.HediffCompSource != null)
                                                {
                                                    weaponHediff = __instance.HediffCompSource.Def;
                                                }
                                            }
                                            else
                                            {
                                                num = 1f;
                                                def = DamageDefOf.Blunt;
                                            }
                                        }

                                        //Log.Message("9");
                                        ThingDef def2;
                                        if (__instance.EquipmentSource != null)
                                        {
                                            def2 = __instance.EquipmentSource.def;
                                        }
                                        else
                                        {
                                            def2 = __instance.CasterPawn.def;
                                        }

                                        //Log.Message("10");
                                        var angle = (target.Thing.Position - __instance.CasterPawn.Position)
                                                    .ToVector3();

                                        //Log.Message("11");
                                        var caster = __instance.caster;

                                        //Log.Message("12");
                                        var newdamage = GenMath.RoundRandom(num);
//                                        Log.Message("applying damage "+newdamage+" out of "+num);
                                        var damageInfo = new DamageInfo(slotBonus.damageDef, newdamage, slotBonus.armorPenetration, -1f,
                                                                        caster, null, def2);
                                        damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                                        damageInfo.SetWeaponBodyPartGroup(weaponBodyPartGroup);
                                        damageInfo.SetWeaponHediff(weaponHediff);
                                        damageInfo.SetAngle(angle);

                                        //Log.Message("13");
                                        newList.Add(damageInfo);

                                        __result = newList.AsEnumerable();
                                    }
                                    var vampiricEffect = slotBonus.vampiricHealChance;
                                    if (vampiricEffect != null)
                                    {
                                        //Log.Message("vampiricHealingCalled");
                                        var randValue = Rand.Value;
                                        //Log.Message("randValue = " + randValue.ToString());

                                        if (randValue <= vampiricEffect.chance)
                                        {
                                            MoteMaker.ThrowText(__instance.CasterPawn.DrawPos,
                                                                __instance.CasterPawn.Map, "Vampiric Effect: Success", 6f);
                                            //MoteMaker.ThrowText(__instance.CasterPawn.DrawPos, __instance.CasterPawn.Map, "Success".Translate(), 6f);
                                            ApplyHealing(__instance.caster, vampiricEffect.woundLimit, target.Thing);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public static bool TryCastShot(Verb_MeleeAttack __instance, ref bool __result)
        {
            Pawn casterPawn = __instance.CasterPawn;

            if (!casterPawn.Spawned)
            {
                return(false);
            }

            if (casterPawn.stances.FullBodyBusy)
            {
                return(false);
            }

            Thing thing = currentTargetFieldRef(__instance).Thing;

            if (!__instance.CanHitTarget(thing))
            {
                Log.Warning(string.Concat(casterPawn, " meleed ", thing, " from out of melee position."));
            }

            casterPawn.rotationTracker.Face(thing.DrawPos);
            if (!funcIsTargetImmobile(__instance, currentTargetFieldRef(__instance)) && casterPawn.skills != null)
            {
                casterPawn.skills.Learn(SkillDefOf.Melee, 200f * __instance.verbProps.AdjustedFullCycleTime(__instance, casterPawn));
            }

            Pawn pawn = thing as Pawn;

            if (pawn != null && !pawn.Dead && (casterPawn.MentalStateDef != MentalStateDefOf.SocialFighting || pawn.MentalStateDef != MentalStateDefOf.SocialFighting))
            {
                pawn.mindState.meleeThreat             = casterPawn;
                pawn.mindState.lastMeleeThreatHarmTick = Find.TickManager.TicksGame;
            }

            Map      map     = thing.Map;
            Vector3  drawPos = thing.DrawPos;
            SoundDef soundDef;
            bool     result;

            if (Rand.Chance(funcGetNonMissChance(__instance, thing)))
            {
                if (!Rand.Chance(funcGetDodgeChance(__instance, thing)))
                {
                    soundDef = ((thing.def.category != ThingCategory.Building) ? funcSoundHitPawn(__instance) : funcSoundHitBuilding(__instance));
                    if (__instance.verbProps.impactMote != null)
                    {
                        MoteMaker.MakeStaticMote(drawPos, map, __instance.verbProps.impactMote);
                    }

                    BattleLogEntry_MeleeCombat battleLogEntry_MeleeCombat = __instance.CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesHit, alwaysShow: true);
                    result = true;
                    DamageWorker.DamageResult damageResult = funcApplyMeleeDamageToTarget(__instance, currentTargetFieldRef(__instance));
                    if (damageResult.stunned && damageResult.parts.NullOrEmpty())
                    {
                        Find.BattleLog.RemoveEntry(battleLogEntry_MeleeCombat);
                    }
                    else
                    {
                        damageResult.AssociateWithLog(battleLogEntry_MeleeCombat);
                        if (damageResult.deflected)
                        {
                            battleLogEntry_MeleeCombat.RuleDef             = __instance.maneuver.combatLogRulesDeflect;
                            battleLogEntry_MeleeCombat.alwaysShowInCompact = false;
                        }
                    }
                }
                else
                {
                    result   = false;
                    soundDef = funcSoundDodge(__instance, thing);
                    MoteMaker.ThrowText(drawPos, map, "TextMote_Dodge".Translate(), 1.9f);
                    __instance.CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDodge, alwaysShow: false);
                }
            }
            else
            {
                result   = false;
                soundDef = funcSoundMiss(__instance);
                __instance.CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, alwaysShow: false);
            }

            soundDef.PlayOneShot(new TargetInfo(thing.Position, map));
            if (casterPawn.Spawned)
            {
                casterPawn.Drawer.Notify_MeleeAttackOn(thing);
            }

            if (pawn != null && !pawn.Dead && pawn.Spawned)
            {
                pawn.stances.StaggerFor(95);
            }

            if (casterPawn.Spawned)
            {
                casterPawn.rotationTracker.FaceCell(thing.Position);
            }

            if (casterPawn.caller != null)
            {
                casterPawn.caller.Notify_DidMeleeAttack();
            }

            return(result);
        }
Esempio n. 19
0
        public static bool Prefix(Verb_MeleeAttack __instance, ref bool __result)
        {
            var verbMA = Traverse.Create(__instance);

            if (__instance.CasterPawn.stances.FullBodyBusy)
            {
                __result = false;
                return(false);
            }
            LocalTargetInfo target = verbMA.Field("currentTarget").GetValue <LocalTargetInfo>();
            Thing           thing  = target.Thing;

            if (!__instance.CanHitTarget(thing))
            {
                Log.Warning(string.Concat(new object[]
                {
                    __instance.CasterPawn,
                    " meleed ",
                    thing,
                    " from out of melee position."
                }));
            }
            __instance.CasterPawn.Drawer.rotator.Face(thing.DrawPos);
            if (!verbMA.Method("IsTargetImmobile", target).GetValue <bool>() && __instance.CasterPawn.skills != null)
            {
                __instance.CasterPawn.skills.Learn(SkillDefOf.Melee, 250f, false);
            }
            SoundDef soundDef;

            // We register the attacker and reset its ParryCounters
            MainController.ResetParryCounter(__instance.CasterPawn);
            switch (ResolveMeleeAttack(__instance.CasterPawn, thing, verbMA.Field("surpriseAttack").GetValue <bool>())) // 0 Miss, 1 Hit, 2 Parry, 3 Critical
            {
            case 1:                                                                                                     // Hit
                __result = true;
                ApplyNormalDamageToTarget(__instance, __instance.CasterPawn, target);
                if (thing.def.category == ThingCategory.Building)
                {
                    soundDef = verbMA.Method("SoundHitBuilding").GetValue <SoundDef>();
                }
                else
                {
                    soundDef = verbMA.Method("SoundHitPawn").GetValue <SoundDef>();
                }
                break;

            case 2:     // Parry
                ApplyParryDamageToTarget(__instance, __instance.CasterPawn, target);
                __result = false;
                soundDef = SoundDefOf.MetalHitImportant;
                break;

            case 3:     // Critical
                ApplyCriticalDamageToTarget(__instance, __instance.CasterPawn, target);
                __result = true;
                soundDef = SoundDefOf.Thunder_OnMap;
                break;

            default:     // Miss
                __result = false;
                soundDef = verbMA.Method("SoundMiss").GetValue <SoundDef>();
                break;
            }
            soundDef.PlayOneShot(new TargetInfo(thing.Position, __instance.CasterPawn.Map, false));
            __instance.CasterPawn.Drawer.Notify_MeleeAttackOn(thing);
            Pawn pawntemp = thing as Pawn;

            if (pawntemp != null && !pawntemp.Dead)
            {
                pawntemp.stances.StaggerFor(95);
                if (__instance.CasterPawn.MentalStateDef != MentalStateDefOf.SocialFighting || pawntemp.MentalStateDef != MentalStateDefOf.SocialFighting)
                {
                    pawntemp.mindState.meleeThreat             = __instance.CasterPawn;
                    pawntemp.mindState.lastMeleeThreatHarmTick = Find.TickManager.TicksGame;
                }
            }
            __instance.CasterPawn.Drawer.rotator.FaceCell(thing.Position);
            if (__instance.CasterPawn.caller != null)
            {
                __instance.CasterPawn.caller.Notify_DidMeleeAttack();
            }
            return(false);
        }
        // RimWorld.Verb_MeleeAttack
        public static void DamageInfosToApply_PostFix(Verb_MeleeAttack __instance, ref IEnumerable <DamageInfo> __result, LocalTargetInfo target)
        {
            List <DamageInfo> newList = new List <DamageInfo>();
            //__result = null;
            ThingWithComps ownerEquipment = __instance.ownerEquipment;

            if (ownerEquipment != null)
            {
                //Log.Message("1");
                ThingComp comp = ownerEquipment.AllComps.FirstOrDefault((ThingComp x) => x is CompSlotLoadable);
                if (comp != null)
                {
                    //Log.Message("2");
                    CompSlotLoadable compSlotLoadable = comp as CompSlotLoadable;
                    if (compSlotLoadable.Slots != null && compSlotLoadable.Slots.Count > 0)
                    {
                        //Log.Message("3");
                        List <SlotLoadable> statSlots = compSlotLoadable.Slots.FindAll((SlotLoadable z) => !z.IsEmpty() && ((SlotLoadableDef)z.def).doesChangeStats == true);
                        if (statSlots != null && statSlots.Count > 0)
                        {
                            //Log.Message("4");
                            foreach (SlotLoadable slot in statSlots)
                            {
                                //Log.Message("5");
                                CompSlottedBonus slotBonus = slot.SlotOccupant.TryGetComp <CompSlottedBonus>();
                                if (slotBonus != null)
                                {
                                    //Log.Message("6");
                                    Type superClass = __instance.GetType().BaseType;
                                    if (slotBonus.Props.damageDef != null)
                                    {
                                        //Log.Message("7");
                                        float            num = __instance.verbProps.AdjustedMeleeDamageAmount(__instance, __instance.CasterPawn, __instance.ownerEquipment);
                                        DamageDef        def = __instance.verbProps.meleeDamageDef;
                                        BodyPartGroupDef weaponBodyPartGroup = null;
                                        HediffDef        weaponHediff        = null;
                                        if (__instance.CasterIsPawn)
                                        {
                                            //Log.Message("8");
                                            if (num >= 1f)
                                            {
                                                weaponBodyPartGroup = __instance.verbProps.linkedBodyPartsGroup;
                                                if (__instance.ownerHediffComp != null)
                                                {
                                                    weaponHediff = __instance.ownerHediffComp.Def;
                                                }
                                            }
                                            else
                                            {
                                                num = 1f;
                                                def = DamageDefOf.Blunt;
                                            }
                                        }

                                        //Log.Message("9");
                                        ThingDef def2;
                                        if (__instance.ownerEquipment != null)
                                        {
                                            def2 = __instance.ownerEquipment.def;
                                        }
                                        else
                                        {
                                            def2 = __instance.CasterPawn.def;
                                        }

                                        //Log.Message("10");
                                        Vector3 angle = (target.Thing.Position - __instance.CasterPawn.Position).ToVector3();

                                        //Log.Message("11");
                                        Thing caster = __instance.caster;

                                        //Log.Message("12");
                                        int newdamage = GenMath.RoundRandom(num);
//                                        Log.Message("applying damage "+newdamage+" out of "+num);
                                        DamageInfo damageInfo = new DamageInfo(slotBonus.Props.damageDef, newdamage, -1f, caster, null, def2);
                                        damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                                        damageInfo.SetWeaponBodyPartGroup(weaponBodyPartGroup);
                                        damageInfo.SetWeaponHediff(weaponHediff);
                                        damageInfo.SetAngle(angle);

                                        //Log.Message("13");
                                        newList.Add(damageInfo);

                                        __result = newList.AsEnumerable <DamageInfo>();
                                    }
                                    SlotBonusProps_VampiricEffect vampiricEffect = slotBonus.Props.vampiricHealChance;
                                    if (vampiricEffect != null)
                                    {
                                        //Log.Message("vampiricHealingCalled");
                                        float randValue = Rand.Value;
                                        //Log.Message("randValue = " + randValue.ToString());

                                        if (randValue <= vampiricEffect.chance)
                                        {
                                            MoteMaker.ThrowText(__instance.CasterPawn.DrawPos, __instance.CasterPawn.Map, "Vampiric Effect: Success", 6f);
                                            //MoteMaker.ThrowText(__instance.CasterPawn.DrawPos, __instance.CasterPawn.Map, "Success".Translate(), 6f);
                                            ApplyHealing(__instance.caster, vampiricEffect.woundLimit, target.Thing);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Esempio n. 21
0
        public static void DamageInfosToApply_PostFix(Verb_MeleeAttack __instance, ref IEnumerable <DamageInfo> __result,
                                                      LocalTargetInfo target)
        {
            var equipmentSource = __instance.EquipmentSource;

            if (equipmentSource == null)
            {
                return;
            }
            var casterPawn = __instance.CasterPawn;

            if (casterPawn == null)
            {
                return;
            }

            var slots = equipmentSource.GetSlots();

            if (slots != null)
            {
                Vector3?damageAngle      = null;
                var     hediffCompSource = __instance.HediffCompSource;
                var     verbProps        = __instance.verbProps;

                List <DamageInfo> newList = null;
                foreach (var slot in slots)
                {
                    // Skip slot if doesChangeStats (defaults to false) is false.
                    if (!(slot.Def?.doesChangeStats ?? false))
                    {
                        continue;
                    }
                    var slotBonus = slot.SlotOccupant?.TryGetCompSlottedBonus();
                    if (slotBonus != null)
                    {
                        var slotBonusProps = slotBonus.Props;
                        var damageDef      = slotBonusProps.damageDef;
                        if (damageDef != null)
                        {
                            // This logic should be same as the first Verb_MeleeAttackDamage.DamageInfosToApply DamageInfo,
                            // except using damageDef (and CasterPawn always being non-null as established above).
                            var       damageAmount        = verbProps.AdjustedMeleeDamageAmount(__instance, casterPawn);
                            var       weaponBodyPartGroup = verbProps.AdjustedLinkedBodyPartsGroup(__instance.tool);
                            HediffDef weaponHediff        = null;
                            damageAmount = Rand.Range(damageAmount * MeleeDamageRandomFactorMin,
                                                      damageAmount * MeleeDamageRandomFactorMax);
                            if (damageAmount >= 1f)
                            {
                                if (hediffCompSource != null)
                                {
                                    weaponHediff = hediffCompSource.Def;
                                }
                            }
                            else
                            {
                                damageAmount = 1f;
                                damageDef    = DamageDefOf.Blunt;
                            }

                            damageAngle ??= (target.Thing.Position - casterPawn.Position).ToVector3();
                            // TODO: armorPenetration should somehow be calculated via VerbProperties.AdjustedArmorPenetration.
                            var damageInfo = new DamageInfo(damageDef, damageAmount, slotBonusProps.armorPenetration,
                                                            -1f, casterPawn, weapon: equipmentSource.def);
                            damageInfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside);
                            damageInfo.SetWeaponBodyPartGroup(weaponBodyPartGroup);
                            damageInfo.SetWeaponHediff(weaponHediff);
                            damageInfo.SetAngle(damageAngle.Value);

                            if (newList == null)
                            {
                                newList  = new List <DamageInfo>();
                                __result = newList;
                            }
                            newList.Add(damageInfo);
                        }
                        var vampiricEffect = slotBonusProps.vampiricHealChance;
                        if (vampiricEffect != null)
                        {
                            var randValue = Rand.Value;
                            //Log.Message("vampiricHealingCalled: randValue = " + randValue);
                            if (randValue <= vampiricEffect.chance)
                            {
                                MoteMaker.ThrowText(casterPawn.DrawPos, casterPawn.Map, "Vampiric Effect: Success", 6f); // TODO: Translate()?
                                damageAngle ??= (target.Thing.Position - casterPawn.Position).ToVector3();
                                ApplyHealing(casterPawn, vampiricEffect.woundLimit, vampiricEffect.amountRange, target.Pawn,
                                             vampiricEffect.damageDef, vampiricEffect.armorPenetration, damageAngle);
                            }
                        }
                    }
                }
            }
        }