protected override bool TryCastShot() { var result = base.TryCastShot(); try { if (compBuffM == null) { compBuffM = EquipmentSource.GetComp <CompBuffManager>(); properties = (NegativeRecoilProperties)verbProps; } //네거티브 리코일 버프가 없다면 if (!(compBuffM.FindWithDef(properties.weaponBuffDef) is NegativeRecoilBuff nRWBuff)) { compBuffM.AddBuff(properties.weaponBuffDef, EquipmentSource); } else { nRWBuff.AddOverlapLevel(1); } if (!(compBuffM.FindWithDef(properties.pawnBuffDef) is NegativeRecoilBuff nRPBuff)) { compBuffM.AddBuff(properties.pawnBuffDef, EquipmentSource); }
protected override bool TryCastShot() { if (burstShotsLeft > 1) { RatkinSoundDefOf.RK_Charge.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false)); if (verbProps.consumeFuelPerShot > 0f) { CompRefuelable compGunlance = EquipmentSource.TryGetComp <CompGunlanceFuel>(); if (compGunlance != null) { compGunlance.ConsumeFuel(verbProps.consumeFuelPerShot); } } AttachableThing_GunlanceIgnition ignition = ThingMaker.MakeThing(GunlanceDefOf.GunlancePreIgnition, null) as AttachableThing_GunlanceIgnition; ignition.AttachTo(CasterPawn); GenSpawn.Spawn(ignition, CasterPawn.Position, CasterPawn.Map, caster.Rotation, WipeMode.Vanish, false); } else { CasterPawn.GetAttachment(GunlanceDefOf.GunlancePreIgnition).Destroy(); AttachableThing_AfterIgnition ignition = ThingMaker.MakeThing(GunlanceDefOf.GunlanceAfterIgnition, null) as AttachableThing_AfterIgnition; ignition.AttachTo(CasterPawn); GenSpawn.Spawn(ignition, CasterPawn.Position, CasterPawn.Map, caster.Rotation, WipeMode.Vanish, false); RatkinSoundDefOf.RK_WyvernFire.PlayOneShot(new TargetInfo(caster.Position, caster.Map, false)); MakeExplosion(); } return(true); }
internal Equipment(EquipmentId id, EquipmentClass eClass, BonusType bonusType, EquipmentRarity rarity, double attributeBase, double attributeBaseInc, double attributeExp1, double attributeExp2, double attributeExpBase, EquipmentSource source, double[] _1163, double[] _2095, double[] _4450, string fileVersion, Func <string, ValueTask <Bitmap> > imageGetter = null) { Id = id; Class = eClass; BonusType = bonusType; Rarity = rarity; AttributeBase = attributeBase; AttributeBaseInc = attributeBaseInc; AttributeExp1 = attributeExp1; AttributeExp2 = attributeExp2; AttributeExpBase = attributeExpBase; Source = source; this._1163 = _1163; this._2095 = _2095; this._4450 = _4450; FileVersion = fileVersion; ImageGetter = imageGetter; }
public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target) { IntVec3 targetCell = target.Cell; ShiftVecReport report = new ShiftVecReport(); report.target = target; report.aimingAccuracy = AimingAccuracy; report.sightsEfficiency = SightsEfficiency; report.shotDist = (targetCell - caster.Position).LengthHorizontal; report.maxRange = verbProps.range; report.lightingShift = 1 - caster.Map.glowGrid.GameGlowAt(targetCell); if (!caster.Position.Roofed(caster.Map) || !targetCell.Roofed(caster.Map)) //Change to more accurate algorithm? { report.weatherShift = 1 - caster.Map.weatherManager.CurWeatherAccuracyMultiplier; } report.shotSpeed = ShotSpeed; report.swayDegrees = SwayAmplitude; var spreadmult = projectilePropsCE != null ? projectilePropsCE.spreadMult : 0f; report.spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * spreadmult; Thing cover; float smokeDensity; GetHighestCoverAndSmokeForTarget(target, out cover, out smokeDensity); report.cover = cover; report.smokeDensity = smokeDensity; return(report); }
protected override bool TryCastShot() { Log.Message("test3"); AERIALChangeableProjectile comp = EquipmentSource.GetComp <AERIALChangeableProjectile>(); Thing launcher = caster; ThingDef projectile = Projectile; if (projectile == null) { return(false); } Log.Message("test"); Thing equipment = EquipmentSource; Vector3 drawPos = this.caster.DrawPos; ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine); float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.forcedMissRadius, this.currentTarget.Cell - this.caster.Position); int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } IntVec3 pos = shootLine.Source; pos.x += 20; pos.z += 20; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, pos, this.caster.Map, WipeMode.Vanish); projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null); comp.loadedShells.RemoveAt(comp.loadedShells.Count - 1); if (!comp.loadedShells.NullOrEmpty()) { pos = shootLine.Source; pos.z -= 20; pos.x -= 20; projectile = Projectile; projectile2 = (Projectile)GenSpawn.Spawn(projectile, pos, this.caster.Map, WipeMode.Vanish); projectile2.Launch(launcher, drawPos, c, this.currentTarget, projectileHitFlags, equipment, null); comp.loadedShells.RemoveAt(comp.loadedShells.Count - 1); } Log.Message($"{comp.loadedShells.Count}"); return(true); }
private void SelfConsume() { if (remainBullet > 0) { remainBullet--; } else { EquipmentSource.GetComp <CompEquippable>().AllVerbs.Remove(this); } }
internal Equipment(EquipmentStatic staticData, EquipmentClass eClass, BonusType bonusType, EquipmentRarity rarity, double bonusBase, double bonusIncrease, EquipmentSource source, Bitmap image, string fileVersion) { _staticData = staticData; Class = eClass; BonusType = bonusType; Rarity = rarity; BonusBase = bonusBase; BonusIncrease = bonusIncrease; Source = source; Image = image; FileVersion = fileVersion; }
protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } Map target = caster.Map; IntVec3 intVec3 = currentTarget.Cell; DropPodUtility.DropThingsNear(intVec3, target, _emergencyResourcesList, 110, false, true); if (EquipmentSource != null && !EquipmentSource.Destroyed) { EquipmentSource.Destroy(); } return(true); }
public override bool Available() { if (burstShotsLeft > 0) { return(true); } if (verbProps.consumeFuelPerShot > 0f) { CompGunlanceFuel compGunlance = EquipmentSource.TryGetComp <CompGunlanceFuel>(); if ((compGunlance != null && compGunlance.Fuel < verbProps.consumeFuelPerShot)) { return(false); } } return(true); }
public virtual bool Available() { if (verbProps.consumeFuelPerShot > 0f) { CompRefuelable compRefuelable = caster.TryGetComp <CompRefuelable>(); if (compRefuelable != null && compRefuelable.Fuel < verbProps.consumeFuelPerShot) { return(false); } } CompReloadable compReloadable = EquipmentSource?.GetComp <CompReloadable>(); if (compReloadable != null && !compReloadable.CanBeUsed) { return(false); } return(true); }
protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } var mechfall = (MechFall)GenSpawn.Spawn(ThingDefOf.MechFallBeam, currentTarget.Cell, caster.Map); mechfall.duration = 450; mechfall.instigator = caster; mechfall.weaponDef = EquipmentSource?.def; mechfall.StartStrike(); if (EquipmentSource != null && !EquipmentSource.Destroyed) { EquipmentSource.Destroy(); } return(true); }
public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target) { IntVec3 targetCell = target.Cell; ShiftVecReport report = new ShiftVecReport(); report.target = target; report.aimingAccuracy = AimingAccuracy; report.sightsEfficiency = SightsEfficiency; report.shotDist = (targetCell - caster.Position).LengthHorizontal; report.maxRange = verbProps.range; report.lightingShift = CE_Utility.GetLightingShift(caster, LightingTracker.CombatGlowAtFor(caster.Position, targetCell)); if (!caster.Position.Roofed(caster.Map) || !targetCell.Roofed(caster.Map)) //Change to more accurate algorithm? { report.weatherShift = 1 - caster.Map.weatherManager.CurWeatherAccuracyMultiplier; } report.shotSpeed = ShotSpeed; report.swayDegrees = SwayAmplitude; var spreadmult = projectilePropsCE != null ? projectilePropsCE.spreadMult : 0f; report.spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * spreadmult; Thing cover; float smokeDensity; GetHighestCoverAndSmokeForTarget(target, out cover, out smokeDensity); report.cover = cover; report.smokeDensity = smokeDensity; if (Controller.settings.DebugVerbose) { Log.Message($"<color=red>CE</color>: <color=orange>{caster}</color> shooting <color=orange>{target.Thing}</color> <color=yellow>ShiftVecReport</color>\n" + $"1- aimingAccuracy:{report.aimingAccuracy}\n" + $"2- sightsEfficiency:{report.sightsEfficiency}\n" + $"3- maxRange:{report.maxRange}\n" + $"4- lightingShift:{report.lightingShift}\n" + $"5- spreadDegrees:{report.spreadDegrees}\n" + $"6- smokeDensity:{report.smokeDensity}\n" + $"7- swayDegrees:{report.swayDegrees}\n" + $"8- shotSpeed:{report.shotSpeed}\n" + $"9- shotDist:{report.shotDist}\n"); } return(report); }
private NSEquipmentDetail HandlerQueue_NationalStandard(EquipmentSource datare) { byte[] data = datare.RawData; if (data.Length < 15) { return(null); } NSEquipmentDetail equipmentDetail = new NSEquipmentDetail(); try { log.Info("开始解析数据-" + data.Length); string outMsg; //返回的错误信息,正确解析则返回空 var detail = EquipmentHelper.HandleData_NS(data, out outMsg); if (detail != null && string.IsNullOrWhiteSpace(outMsg)) { #region 解析EquipmentDetail foreach (var key in detail.Keys) { var proInfo = typeof(NSEquipmentDetail).GetProperty(key.ToString()); if (null != proInfo) { var eqValue = EquipmentHelper.GetNSEquipmentValue(key, detail[key], equipmentDetail); proInfo.SetValue(equipmentDetail, eqValue, null); } } #endregion } else { equipmentDetail = null; } } catch (Exception ex) { log.Error("设备详细信息解析异常", ex); equipmentDetail = null; } return(equipmentDetail); }
public void Explosion() { Map map2 = EquipmentSource.Map; GenExplosion.DoExplosion ( center: currentTarget.Thing.Position, map: CasterPawn.Map, radius: 2f, damType: RatkinDamageDefOf.DemoBomb, instigator: EquipmentSource, damAmount: 15, armorPenetration: 0.60f, explosionSound: null, weapon: EquipmentSource.def, projectile: null, intendedTarget: currentTarget.Thing, chanceToStartFire: 0, damageFalloff: true ); if (CasterPawn != null && CasterPawn.inventory != null) { Thing magicWand = CasterPawn.inventory.innerContainer.FirstOrDefault((Thing t) => t != null && t.def == RatkinWeaponDefOf.RK_MagicWand); if (magicWand != null) { magicWand.stackCount -= 1; if (magicWand.stackCount <= 0) { CasterPawn.inventory.innerContainer.Remove(magicWand); CasterPawn.inventory.Notify_ItemRemoved(magicWand); magicWand.Destroy(DestroyMode.Vanish); } } else { if (EquipmentSource != null && !EquipmentSource.Destroyed) { EquipmentSource.Destroy(DestroyMode.Vanish); } } } }
protected override bool TryCastShot() { bool result = base.TryCastShot(); try { if (compBuffM == null) { compBuffM = EquipmentSource.GetComp <CompBuffManager>(); properties = (NegativeRecoilProperties)verbProps; } NegativeRecoilBuff nRWBuff = compBuffM.FindWithDef(properties.weaponBuffDef) as NegativeRecoilBuff; NegativeRecoilBuff nRPBuff = compBuffM.FindWithDef(properties.pawnBuffDef) as NegativeRecoilBuff; //네거티브 리코일 버프가 없다면 if (nRWBuff == null) { compBuffM.AddBuff(properties.weaponBuffDef, EquipmentSource); } else { nRWBuff.AddOverlapLevel(1); } if (nRPBuff == null) { compBuffM.AddBuff(properties.pawnBuffDef, EquipmentSource); } else { nRPBuff.AddOverlapLevel(1); } } catch (Exception ee) { Log.Error("Error : " + ee.ToString()); } return(result); }
protected override bool TryCastShot() { // 水チェック var comp = EquipmentSource.GetComp <CompWaterTool>(); if (comp.StoredWaterVolumePercent < NeedWaterPercentage) { return(false); } // 通常の投擲チェック if (base.TryCastShot() == false) { return(false); } // 投擲できた場合は水を減らす comp.StoredWaterVolume = 0f; // グラフィック更新 EquipmentSource.Tick(); return(true); }
protected void TryCastNextBurstShot() { LocalTargetInfo localTargetInfo = currentTarget; if (Available() && TryCastShot()) { if (verbProps.muzzleFlashScale > 0.01f) { MoteMaker.MakeStaticMote(caster.Position, caster.Map, ThingDefOf.Mote_ShotFlash, verbProps.muzzleFlashScale); } if (verbProps.soundCast != null) { verbProps.soundCast.PlayOneShot(new TargetInfo(caster.Position, caster.Map)); } if (verbProps.soundCastTail != null) { verbProps.soundCastTail.PlayOneShotOnCamera(caster.Map); } if (CasterIsPawn) { if (CasterPawn.thinker != null) { CasterPawn.mindState.Notify_EngagedTarget(); } if (CasterPawn.mindState != null) { CasterPawn.mindState.Notify_AttackedTarget(localTargetInfo); } if (CasterPawn.MentalState != null) { CasterPawn.MentalState.Notify_AttackedTarget(localTargetInfo); } if (TerrainDefSource != null) { CasterPawn.meleeVerbs.Notify_UsedTerrainBasedVerb(); } if (CasterPawn.health != null) { CasterPawn.health.Notify_UsedVerb(this, localTargetInfo); } if (EquipmentSource != null) { EquipmentSource.Notify_UsedWeapon(CasterPawn); } if (!CasterPawn.Spawned) { return; } } if (verbProps.consumeFuelPerShot > 0f) { caster.TryGetComp <CompRefuelable>()?.ConsumeFuel(verbProps.consumeFuelPerShot); } burstShotsLeft--; } else { burstShotsLeft = 0; } if (burstShotsLeft > 0) { ticksToNextBurstShot = verbProps.ticksBetweenBurstShots; if (CasterIsPawn) { CasterPawn.stances.SetStance(new Stance_Cooldown(verbProps.ticksBetweenBurstShots + 1, currentTarget, this)); } return; } state = VerbState.Idle; if (CasterIsPawn) { CasterPawn.stances.SetStance(new Stance_Cooldown(verbProps.AdjustedCooldownTicks(this, CasterPawn), currentTarget, this)); } if (castCompleteCallback != null) { castCompleteCallback(); } }
/// <summary> /// 解析终端设备工作状态 /// </summary> /// <param name="data"></param> /// <returns>设备状态</returns> private EquipmentDetail HandlerQueue(EquipmentSource datare) { byte[] data = datare.RawData; if (data.Length < 13) { return(null); } EquipmentDetail equipmentDetail = new EquipmentDetail(); try { equipmentDetail.IPAddressTmpFormat = datare.RemoteIPTmp; equipmentDetail.RemotePortTmp = (ushort)datare.RemotePortTmp; log.Info("开始解析数据-" + data.Length); equipmentDetail.SrvTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); FeaturesCode fc; string outMsg; //返回的错误信息,正确解析则返回空 var detail = EquipmentHelper.HandleData(data, out fc, out outMsg); if (detail != null && string.IsNullOrWhiteSpace(outMsg) && detail.ContainsKey(Equipment.PhysicalAddress)) { var msgType = Convert.ToChar(data[0]); if (msgType == '&') { //帧头占12字节 equipmentDetail.HeaderData = data.Take(12).ToArray(); } else if (msgType == '%') { //帧头占18字节 equipmentDetail.HeaderData = data.Take(18).ToArray(); } byte[] address = detail[Equipment.PhysicalAddress];//每个包必须有物理码 string pp = ""; for (int i = 0; i < address.Length; i++) { pp += address[i].ToString("X2");// bytes[i].ToString("X2").PadLeft(2, '0'); } clientsConn.AddOrUpdate(pp, datare.ConnId, (key, value) => { return(value = datare.ConnId); }); clientsHeadData.AddOrUpdate(pp, equipmentDetail.HeaderData, (key, value) => { return(value = equipmentDetail.HeaderData); }); #region 解析EquipmentDetail foreach (var key in detail.Keys) { if (key.ToString() == "RemoteControlCenterIPAddress") { int ppr = 0; int ffp = 1; int fs = ppr + ffp; Console.Write(""); } var proInfo = typeof(EquipmentDetail).GetProperty(key.ToString()); if (null != proInfo) { var eqValue = EquipmentHelper.GetEquipmentValue(key, detail[key], equipmentDetail); proInfo.SetValue(equipmentDetail, eqValue, null); typeof(EquipmentDetail).GetProperty(key.ToString() + "Format").SetValue(equipmentDetail, EquipmentHelper.GetEquipmentValueString(key, eqValue), null); } } #endregion var dataHeader = EquipmentHelper.HandleHeader(EquipmentHelper.GetFrameHeader(data)); if (dataHeader != null) { equipmentDetail.FactoryName = dataHeader[FrameHeaderEnum.FactoryNumber]; } } else { equipmentDetail = null; } } catch (Exception ex) { log.Error("设备详细信息解析异常", ex); equipmentDetail = null; } return(equipmentDetail); }
private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target) { float damAmount2 = verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn); float armorPenetration = verbProps.AdjustedArmorPenetration(this, base.CasterPawn); DamageDef damDef = verbProps.meleeDamageDef; BodyPartGroupDef bodyPartGroupDef = null; HediffDef hediffDef = null; float additionalMultiplier = 1f; if (target.Thing != null) { if (target.Thing is Pawn pawn) { if (pawn.RaceProps.IsMechanoid) { additionalMultiplier = 5f; } } if (target.Thing is Building building) { if (building.Stuff != null && building.Stuff.stuffProps != null) { StuffCategoryDef stuffCategoryDef = building.Stuff.stuffProps.categories.FirstOrDefault(); if (stuffCategoryDef != null) { if (stuffCategoryDef == StuffCategoryDefOf.Metallic) { additionalMultiplier = 4f; } } } } } if (EquipmentSource != null) { CompChargeableWeapon compChargeableWeapon = EquipmentSource.TryGetComp <CompChargeableWeapon>(); if (compChargeableWeapon != null) { if (compChargeableWeapon.Charge < compChargeableWeapon.Props.ChargePerShot) { additionalMultiplier = 1f; } else { compChargeableWeapon.Used(); } } } damAmount2 = Rand.Range(damAmount2 * 0.8f, damAmount2 * 1.2f) * additionalMultiplier; if (base.CasterIsPawn) { bodyPartGroupDef = verbProps.AdjustedLinkedBodyPartsGroup(tool); if (damAmount2 >= 1f) { if (base.HediffCompSource != null) { hediffDef = base.HediffCompSource.Def; } } else { damAmount2 = 1f; damDef = DamageDefOf.Blunt; } } ThingDef source = (base.EquipmentSource == null) ? base.CasterPawn.def : base.EquipmentSource.def; Vector3 direction = (target.Thing.Position - base.CasterPawn.Position).ToVector3(); DamageDef def = damDef; float amount = damAmount2; float armorPenetration2 = armorPenetration; Thing caster = base.caster; DamageInfo mainDinfo = new DamageInfo(def, amount, armorPenetration2, -1f, caster, null, source); mainDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef); mainDinfo.SetWeaponHediff(hediffDef); mainDinfo.SetAngle(direction); yield return(mainDinfo); if (surpriseAttack && ((verbProps.surpriseAttack != null && !verbProps.surpriseAttack.extraMeleeDamages.NullOrEmpty()) || (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty()))) { IEnumerable <ExtraDamage> extraDamages = Enumerable.Empty <ExtraDamage>(); if (verbProps.surpriseAttack != null && verbProps.surpriseAttack.extraMeleeDamages != null) { extraDamages = extraDamages.Concat(verbProps.surpriseAttack.extraMeleeDamages); } if (tool != null && tool.surpriseAttack != null && !tool.surpriseAttack.extraMeleeDamages.NullOrEmpty()) { extraDamages = extraDamages.Concat(tool.surpriseAttack.extraMeleeDamages); } foreach (ExtraDamage extraDamage in extraDamages) { int extraDamageAmount = GenMath.RoundRandom(extraDamage.AdjustedDamageAmount(this, base.CasterPawn)); float extraDamageArmorPenetration = extraDamage.AdjustedArmorPenetration(this, base.CasterPawn); def = extraDamage.def; armorPenetration2 = extraDamageAmount; amount = extraDamageArmorPenetration; caster = base.caster; DamageInfo extraDinfo = new DamageInfo(def, armorPenetration2, amount, -1f, caster, null, source); extraDinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); extraDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef); extraDinfo.SetWeaponHediff(hediffDef); extraDinfo.SetAngle(direction); yield return(extraDinfo); } } }
public static LocalisedString Localisable(EquipmentSource source) => new LocalisedString(BASE_PATH + source.ToString().ToUpper());
public static ILocalisable <string> ToLocalisable(this EquipmentSource equipSource) => EquipmentSourceText.Localisable(equipSource);
/// <summary> /// Performs the actual melee attack part. Awards XP, calculates and applies whether an attack connected and the outcome. /// </summary> /// <returns>True if the attack connected, false otherwise</returns> protected override bool TryCastShot() { Pawn casterPawn = CasterPawn; if (casterPawn.stances.FullBodyBusy) { return(false); } Thing targetThing = currentTarget.Thing; if (!CanHitTarget(targetThing)) { Log.Warning(string.Concat(new object[] { casterPawn, " meleed ", targetThing, " from out of melee position." })); } casterPawn.rotationTracker.Face(targetThing.DrawPos); // Award XP as per vanilla bool targetImmobile = IsTargetImmobile(currentTarget); if (!targetImmobile && casterPawn.skills != null) { casterPawn.skills.Learn(SkillDefOf.Melee, HitXP, false); } // Hit calculations bool result; string moteText = ""; SoundDef soundDef; Pawn defender = targetThing as Pawn; //var hitRoll = Rand.Value; if (Rand.Chance(GetHitChance(targetThing))) { // Check for dodge if (!targetImmobile && !surpriseAttack && Rand.Chance(defender.GetStatValue(StatDefOf.MeleeDodgeChance))) { // Attack is evaded result = false; soundDef = SoundMiss(); CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDodge, false); moteText = "TextMote_Dodge".Translate(); defender.skills?.Learn(SkillDefOf.Melee, DodgeXP, false); } else { // Attack connects, calculate resolution //var resultRoll = Rand.Value; var parryBonus = 1 / EquipmentSource?.GetStatValue(CE_StatDefOf.MeleeCounterParryBonus) ?? 1; var parryChance = GetComparativeChanceAgainst(defender, casterPawn, CE_StatDefOf.MeleeParryChance, BaseParryChance, parryBonus); if (!surpriseAttack && defender != null && CanDoParry(defender) && Rand.Chance(parryChance)) { // Attack is parried Apparel shield = defender.apparel.WornApparel.FirstOrDefault(x => x is Apparel_Shield); bool isShieldBlock = shield != null && Rand.Chance(ShieldBlockChance); Thing parryThing = isShieldBlock ? shield : defender.equipment?.Primary ?? defender; if (Rand.Chance(GetComparativeChanceAgainst(defender, casterPawn, CE_StatDefOf.MeleeCritChance, BaseCritChance))) { // Do a riposte DoParry(defender, parryThing, true); moteText = "CE_TextMote_Riposted".Translate(); CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesDeflect, false); //placeholder defender.skills?.Learn(SkillDefOf.Melee, CritXP + ParryXP, false); } else { // Do a parry DoParry(defender, parryThing); moteText = "CE_TextMote_Parried".Translate(); CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, false); //placeholder defender.skills?.Learn(SkillDefOf.Melee, ParryXP, false); } result = false; soundDef = SoundMiss(); // TODO Set hit sound to something more appropriate } else { BattleLogEntry_MeleeCombat log = this.CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesHit, false); // Attack connects if (surpriseAttack || Rand.Chance(GetComparativeChanceAgainst(casterPawn, defender, CE_StatDefOf.MeleeCritChance, BaseCritChance))) { // Do a critical hit isCrit = true; ApplyMeleeDamageToTarget(currentTarget).AssociateWithLog(log); moteText = casterPawn.def.race.Animal ? "CE_TextMote_Knockdown".Translate() : "CE_TextMote_CriticalHit".Translate(); casterPawn.skills?.Learn(SkillDefOf.Melee, CritXP, false); } else { // Do a regular hit as per vanilla ApplyMeleeDamageToTarget(currentTarget).AssociateWithLog(log); } result = true; soundDef = targetThing.def.category == ThingCategory.Building ? SoundHitBuilding() : SoundHitPawn(); } } } else { // Attack missed result = false; soundDef = SoundMiss(); CreateCombatLog((ManeuverDef maneuver) => maneuver.combatLogRulesMiss, false); } if (!moteText.NullOrEmpty()) { MoteMaker.ThrowText(targetThing.PositionHeld.ToVector3Shifted(), targetThing.MapHeld, moteText); } soundDef.PlayOneShot(new TargetInfo(targetThing.PositionHeld, targetThing.MapHeld)); casterPawn.Drawer.Notify_MeleeAttackOn(targetThing); if (defender != null && !defender.Dead) { defender.stances.StaggerFor(95); if (casterPawn.MentalStateDef != MentalStateDefOf.SocialFighting || defender.MentalStateDef != MentalStateDefOf.SocialFighting) { defender.mindState.meleeThreat = casterPawn; defender.mindState.lastMeleeThreatHarmTick = Find.TickManager.TicksGame; } } casterPawn.rotationTracker.FaceCell(targetThing.Position); if (casterPawn.caller != null) { casterPawn.caller.Notify_DidMeleeAttack(); } return(result); }
// Token: 0x0600640C RID: 25612 RVA: 0x001B4770 File Offset: 0x001B2B70 protected override bool TryCastShot() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false); } var shootLine = new ShootLine(); if (verbProps.stopBurstWithoutLos && !TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine)) { return(false); } var comp = EquipmentSource?.GetComp <CompChangeableProjectile>(); comp?.Notify_ProjectileLaunched(); var compMannable = caster.TryGetComp <CompMannable>(); if (compMannable?.ManningPawn != null) { } SpawnBeam(); hitThing(); var shotReport = ShotReport.HitReportFor(caster, this, currentTarget); var randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); var unused = randomCoverToMissInto?.def; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); var nonTargetWorld = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { nonTargetWorld |= ProjectileHitFlags.NonTargetPawns; } return(true); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { var projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } return(true); } var projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } return(true); }
public Equipment Build(EquipmentClass eClass, BonusType bonusType, EquipmentRarity rarity, double bonusBase, double bonusIncrease, EquipmentSource source, Bitmap image, string fileVersion) { return(new Equipment(this, eClass, bonusType, rarity, bonusBase, bonusIncrease, source, image, fileVersion)); }
/// <summary> /// Calculates primary DamageInfo from verb, as well as secondary DamageInfos to apply (i.e. surprise attack stun damage). /// Also calculates the maximum body height an attack can target, so we don't get rabbits biting out a colonist's eye or something. /// </summary> /// <param name="target">The target damage is to be applied to</param> /// <returns>Collection with primary DamageInfo, followed by secondary types</returns> private IEnumerable <DamageInfo> DamageInfosToApply(LocalTargetInfo target, bool isCrit = false) { //START 1:1 COPY Verb_MeleeAttack.DamageInfosToApply float damAmount = this.verbProps.AdjustedMeleeDamageAmount(this, base.CasterPawn); var critModifier = isCrit && verbProps.meleeDamageDef.armorCategory == DamageArmorCategoryDefOf.Sharp && !CasterPawn.def.race.Animal ? 2 : 1; var armorPenetration = verbProps.AdjustedArmorPenetration(this, CasterPawn) * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) * critModifier; DamageDef damDef = verbProps.meleeDamageDef; BodyPartGroupDef bodyPartGroupDef = null; HediffDef hediffDef = null; damAmount = Rand.Range(damAmount * 0.8f, damAmount * 1.2f); if (base.CasterIsPawn) { bodyPartGroupDef = this.verbProps.AdjustedLinkedBodyPartsGroup(this.tool); if (damAmount >= 1f) { if (base.HediffCompSource != null) { hediffDef = base.HediffCompSource.Def; } } else { damAmount = 1f; damDef = DamageDefOf.Blunt; } } ThingDef source; if (base.EquipmentSource != null) { source = base.EquipmentSource.def; } else { source = base.CasterPawn.def; } Vector3 direction = (target.Thing.Position - base.CasterPawn.Position).ToVector3(); DamageDef def = damDef; //END 1:1 COPY BodyPartHeight bodyRegion = GetBodyPartHeightFor(target); //Custom // Add check for body height //START 1:1 COPY DamageInfo mainDinfo = new DamageInfo(def, damAmount, armorPenetration, -1f, caster, null, source, DamageInfo.SourceCategory.ThingOrUnknown, null); //Alteration mainDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside); //Alteration mainDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef); mainDinfo.SetWeaponHediff(hediffDef); mainDinfo.SetAngle(direction); yield return(mainDinfo); // Apply critical damage if (isCrit && !CasterPawn.def.race.Animal && verbProps.meleeDamageDef.armorCategory != DamageArmorCategoryDefOf.Sharp) { var critAmount = GenMath.RoundRandom(mainDinfo.Amount * 0.25f); var critDinfo = new DamageInfo(DamageDefOf.Stun, critAmount, armorPenetration, //Ignore armor //armorPenetration, //Armor Penetration -1, caster, null, source); critDinfo.SetBodyRegion(bodyRegion, BodyPartDepth.Outside); critDinfo.SetWeaponBodyPartGroup(bodyPartGroupDef); critDinfo.SetWeaponHediff(hediffDef); critDinfo.SetAngle(direction); yield return(critDinfo); } }
protected override (bool success, Vector3 launchPos, float angle) TryCastShotInternal() { IntVec3 exitTarget = caster.Position.CellFromDistAngle(Building_Artillery.MaxMapDistance, heading); if (!target.HasWorldObject && !target.HasThing) { return(false, Vector3.zero, 0); } ThingDef projectile = Projectile; if (projectile is null) { return(false, Vector3.zero, 0); } bool flag = TryFindShootLineFromTo(caster.Position, exitTarget, out ShootLine shootLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false, Vector3.zero, 0); } if (EquipmentSource != null) { CompChangeableProjectile comp = EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = caster; Thing equipment = EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 launchPos = caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, caster.Position, caster.Map, WipeMode.Vanish); if (projectile2.AllComps.NullOrEmpty()) { AccessTools.Field(typeof(ThingWithComps), "comps").SetValue(projectile2, new List <ThingComp>()); } projectile2.AllComps.Add(new CompProjectileExitMap(CasterTWC) { airDefenseDef = AntiAircraftDefOf.FlakProjectile, target = target.WorldObject as AerialVehicleInFlight, spawnPos = Building_Artillery.RandomWorldPosition(caster.Map.Tile, 1).FirstOrDefault() }); if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps) { projectile2.AllComps.Add(new CompTurretProjectileProperties(CasterTWC) { speed = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed, hitflag = ProjectileHitFlags.IntendedTarget, hitflags = null }); } ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(heading); projectile2.Launch(launcher, launchPos, exitTarget, exitTarget, ProjectileHitFlags.IntendedTarget, equipment); ThrowDebugText("Hit\nDest", shootLine.Dest); return(true, launchPos, heading); }
/// <summary> /// Fires a projectile using the new aiming system /// </summary> /// <returns>True for successful shot, false otherwise</returns> public override bool TryCastShot() { if (!TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine)) { return(false); } if (projectilePropsCE.pelletCount < 1) { Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1."); return(false); } bool instant = false; float spreadDegrees = 0; float aperatureSize = 0; if (Projectile.projectile is ProjectilePropertiesCE pprop) { instant = pprop.isInstant; spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * pprop.spreadMult; aperatureSize = 0.03f; } ShiftVecReport report = ShiftVecReportFor(currentTarget); bool pelletMechanicsOnly = false; for (int i = 0; i < projectilePropsCE.pelletCount; i++) { ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); ShiftTarget(report, pelletMechanicsOnly, instant); //New aiming algorithm projectile.canTargetSelf = false; var targetDistance = (sourceLoc - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude; projectile.minCollisionDistance = GetMinCollisionDistance(targetDistance); projectile.intendedTarget = currentTarget; projectile.mount = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster); projectile.AccuracyFactor = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f); if (instant) { var shotHeight = ShotHeight; float tsa = AdjustShotHeight(caster, currentTarget, ref shotHeight); projectile.RayCast( Shooter, verbProps, sourceLoc, shotAngle + tsa, shotRotation, shotHeight, ShotSpeed, spreadDegrees, aperatureSize, EquipmentSource); } else { projectile.Launch( Shooter, //Shooter instead of caster to give turret operators' records the damage/kills obtained sourceLoc, shotAngle, shotRotation, ShotHeight, ShotSpeed, EquipmentSource); } pelletMechanicsOnly = true; } /* * Notify the lighting tracker that shots fired with muzzle flash value of VerbPropsCE.muzzleFlashScale */ LightingTracker.Notify_ShotsFiredAt(caster.Position, intensity: VerbPropsCE.muzzleFlashScale); pelletMechanicsOnly = false; numShotsFired++; if (CompAmmo != null && !CompAmmo.CanBeFiredNow) { CompAmmo?.TryStartReload(); } if (CompReloadable != null) { CompReloadable.UsedOnce(); } return(true); }
protected virtual (bool success, Vector3 launchPos, float angle) TryCastShotInternal() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false, Vector3.zero, 0); } ThingDef projectile = Projectile; if (projectile == null) { return(false, Vector3.zero, 0); } ShootLine shootLine; bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false, Vector3.zero, 0); } if (EquipmentSource != null) { CompChangeableProjectile comp = EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = caster; Thing equipment = EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 launchPos = caster.DrawPos; float angle = launchPos.AngleToPoint(currentTarget.CenterVector3); Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, caster.Map, WipeMode.Vanish); if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps) { projectile2.AllComps.Insert(0, new CompTurretProjectileProperties(CasterTWC) { speed = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed, hitflag = projectileProps.projectileHitFlag, hitflags = projectileProps.hitFlagDef }); } if (verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); ThrowDebugText("ToRadius"); ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, launchPos, c, currentTarget, projectileHitFlags, equipment, null); return(true, launchPos, angle); } } } ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ThrowDebugText("ToWild" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, shootLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true, launchPos, angle); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { ThrowDebugText("ToCover" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true, launchPos, angle); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); if (currentTarget.Thing != null) { angle = launchPos.AngleToPoint(currentTarget.CenterVector3); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", currentTarget.Cell); } else { angle = launchPos.AngleToPoint(shootLine.Dest.ToVector3Shifted()); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true, launchPos, angle); }