コード例 #1
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (pawn != null && pawn.Map != null && pawn.health != null && pawn.health.hediffSet != null && pawn.health.hediffSet.HasHediff(TorannMagicDefOf.TM_ChiHD) && !pawn.Drafted)
            {
                if (pawn.InBed() || HealthAIUtility.ShouldSeekMedicalRest(pawn) || !(pawn.GetPosture() == PawnPosture.Standing))
                {
                    return(null);
                }
                Need_Joy curJoy = pawn.needs.joy;
                if (curJoy == null)
                {
                    return(null);
                }
                if (curJoy.CurLevel >= .8f)
                {
                    return(null);
                }
                CompAbilityUserMight comp = pawn.GetComp <CompAbilityUserMight>();
                if (comp != null)
                {
                    MightPower mightPower = comp.MightData.MightPowersM.FirstOrDefault <MightPower>((MightPower x) => x.abilityDef == TorannMagicDefOf.TM_Meditate);

                    if (mightPower == null)
                    {
                        return(null);
                    }

                    if (!mightPower.AutoCast)
                    {
                        return(null);
                    }

                    Hediff      hediff  = pawn.health.hediffSet.GetFirstHediffOfDef(TorannMagicDefOf.TM_ChiHD);
                    PawnAbility ability = pawn.GetComp <CompAbilityUserMight>().AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == TorannMagicDefOf.TM_Meditate);

                    if (ability.CooldownTicksLeft > 0 || hediff.Severity >= 70)
                    {
                        return(null);
                    }

                    Building_Bed building_Bed = pawn.ownership.OwnedBed;
                    if (building_Bed != null)
                    {
                        if (building_Bed.GetRoom() != null && !building_Bed.GetRoom().PsychologicallyOutdoors)
                        {
                            List <IntVec3> roomCells = building_Bed.GetRoom().Cells.ToList();
                            for (int i = 0; i < roomCells.Count; i++)
                            {
                                if (roomCells[i].IsValid && roomCells[i].Walkable(pawn.Map) && roomCells[i].GetFirstBuilding(pawn.Map) == null)
                                {
                                    return(new Job(TorannMagicDefOf.JobDriver_TM_Meditate, roomCells[i]));
                                }
                            }
                        }
                    }
                    return(new Job(TorannMagicDefOf.JobDriver_TM_Meditate, pawn.Position));
                }
            }
            return(null);
        }
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            bool result = false;
            Pawn pawn2  = t as Pawn;

            if (pawn.story.traits.HasTrait(WizardryDefOf.LotRW_Istari))
            {
                CompWizardry comp        = pawn.GetComp <CompWizardry>();
                PawnAbility  pawnAbility = comp.AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == WizardryDefOf.LotRW_Nienna_HealingTouch);
                if (pawn2 != null && (!this.def.tendToHumanlikesOnly || pawn2.RaceProps.Humanlike) && (!this.def.tendToAnimalsOnly || pawn2.RaceProps.Animal) && WorkGiver_Tend.GoodLayingStatusForTend(pawn2, pawn) && HasHediffInjuries(pawn2) && pawn != pawn2 && pawnAbility.CooldownTicksLeft <= 0)
                {
                    LocalTargetInfo target = pawn2;
                    if (pawn.CanReserve(target, 1, -1, null, forced))
                    {
                        return(true);
                    }
                }
            }
            return(result);
        }
コード例 #3
0
ファイル: Constants.cs プロジェクト: TorannD/TMagic
        public static int GetGizmoCount(Pawn p, PawnAbility pa)
        {
            if (iconPawn != p)
            {
                iconPawn = p;
                iconOffset.Clear();
                iconAnchorY = 0;
                iconAnchorX = 0;
            }

            if (iconOffset.ContainsKey(pa))
            {
                return(iconOffset[pa]);
            }
            else
            {
                int count = iconOffset.Count;
                iconOffset.Add(pa, count);
                return(count);
            }
        }
コード例 #4
0
        public static bool PawnAbility_GetJob_Prefix(PawnAbility __instance, AbilityContext context, LocalTargetInfo target, ref Job __result)
        {
            Job job;

            Log.Message("target is " + target.Thing.LabelShort);
            AbilityDef abilityDef = Traverse.Create(root: __instance).Field(name: "powerdef").GetValue <AbilityDef>();

            Log.Message("ability def is " + abilityDef.defName);
            Verb_UseAbility verb = Traverse.Create(root: __instance).Field(name: "verb").GetValue <Verb_UseAbility>();

            Log.Message("verb is " + verb);
            if (verb == null)
            {
                Verb_UseAbility verb_UseAbility = (Verb_UseAbility)Activator.CreateInstance(abilityDef.MainVerb.verbClass);
                verb_UseAbility.caster    = __instance.Pawn;
                verb_UseAbility.Ability   = __instance;
                verb_UseAbility.verbProps = abilityDef.MainVerb;
                verb = verb_UseAbility;
            }
            if (verb != null)
            {
                Log.Message("verb is no longer null");
            }
            job = abilityDef.GetJob(verb.UseAbilityProps.AbilityTargetCategory, target);
            job.playerForced = true;
            job.verbToUse    = verb;
            job.count        = context == AbilityContext.Player ? 1 : 0; //Count 1 for Player : 0 for AI
            if (target != null)
            {
                if (target.Thing is Pawn pawn2)
                {
                    job.killIncappedTarget = pawn2.Downed;
                }
            }
            __result = job;
            return(false);
        }
コード例 #5
0
        public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, HediffDef hediffDef, out bool success)
        {
            success = false;
            if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0)
            {
                Pawn            caster           = casterComp.Pawn;
                LocalTargetInfo jobTarget        = TM_Calc.FindNearbyPawn(caster, (int)(abilitydef.MainVerb.range * .9f));
                float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
                if (distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null && jobTarget.Thing is Pawn)
                {
                    Pawn targetPawn = jobTarget.Thing as Pawn;
                    if (targetPawn.RaceProps.Humanlike && targetPawn.IsColonist)
                    {
                        bool tatteredApparel = false;
                        //List<Thought_Memory> targetPawnThoughts = null;
                        //targetPawn.needs.mood.thoughts.GetDistinctMoodThoughtGroups(targetPawnThoughts);
                        //Log.Message("target pawn is " + targetPawn.LabelShort);
                        //List<Thought_Memory> targetPawnThoughts = targetPawn.needs.mood.thoughts.memories.Memories;
                        //for (int i = 0; i < targetPawnThoughts.Count; i++)
                        //{

                        //    if (targetPawnThoughts[i].def == ThoughtDefOf.ApparelDamaged)
                        //    {
                        //        tatteredApparel = true;
                        //    }
                        //}
                        List <Apparel> apparel = targetPawn.apparel.WornApparel;
                        for (int i = 0; i < apparel.Count; i++)
                        {
                            //Log.Message("evaluating equipment " + apparel[i].def.defName + " with hitpoint % of " + (float)(apparel[i].HitPoints/ apparel[i].MaxHitPoints) + " or " + (float)(apparel[i].HitPoints) / (float)(apparel[i].MaxHitPoints));
                            if (((float)(apparel[i].HitPoints) / (float)(apparel[i].MaxHitPoints)) < .5f)
                            {
                                tatteredApparel = true;
                            }
                        }
                        if (targetPawn.equipment.Primary != null)
                        {
                            if ((float)(targetPawn.equipment.Primary.HitPoints) / (float)(targetPawn.equipment.Primary.MaxHitPoints) < .5f)
                            {
                                tatteredApparel = true;
                            }
                        }
                        if (!targetPawn.health.hediffSet.HasHediff(hediffDef, false) && tatteredApparel)
                        {
                            Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                            caster.jobs.TryTakeOrderedJob(job);
                            success = true;
                        }
                    }
                }
            }
        }
コード例 #6
0
 public static void Evaluate(CompAbilityUserMight casterComp, TMAbilityDef abilitydef, PawnAbility ability, MightPower power, out bool success)
 {
     success = false;
     if (casterComp.Stamina.CurLevel >= abilitydef.staminaCost && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = TM_Calc.FindNearbyFighter(caster, (int)(abilitydef.MainVerb.range * 1.5f), false);
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget < (abilitydef.MainVerb.range * 1.5f) && jobTarget != null && jobTarget.Thing != null && jobTarget.Thing is Pawn)
         {
             Pawn targetPawn = jobTarget.Thing as Pawn;
             CompAbilityUserMight targetPawnComp = targetPawn.GetComp <CompAbilityUserMight>();
             if (targetPawn.CurJobDef.joyKind != null || targetPawn.CurJobDef == JobDefOf.Wait_Wander || targetPawn.CurJobDef == JobDefOf.GotoWander)
             {
                 if (targetPawn.IsColonist && targetPawnComp.MightUserLevel < casterComp.MightUserLevel && caster.relations.OpinionOf(targetPawn) >= 0)
                 {
                     Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                     caster.jobs.TryTakeOrderedJob(job);
                     success = true;
                 }
             }
         }
     }
 }
コード例 #7
0
        public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, out bool success)
        {
            success = false;
            Pawn            caster    = casterComp.Pawn;
            LocalTargetInfo jobTarget = caster;

            if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0 && jobTarget.Thing != null)
            {
                float injurySeverity = 0;
                using (IEnumerator <BodyPartRecord> enumerator = caster.health.hediffSet.GetInjuredParts().GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        BodyPartRecord rec = enumerator.Current;
                        IEnumerable <Hediff_Injury> arg_BB_0 = caster.health.hediffSet.GetHediffs <Hediff_Injury>();
                        Func <Hediff_Injury, bool>  arg_BB_1;
                        arg_BB_1 = ((Hediff_Injury injury) => injury.Part == rec);

                        foreach (Hediff_Injury current in arg_BB_0.Where(arg_BB_1))
                        {
                            bool flag5 = current.CanHealNaturally() && !current.IsPermanent();
                            if (flag5)
                            {
                                injurySeverity += current.Severity;
                            }
                        }
                    }
                }
                if (injurySeverity != 0 && !(caster.health.hediffSet.HasHediff(HediffDef.Named("TM_HediffShield"))))
                {
                    Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                    caster.jobs.TryTakeOrderedJob(job);
                    success = true;
                }
            }
        }
コード例 #8
0
        public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, out bool success)
        {
            success = false;
            Pawn            caster    = casterComp.Pawn;
            LocalTargetInfo jobTarget = caster.Position;

            if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0 && jobTarget != null)
            {
                Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                caster.jobs.TryTakeOrderedJob(job);
                success = true;
            }
        }
        public override AbilityAIDef TryPickAbility(Pawn caster)
        {
            //Get all eligible abilities.
            IEnumerable <AbilityAIDef> abilities =
                from validAbilityDef in
                //Initial filtering.
                (from abilityAIDef in profileDef.abilities
                 //where tags.FindAll(tag => tags.Contains(tag))?.Count() >= tags.Count
                 where tags.FindAll(tag => abilityAIDef.tags.Contains(tag))?.Count() >= tags.Count
                 select abilityAIDef)
                //Blacklist filtering.
                where !validAbilityDef.tags.Any(tag => blacklistedTags.Contains(tag))
                select validAbilityDef;

            //Debug
            //Log.Message("-=abilities list=-");
            //GenDebug.LogList(abilities);

            if (abilities != null)
            {
                //Filter out abilities we do not have.
                ThingComp       thingComp       = caster.AllComps.First(comp => comp.GetType() == profileDef.compAbilityUserClass);
                CompAbilityUser compAbilityUser = thingComp as CompAbilityUser;

                IEnumerable <AbilityAIDef> knownAbilities =
                    from abilityAIDef in abilities
                    from abilityUserAbility in compAbilityUser.AbilityData.AllPowers
                    where abilityAIDef.ability == abilityUserAbility.Def && profileDef.Worker.CanUseAbility(profileDef, caster, abilityAIDef)
                    orderby abilityAIDef.Worker.PowerScoreFor(abilityAIDef, caster) descending
                    select abilityAIDef;

                //Debug
                //Log.Message("-=knownAbilities list=-");
                //GenDebug.LogList(knownAbilities);

                if (compAbilityUser != null)
                {
                    if (knownAbilities != null && knownAbilities.Count() > 0)
                    {
                        //Return highest power ability which can be cast.
                        foreach (AbilityAIDef ability in knownAbilities)
                        {
                            string reason = "";

                            //Log.Message("-=AbilityVerbs list=-");
                            //GenDebug.LogList(compAbilityUser.AbilityVerbs);

                            //Can we cast the ability in the implementation of it?
                            PawnAbility     pawnAbility = compAbilityUser.AbilityData.AllPowers.First(pawnAbilityInt => pawnAbilityInt.Def == ability.ability);
                            Verb_UseAbility abilityVerb = pawnAbility.Verb; //.First(abilityIntVerb => abilityIntVerb.Ability.Def == ability.ability);

                            //Log.Message("abilityVerb=" + abilityVerb.ability.powerdef.defName);
                            if (compAbilityUser.CanCastPowerCheck(abilityVerb, out reason) /*&& !pawnAbility.NeedsCooldown*/) //To-Do: Put back check after Ability Framework redesign.
                            {
                                //Debug
                                //Log.Message("Can cast abilityVerb=" + abilityVerb.ability.powerdef.defName);

                                if (ability.usedOnCaster)
                                {
                                    //Target self.
                                    if (ability.CanPawnUseThisAbility(caster, caster))
                                    {
                                        return(ability);
                                    }
                                }
                                else if (ability.needEnemyTarget)
                                {
                                    //Enemy target specific.
                                    if (caster.mindState.enemyTarget != null && ability.CanPawnUseThisAbility(caster, caster.mindState.enemyTarget))
                                    {
                                        return(ability);
                                    }
                                }
                                else
                                {
                                    //Need no target.
                                    if (ability.CanPawnUseThisAbility(caster, LocalTargetInfo.Invalid))
                                    {
                                        return(ability);
                                    }
                                }
                            }
                            else
                            {
                                //Debug
                                //Log.Message("Can't cast abilityVerb=" + abilityVerb.ability.powerdef.defName + ", with reason: " + reason.Translate(abilityVerb.caster.ToString()));
                            }
                        }
                    }
                }
            }

            return(null);
        }
コード例 #10
0
 public static void TryExecute(CompAbilityUserMight casterComp, TMAbilityDef abilitydef, PawnAbility ability, MightPower power, LocalTargetInfo target, int minRange, out bool success)
 {
     success = false;
     if (casterComp.Stamina.CurLevel >= abilitydef.staminaCost && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = target;
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget > minRange && distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null && TM_Calc.HasLoSFromTo(caster.Position, jobTarget, caster, 0, abilitydef.MainVerb.range))
         {
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             job.endIfCantShootTargetFromCurPos = true;
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
         }
     }
 }
コード例 #11
0
 public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, out bool success)
 {
     success = false;
     EvaluateMinRange(casterComp, abilitydef, ability, power, 6f, out success);
 }
コード例 #12
0
        public void ClearSpellRemnants(CompAbilityUserMagic comp)
        {
            if (comp != null)
            {
                if (comp.Pawn.equipment != null && comp.Pawn.equipment.Primary != null && comp.Pawn.equipment.Primary.def.defName.Contains("TM_TechnoWeapon_Base"))
                {
                    comp.technoWeaponThing    = null;
                    comp.technoWeaponThingDef = null;
                    comp.technoWeaponDefNum   = -1;
                    if (!comp.Pawn.equipment.Primary.DestroyedOrNull())
                    {
                        comp.Pawn.equipment.Primary.Destroy(DestroyMode.Vanish);
                    }
                }

                if (comp.MagicUserLevel >= 20)
                {
                    PawnAbility pa = comp.AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == TorannMagicDefOf.TM_TeachMagic);
                    if (pa != null)
                    {
                        pa.CooldownTicksLeft = Mathf.RoundToInt(pa.MaxCastingTicks * comp.coolDown);
                    }
                }

                if (comp.earthSprites != IntVec3.Invalid || comp.earthSpriteType != 0)
                {
                    comp.earthSpriteType    = 0;
                    comp.earthSpriteMap     = null;
                    comp.earthSprites       = IntVec3.Invalid;
                    comp.earthSpritesInArea = false;
                }

                if (comp.stoneskinPawns != null && comp.stoneskinPawns.Count > 0)
                {
                    for (int i = 0; i < comp.stoneskinPawns.Count; i++)
                    {
                        if (comp.stoneskinPawns[i].health.hediffSet.HasHediff(TorannMagicDefOf.TM_StoneskinHD))
                        {
                            Hediff hd = comp.stoneskinPawns[i].health?.hediffSet?.GetFirstHediffOfDef(TorannMagicDefOf.TM_StoneskinHD);
                            if (hd != null)
                            {
                                comp.stoneskinPawns[i].health.RemoveHediff(hd);
                            }
                        }
                    }
                }

                if (comp.weaponEnchants != null && comp.weaponEnchants.Count > 0)
                {
                    for (int i = 0; i < comp.weaponEnchants.Count; i++)
                    {
                        Verb_DispelEnchantWeapon.RemoveExistingEnchantment(comp.weaponEnchants[i]);
                    }
                    comp.weaponEnchants.Clear();
                    comp.RemovePawnAbility(TorannMagicDefOf.TM_DispelEnchantWeapon);
                }

                if (comp.enchanterStones != null && comp.enchanterStones.Count > 0)
                {
                    for (int i = 0; i < comp.enchanterStones.Count; i++)
                    {
                        if (comp.enchanterStones[i].Map != null)
                        {
                            TM_Action.TransmutateEffects(comp.enchanterStones[i].Position, comp.Pawn);
                        }
                        comp.enchanterStones[i].Destroy(DestroyMode.Vanish);
                    }
                    comp.enchanterStones.Clear();
                    comp.RemovePawnAbility(TorannMagicDefOf.TM_DismissEnchanterStones);
                }

                if (comp.summonedSentinels != null && comp.summonedSentinels.Count > 0)
                {
                    for (int i = 0; i < comp.summonedSentinels.Count; i++)
                    {
                        if (comp.summonedSentinels[i].Map != null)
                        {
                            TM_Action.TransmutateEffects(comp.summonedSentinels[i].Position, comp.Pawn);
                        }
                        comp.summonedSentinels[i].Destroy(DestroyMode.Vanish);
                    }
                    comp.summonedSentinels.Clear();
                    comp.RemovePawnAbility(TorannMagicDefOf.TM_ShatterSentinel);
                }

                if (comp.soulBondPawn != null)
                {
                    comp.soulBondPawn = null;
                }
            }
        }
コード例 #13
0
 public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, HediffDef hediffDef, out bool success)
 {
     success = false;
     EvaluateMinSeverity(casterComp, abilitydef, ability, power, hediffDef, 0, out success);
 }
コード例 #14
0
 public static void EvaluateMinSeverity(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, float minSeverity, out bool success)
 {
     success = false;
     if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = TM_Calc.FindNearbyPermanentlyInjuredPawn(caster, (int)(abilitydef.MainVerb.range * .9f), minSeverity);
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null)
         {
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
             TM_Action.TM_Toils.GotoAndWait(jobTarget.Thing as Pawn, caster, Mathf.RoundToInt(ability.Def.MainVerb.warmupTime * 60));
         }
     }
 }
コード例 #15
0
 public static void EvaluateMinSeverity(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, float minSeverity, out bool success)
 {
     success = false;
     if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = TM_Calc.FindNearbyInjuredPawn(caster, (int)(abilitydef.MainVerb.range * .9f), minSeverity);
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null)
         {
             if (abilitydef == TorannMagicDefOf.TM_CauterizeWound && jobTarget.Thing is Pawn)
             {
                 Pawn targetPawn = jobTarget.Thing as Pawn;
                 if (targetPawn.health.HasHediffsNeedingTend(false))
                 {
                     Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                     job.endIfCantShootTargetFromCurPos = true;
                     caster.jobs.TryTakeOrderedJob(job);
                     success = true;
                 }
             }
             else
             {
                 Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                 caster.jobs.TryTakeOrderedJob(job);
                 success = true;
             }
         }
     }
 }
コード例 #16
0
 public static void EvaluateMinRange(CompAbilityUserMight casterComp, TMAbilityDef abilitydef, PawnAbility ability, MightPower power, float minRange, out bool success)
 {
     success = false;
     if (casterComp.Stamina.CurLevel >= abilitydef.staminaCost && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster    = casterComp.Pawn;
         LocalTargetInfo jobTarget = TM_Calc.FindNearbyEnemy(caster, (int)(abilitydef.MainVerb.range * .9f));
         if (jobTarget != null && jobTarget.Thing != null && abilitydef == TorannMagicDefOf.TM_AntiArmor)
         {
             Pawn targetPawn = jobTarget.Thing as Pawn;
             if (targetPawn.RaceProps.IsFlesh)
             {
                 jobTarget = null;
             }
         }
         float distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (jobTarget != null && jobTarget.Thing != null && (distanceToTarget > minRange && distanceToTarget < (abilitydef.MainVerb.range * .9f)) && TM_Calc.HasLoSFromTo(caster.Position, jobTarget, caster, 0, abilitydef.MainVerb.range))
         {
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             job.endIfCantShootTargetFromCurPos = true;
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
         }
     }
 }
コード例 #17
0
 public static void Evaluate(CompAbilityUserMight mightComp, TMAbilityDef abilitydef, PawnAbility ability, MightPower power, int minTargetCount, int radiusAround, IntVec3 evaluatedCenter, bool hostile, out bool success)
 {
     success = false;
     if (mightComp.Stamina.CurLevel >= abilitydef.staminaCost && ability.CooldownTicksLeft <= 0)
     {
         Pawn        caster     = mightComp.Pawn;
         List <Pawn> targetList = TM_Calc.FindPawnsNearTarget(caster, radiusAround, evaluatedCenter, hostile);
         if (targetList != null)
         {
             LocalTargetInfo jobTarget = null;
             if (targetList.Count >= minTargetCount && (abilitydef == TorannMagicDefOf.TM_BladeSpin))
             {
                 jobTarget = caster;
             }
             if (jobTarget != null && jobTarget.Thing != caster)
             {
                 float distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
             }
             if (jobTarget != null && jobTarget.Thing != null)
             {
                 Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                 caster.jobs.TryTakeOrderedJob(job);
                 success = true;
             }
         }
     }
 }
コード例 #18
0
        public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, float minDistance, out bool success)
        {
            success = false;
            Pawn            caster       = casterComp.Pawn;
            LocalTargetInfo jobTarget    = caster.CurJob.targetA;
            Thing           carriedThing = null;

            if (caster.CurJob.targetA.Thing != null)               //&& caster.CurJob.def.defName != "Sow")
            {
                if (caster.CurJob.targetA.Thing.Map != caster.Map) //carrying thing
                {
                    jobTarget    = caster.CurJob.targetB;
                    carriedThing = caster.CurJob.targetA.Thing;
                }
                else if (caster.CurJob.targetB != null && caster.CurJob.targetB.Thing != null && caster.CurJob.def != JobDefOf.Rescue) //targetA using targetB for job
                {
                    if (caster.CurJob.targetB.Thing.Map != caster.Map)                                                                 //carrying targetB to targetA
                    {
                        jobTarget    = caster.CurJob.targetA;
                        carriedThing = caster.CurJob.targetB.Thing;
                    }
                    else if (caster.CurJob.def == JobDefOf.TendPatient)
                    {
                        jobTarget = caster.CurJob.targetB;
                    }
                    else //Getting targetA to carry to TargetB
                    {
                        jobTarget = caster.CurJob.targetA;
                    }
                }
                else
                {
                    jobTarget = caster.CurJob.targetA;
                }
            }
            float   distanceToTarget  = (jobTarget.Cell - caster.Position).LengthHorizontal;
            Vector3 directionToTarget = TM_Calc.GetVector(caster.Position, jobTarget.Cell);

            //Log.Message("" + caster.LabelShort + " job def is " + caster.CurJob.def.defName + " targetA " + caster.CurJob.targetA + " targetB " + caster.CurJob.targetB + " jobTarget " + jobTarget + " at distance " + distanceToTarget + " min distance " + minDistance + " at vector " + directionToTarget);
            if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0 && distanceToTarget < 200)
            {
                if (distanceToTarget > minDistance && caster.CurJob.locomotionUrgency >= LocomotionUrgency.Jog && caster.CurJob.bill == null)
                {
                    if (distanceToTarget <= abilitydef.MainVerb.range && jobTarget.Cell != default(IntVec3))
                    {
                        //Log.Message("doing blink to thing");
                        DoBlink(caster, jobTarget.Cell, ability, carriedThing);
                        success = true;
                    }
                    else
                    {
                        IntVec3 blinkToCell = caster.Position + (directionToTarget * abilitydef.MainVerb.range).ToIntVec3();
                        //Log.Message("doing partial blink to cell " + blinkToCell);
                        //MoteMaker.ThrowHeatGlow(blinkToCell, caster.Map, 1f);
                        if (blinkToCell.IsValid && blinkToCell.InBounds(caster.Map) && blinkToCell.Walkable(caster.Map) && !blinkToCell.Fogged(caster.Map) && ((blinkToCell - caster.Position).LengthHorizontal < distanceToTarget))
                        {
                            DoBlink(caster, blinkToCell, ability, carriedThing);
                            success = true;
                        }
                    }
                }
            }
        }
コード例 #19
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            //Do we have at least one elegible profile?
            IEnumerable <AbilityUserAIProfileDef> profiles = pawn.EligibleAIProfiles();

            /*StringBuilder builder = new StringBuilder("profiles = ");
             *
             * foreach(AbilityUserAIProfileDef profile in profiles)
             * {
             *  builder.Append(profile.defName + ", ");
             * }
             *
             * Log.Message(builder.ToString());*/

            if (profiles != null && profiles.Count() > 0)
            {
                //No Job to give. Yet.
                //Go through all available Profiles in order to find a Ability to use.
                foreach (AbilityUserAIProfileDef profile in profiles)
                {
                    if (profile != null)
                    {
                        //Traverse the decision tree.
                        //List<AbilityDecisionNode> currentNodes = new List<AbilityDecisionNode>();
                        //List<AbilityDecisionNode> nextNodes = new List<AbilityDecisionNode>();

                        //Seed root.
                        //nextNodes.Add(profile.decisionTree);

                        //Result AbilityAIDef to use.
                        AbilityAIDef useThisAbility = null;

                        if (profile.decisionTree != null)
                        {
                            useThisAbility = profile.decisionTree.RecursivelyGetAbility(pawn);
                        }

                        //Debug

                        /*int nodesTraversed = 0;
                         * AbilityDecisionNode lastNode = null;
                         *
                         * //Flat recursive iteration
                         * do
                         * {
                         *  //Add from next list to current list.
                         *  currentNodes.AddRange(nextNodes);
                         *  nextNodes.Clear();
                         *
                         *  //Check if we can continue traversing on the current level.
                         *  foreach (AbilityDecisionNode currentNode in currentNodes)
                         *  {
                         *      nodesTraversed++;
                         *
                         *      if (currentNode.CanContinueTraversing(pawn))
                         *          nextNodes.AddRange(currentNode.subNodes);
                         *
                         *      //Try picking an ability.
                         *      useThisAbility = currentNode.TryPickAbility(pawn);
                         *
                         *      //Found ability to use.
                         *      if (useThisAbility != null)
                         *      {
                         *          lastNode = currentNode;
                         *          break;
                         *      }
                         *  }
                         *
                         *  //Found ability to use.
                         *  if (useThisAbility != null)
                         *      break;
                         *
                         *  //Clear current set.
                         *  currentNodes.Clear();
                         * } while (nextNodes.Count > 0);*/

                        //Debug
                        //if (useThisAbility != null)
                        //    Log.Message("JobGiver_AIAbilityUser.TryGiveJob for '" + pawn.ThingID + "' with ability: " + useThisAbility.defName + ", while traversing " + nodesTraversed + " nodes.");
                        //else
                        //    Log.Message("JobGiver_AIAbilityUser.TryGiveJob for '" + pawn.ThingID + "' with ability: No ability, while traversing " + nodesTraversed + " nodes.");

                        if (useThisAbility != null)
                        {
                            //Debug

                            /*Log.Message("Ability '" + useThisAbility.defName + "' picked for AI.\n" +
                             *  "lastNode=" + lastNode.GetType().Name + "\n" +
                             *  "lastNode.parent=" + lastNode?.parent?.GetType()?.Name);*/

                            //Get CompAbilityUser
                            ThingComp       thingComp       = pawn.AllComps.First(comp => comp.GetType() == profile.compAbilityUserClass);
                            CompAbilityUser compAbilityUser = thingComp as CompAbilityUser;

                            if (compAbilityUser != null)
                            {
                                //Get Ability from Pawn.
                                PawnAbility useAbility = compAbilityUser.AbilityData.AllPowers.First(ability => ability.Def == useThisAbility.ability);

                                string reason = "";
                                //Give job.
                                if (useAbility.CanCastPowerCheck(AbilityContext.AI, out reason))
                                {
                                    LocalTargetInfo target = useThisAbility.Worker.TargetAbilityFor(useThisAbility, pawn);
                                    if (target.IsValid)
                                    {
                                        return(useAbility.UseAbility(AbilityContext.AI, target));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //No Job to give.
            //Report.
            //Log.Message("JobGiver_AIAbilityUser.TryGiveJob for '" + pawn.ThingID + "' is Invalid.");
            return(null);
        }
コード例 #20
0
        private static void DoPhase(Pawn caster, IntVec3 targetCell, PawnAbility ability, Thing carriedThing)
        {
            JobDef          retainJobDef  = caster.CurJobDef;
            LocalTargetInfo retainTargetA = caster.CurJob.targetA;
            int             retainCount   = 1;

            if (retainTargetA.Thing != null && retainTargetA.Thing.stackCount != 1)
            {
                retainCount = retainTargetA.Thing.stackCount;
            }
            LocalTargetInfo retainTargetB = caster.CurJob.targetB;
            LocalTargetInfo retainTargetC = caster.CurJob.targetC;
            Pawn            p             = caster;
            Thing           cT            = carriedThing;

            if (cT != null && cT.stackCount != 1)
            {
                retainCount = cT.stackCount;
            }
            Map     map          = caster.Map;
            IntVec3 casterCell   = caster.Position;
            bool    selectCaster = false;

            if (Find.Selector.FirstSelectedObject == caster)
            {
                selectCaster = true;
            }
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    TM_MoteMaker.ThrowGenericMote(ThingDefOf.Mote_Smoke, caster.DrawPos, caster.Map, Rand.Range(.6f, 1f), .4f, .1f, Rand.Range(.8f, 1.2f), 0, Rand.Range(2, 3), Rand.Range(-30, 30), 0);
                    TM_MoteMaker.ThrowGenericMote(TorannMagicDefOf.Mote_Enchanting, caster.DrawPos, caster.Map, Rand.Range(1.4f, 2f), .2f, .05f, Rand.Range(.4f, .6f), Rand.Range(-200, 200), 0, 0, 0);
                }

                caster.DeSpawn();
                GenSpawn.Spawn(p, targetCell, map);
                if (carriedThing != null)
                {
                    carriedThing.DeSpawn();
                    GenPlace.TryPlaceThing(cT, targetCell, map, ThingPlaceMode.Near);
                    //GenSpawn.Spawn(cT, targetCell, map);
                }

                caster.GetComp <CompAbilityUserMight>().MightUserXP -= 50;
                ability.PostAbilityAttempt();
                if (selectCaster)
                {
                    Find.Selector.Select(caster, false, true);
                }
                for (int i = 0; i < 3; i++)
                {
                    TM_MoteMaker.ThrowGenericMote(ThingDefOf.Mote_Smoke, caster.DrawPos, caster.Map, Rand.Range(.6f, 1f), .4f, .1f, Rand.Range(.8f, 1.2f), 0, Rand.Range(2, 3), Rand.Range(-30, 30), 0);
                    TM_MoteMaker.ThrowGenericMote(TorannMagicDefOf.Mote_Enchanting, caster.DrawPos, caster.Map, Rand.Range(1.4f, 2f), .2f, .05f, Rand.Range(.4f, .6f), Rand.Range(-200, 200), 0, 0, 0);
                }

                Job job = new Job(retainJobDef, retainTargetA, retainTargetB, retainTargetC)
                {
                    count        = retainCount,
                    playerForced = false
                };
                //caster.jobs.TryTakeOrderedJob();

                caster.jobs.StartJob(job);
            }
            catch
            {
                if (!caster.Spawned)
                {
                    GenSpawn.Spawn(p, casterCell, map);
                }
            }
        }
コード例 #21
0
 public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, bool inCombat, bool reverse, out bool success) //reverse == true transfers mana to caster
 {
     success = false;
     if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster    = casterComp.Pawn;
         LocalTargetInfo jobTarget = TM_Calc.FindNearbyMage(caster, (int)(abilitydef.MainVerb.range * .9f), inCombat);
         if (!inCombat && jobTarget != null && jobTarget.Thing != null)
         {
             Pawn transferPawn          = jobTarget.Thing as Pawn;
             CompAbilityUserMagic tComp = transferPawn.GetComp <CompAbilityUserMagic>();
             if (reverse)
             {
                 if (casterComp.Mana.CurLevel >= .3f || tComp.Mana.CurLevel <= .9f)
                 {
                     jobTarget = null;
                 }
             }
             else
             {
                 if (casterComp.Mana.CurLevel <= .9f || tComp.Mana.CurLevel >= .9f)
                 {
                     jobTarget = null;
                 }
             }
         }
         float distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null)
         {
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
         }
     }
 }
コード例 #22
0
 public static void TryExecute(CompAbilityUser casterComp, AbilityDef abilitydef, PawnAbility ability, LocalTargetInfo target, int minRange, out bool success)
 {
     success = false;
     if (ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = target;
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget > minRange && distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null && Functions.Eval.HasLoSFromTo(caster.Position, jobTarget, caster, 0, abilitydef.MainVerb.range))
         {
             Log.Message("ability is " + ability.Def.defName + " target is " + jobTarget.Thing.LabelShort + " caster job is " + caster.CurJob);
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             Log.Message("job is " + job);
             job.endIfCantShootTargetFromCurPos = true;
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
         }
         //a small change to test a push
     }
 }
コード例 #23
0
        public static void Evaluate(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, float minDistance, out bool success)
        {
            success = false;
            Pawn            caster            = casterComp.Pawn;
            LocalTargetInfo jobTarget         = caster.CurJob.targetA;
            float           distanceToTarget  = (jobTarget.Cell - caster.Position).LengthHorizontal;
            Vector3         directionToTarget = TM_Calc.GetVector(caster.Position, jobTarget.Cell);

            if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0 && jobTarget.Thing != null && jobTarget.Thing.def.EverHaulable)
            {
                //Log.Message("summon: " + caster.LabelShort + " job def is " + caster.CurJob.def.defName + " targetA " + caster.CurJob.targetA + " targetB " + caster.CurJob.targetB + " jobTarget " + jobTarget + " at distance " + distanceToTarget + " min distance " + minDistance + " at vector " + directionToTarget);
                if (distanceToTarget > minDistance && distanceToTarget < abilitydef.MainVerb.range && caster.CurJob.locomotionUrgency >= LocomotionUrgency.Jog && caster.CurJob.bill == null && distanceToTarget < 200)
                {
                    Job job = ability.GetJob(AbilityContext.AI, jobTarget);
                    caster.jobs.TryTakeOrderedJob(job);
                    success = true;
                }
            }
        }
コード例 #24
0
 public static void EvaluateMinRange(CompAbilityUserMagic casterComp, TMAbilityDef abilitydef, PawnAbility ability, MagicPower power, float minRange, out bool success)
 {
     success = false;
     if (casterComp.Mana.CurLevel >= casterComp.ActualManaCost(abilitydef) && ability.CooldownTicksLeft <= 0)
     {
         Pawn            caster           = casterComp.Pawn;
         LocalTargetInfo jobTarget        = TM_Calc.FindNearbyEnemy(caster, (int)(abilitydef.MainVerb.range * .9f));
         float           distanceToTarget = (jobTarget.Cell - caster.Position).LengthHorizontal;
         if (distanceToTarget > minRange && distanceToTarget < (abilitydef.MainVerb.range * .9f) && jobTarget != null && jobTarget.Thing != null && TM_Calc.HasLoSFromTo(caster.Position, jobTarget, caster, 0, abilitydef.MainVerb.range))
         {
             Job job = ability.GetJob(AbilityContext.AI, jobTarget);
             job.endIfCantShootTargetFromCurPos = true;
             caster.jobs.TryTakeOrderedJob(job);
             success = true;
         }
     }
 }
コード例 #25
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Pawn patient     = TargetA.Thing as Pawn;
            Toil gotoPatient = new Toil()
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetA, PathEndMode.Touch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(gotoPatient);

            Toil doHealing = new Toil();

            doHealing.initAction = delegate
            {
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                if (patient.DestroyedOrNull() || patient.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
            };
            doHealing.tickAction = delegate
            {
                if (patient.DestroyedOrNull() || patient.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
                if (Find.TickManager.TicksGame % 1 == 0)
                {
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingMote"), this.pawn.DrawPos, this.Map, Rand.Range(.3f, .5f), (Quaternion.AngleAxis(90, Vector3.up) * GetVector(this.pawn.Position, patient.Position)).ToAngleFlat() + Rand.Range(-10, 10), 5f, 0);
                }
                if (age > (lastHeal + ticksTillNextHeal))
                {
                    DoHealingEffect(patient);
                    EffectMaker.MakeEffect(ThingDef.Named("Mote_HealingCircles"), patient.DrawPos, this.Map, Rand.Range(.3f, .4f), 0, 0, Rand.Range(400, 500), Rand.Range(0, 360), .08f, .01f, .24f, false);
                    lastHeal = age;
                    if (this.injuryCount == 0)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
                if (!patient.Drafted && patient.CurJobDef != JobDefOf.Wait)
                {
                    if (patient.jobs.posture == PawnPosture.Standing)
                    {
                        Job job = new Job(JobDefOf.Wait, patient);
                        patient.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                    }
                }
                age++;
                ticksLeftThisToil = duration - age;
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            doHealing.defaultCompleteMode = ToilCompleteMode.Delay;
            doHealing.defaultDuration     = this.duration;
            doHealing.WithProgressBar(TargetIndex.B, delegate
            {
                if (this.pawn.DestroyedOrNull() || this.pawn.Dead)
                {
                    return(1f);
                }
                return(1f - (float)doHealing.actor.jobs.curDriver.ticksLeftThisToil / this.duration);
            }, false, 0f);
            doHealing.AddFinishAction(delegate
            {
                CompWizardry comp       = pawn.GetComp <CompWizardry>();
                PawnAbility pawnAbility = comp.AbilityData.Powers.FirstOrDefault((PawnAbility x) => x.Def == WizardryDefOf.LotRW_Nienna_HealingTouch);
                pawnAbility.PostAbilityAttempt();
                patient.jobs.EndCurrentJob(JobCondition.Succeeded, true);
            });
            yield return(doHealing);
        }