private void FightTarget(Pawn fighter, LocalTargetInfo targetInfo) { Verb attackVerb = null; if (fighter != null) { attackVerb = fighter.TryGetAttackVerb(targetInfo.Thing, false); } if (attackVerb != null) { // Only added because the TryStartCast does throw an error that I can't find.. // This is the WorkAround for the unexplainable Melee-Verb-Error // ================================ if (fighter.stances.FullBodyBusy) { return; } SoundDef soundDef; if (Rand.Value >= 0.6f) { soundDef = SoundDef.Named("Pawn_Melee_Punch_HitBuilding"); fighter.skills.Learn(SkillDefOf.Melee, 25f); } else { soundDef = SoundDef.Named("Pawn_Melee_Punch_Miss"); fighter.skills.Learn(SkillDefOf.Melee, 10f); } soundDef.PlayOneShot(new TargetInfo(targetInfo.Cell, Map, false)); Stance_Cooldown stance_Cooldown = fighter.stances.curStance as Stance_Cooldown; if (stance_Cooldown == null || stance_Cooldown.ticksLeft >= 50) { fighter.stances.SetStance(new Stance_Cooldown(50, targetInfo, attackVerb)); } // ================================ // Original: // This would be the original code, if the Melee-Verb-Error wouldn't come.. //attackVerb.TryStartCastOn(targetInfo); // Throws NullReference -> Why, can't locate origin??? - Also throws error 'PAWN meleed OBJECT from out of melee position.' -> WHY, I'm standing right next to it??? } // increase the experienced xp int ticksSinceLastShot = GenTicks.TicksAbs - lastTick; lastTick = GenTicks.TicksAbs; if (ticksSinceLastShot > 2000) { ticksSinceLastShot = 0; } if (fighter.CurJob.def.joySkill != null) { fighter.skills.GetSkill(fighter.CurJob.def.joySkill).Learn(fighter.CurJob.def.joyXpPerTick * ticksSinceLastShot); } }
public static void WeaponTrainingAnimation(Pawn pawn, LocalTargetInfo target, Verb verbToUse, int ticksSpentAlready) { Stance_Cooldown stance = pawn.stances.curStance as Stance_Cooldown; if (stance != null) { stance.ticksLeft++; } else { pawn.stances.SetStance(new Stance_Cooldown(2, target, verbToUse)); } if (verbToUse.verbProps != null && verbToUse.verbProps.warmupTime > 0) { int warmup = (int)(verbToUse.verbProps.AdjustedFullCycleTime(verbToUse, pawn).SecondsToTicks() * warmupSoundFactor); if ((ticksSpentAlready % warmup) == 0) { if (verbToUse.verbProps.soundCast != null) { verbToUse.verbProps.soundCast.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false)); } if (verbToUse.verbProps.soundCastTail != null) { verbToUse.verbProps.soundCastTail.PlayOneShotOnCamera(pawn.Map); } } } }
public void UpdateState() { var holder = ParentHolder as Pawn_EquipmentTracker; if (holder == null) { return; } Stance stance = holder.pawn.stances.curStance; Stance_Warmup warmup; switch (state) { case State.Idle: warmup = stance as Stance_Warmup; if (warmup != null) { state = State.Priming; ReachPosition(1.0f, warmup.ticksLeft); } break; case State.Priming: if (IsBrusting(holder.pawn)) { state = State.Primed; } else { warmup = stance as Stance_Warmup; if (warmup == null) { state = State.Idle; ReachPosition(0.0f, TicksToIdle); } } break; case State.Primed: if (!IsBrusting(holder.pawn)) { state = State.Idle; Stance_Cooldown cooldown = stance as Stance_Cooldown; if (cooldown != null) { ReachPosition(0.0f, cooldown.ticksLeft); } else { ReachPosition(0.0f, 0); } } break; } }
public override void UpdateState() { var holder = ParentHolder as Pawn_EquipmentTracker; if (holder == null) { return; } Stance stance = holder.pawn.stances.curStance; Stance_Warmup warmup; switch (state) { case State.Idle: warmup = stance as Stance_Warmup; if (warmup != null) { state = State.Spinup; ReachRotationSpeed(def.rotationSpeed, warmup.ticksLeft); } break; case State.Spinup: if (IsBrusting(holder.pawn)) { state = State.Spinning; } else { warmup = stance as Stance_Warmup; if (warmup == null) { state = State.Idle; ReachRotationSpeed(0.0f, 30); } } break; case State.Spinning: if (!IsBrusting(holder.pawn)) { state = State.Idle; Stance_Cooldown cooldown = stance as Stance_Cooldown; if (cooldown != null) { ReachRotationSpeed(0.0f, cooldown.ticksLeft); } else { ReachRotationSpeed(0.0f, 0); } } break; } }
public static void SetStanceRunAndGun(Pawn_StanceTracker stanceTracker, Stance_Cooldown stance) { if (stanceTracker.pawn.equipment == null) { stanceTracker.SetStance(stance); return; } if (stanceTracker.pawn.equipment.Primary == stance.verb.EquipmentSource || stance.verb.EquipmentSource == null) { if ((((stanceTracker.curStance is Stance_RunAndGun) || (stanceTracker.curStance is Stance_RunAndGun_Cooldown))) && stanceTracker.pawn.pather.Moving) { stanceTracker.SetStance(new Stance_RunAndGun_Cooldown(stance.ticksLeft, stance.focusTarg, stance.verb)); } else { stanceTracker.SetStance(stance); } } }
public static void SetStanceOffHand(Pawn_StanceTracker stanceTracker, Stance_Cooldown stance) { ThingWithComps offHandEquip = null; CompEquippable compEquippable = null; if (stance.verb.EquipmentSource != null && Base.Instance.GetExtendedDataStorage().TryGetExtendedDataFor(stance.verb.EquipmentSource, out ExtendedThingWithCompsData twcdata) && twcdata.isOffHand) { offHandEquip = stance.verb.EquipmentSource; compEquippable = offHandEquip.TryGetComp <CompEquippable>(); } //Check if verb is one from a offhand weapon. if (compEquippable != null && offHandEquip != stanceTracker.pawn.equipment.Primary) //TODO: check this code { stanceTracker.pawn.GetStancesOffHand().SetStance(stance); } else if (!(stanceTracker.curStance is Stance_Cooldown) && stanceTracker.curStance.GetType().Name != "Stance_RunAndGun_Cooldown") { stanceTracker.SetStance(stance); } }
//When Run and Gun or the to be patched method isn't found, patch this stub method so no error is thrown. public static void Stub(Pawn_StanceTracker stanceTracker, Stance_Cooldown stance) { //Do nothing }
static void Postfix(Pawn_StanceTracker stanceTracker, Stance_Cooldown stance) { //Make sure this is called when run and gun patches the same line of code as we do in the harmony Patch Verb_TryCastNextBurstShot. //SetStanceOffHand(stanceTracker, stance); Verb_TryCastNextBurstShot.SetStanceOffHand(stanceTracker, stance); }
private void TryEnterNextPathCell() { Building building = this.BuildingBlockingNextPathCell(); if (building != null) { Building_Door building_Door = building as Building_Door; if (building_Door == null || !building_Door.FreePassage) { if ((this.pawn.CurJob != null && this.pawn.CurJob.canBash) || this.pawn.HostileTo(building)) { Job job = new Job(JobDefOf.AttackMelee, building); job.expiryInterval = 300; this.pawn.jobs.StartJob(job, JobCondition.Incompletable, null, false, true, null, null, false); return; } this.PatherFailed(); return; } } Building_Door building_Door2 = this.NextCellDoorToManuallyOpen(); if (building_Door2 != null) { Stance_Cooldown stance_Cooldown = new Stance_Cooldown(building_Door2.TicksToOpenNow, building_Door2, null); stance_Cooldown.neverAimWeapon = true; this.pawn.stances.SetStance(stance_Cooldown); building_Door2.StartManualOpenBy(this.pawn); building_Door2.CheckFriendlyTouched(this.pawn); return; } this.lastCell = this.pawn.Position; this.pawn.Position = this.nextCell; if (this.pawn.RaceProps.Humanlike) { this.cellsUntilClamor--; if (this.cellsUntilClamor <= 0) { GenClamor.DoClamor(this.pawn, 7f, ClamorDefOf.Movement); this.cellsUntilClamor = 12; } } this.pawn.filth.Notify_EnteredNewCell(); if (this.pawn.BodySize > 0.9f) { this.pawn.Map.snowGrid.AddDepth(this.pawn.Position, -0.001f); } Building_Door building_Door3 = this.pawn.Map.thingGrid.ThingAt <Building_Door>(this.lastCell); if (building_Door3 != null && !this.pawn.HostileTo(building_Door3)) { building_Door3.CheckFriendlyTouched(this.pawn); if (!building_Door3.BlockedOpenMomentary && !building_Door3.HoldOpen && building_Door3.SlowsPawns && building_Door3.PawnCanOpen(this.pawn)) { building_Door3.StartManualCloseBy(this.pawn); return; } } if (this.NeedNewPath() && !this.TrySetNewPath()) { return; } if (this.AtDestinationPosition()) { this.PatherArrived(); } else { this.SetupMoveIntoNextCell(); } }
private static bool ShouldSetStance(bool original, Pawn_StanceTracker stanceTracker, Stance_Cooldown stance) { // Also factor in off-hand shield return(original || stanceTracker.pawn.OffHandShield() == stance.verb.EquipmentSource); }