Пример #1
0
        private float GetMass(Thing thing)
        {
            if (thing == null)
            {
                return(0f);
            }
            float num = thing.GetStatValue(StatDefOf.Mass, true);

            if (thing is Pawn pawn)
            {
                if (InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass))
                {
                    num -= MassUtility.InventoryMass(pawn);
                }
            }
            else if (ignoreSpawnedCorpseGearAndInventoryMass)
            {
                if (thing is Corpse corpse && corpse.Spawned)
                {
                    num -= MassUtility.GearAndInventoryMass(corpse.InnerPawn);
                }
            }
            return(num);
        }
Пример #2
0
        public static void PushEffect(Thing caster, Thing target, float damageAbsorbedPercent,
                                      HediffCompProperties_Knockback props)
        {
            if (target is Pawn pawn && pawn.Spawned && !pawn.Downed && !pawn.Dead && pawn.MapHeld != null)
            {
                var origDistance = props.knockDistance.RandomInRange;
                if (origDistance == 0)
                {
                    return;
                }
                var distanceAbsorbedFactor = props.knockDistanceAbsorbedPercentCurve.Evaluate(damageAbsorbedPercent);
                var pawnMass           = pawn.GetStatValue(StatDefOf.Mass);
                var inventoryMass      = MassUtility.InventoryMass(pawn);
                var distanceMassFactor = props.knockDistanceMassCurve.Evaluate(pawnMass - inventoryMass);
                var distance           = origDistance * distanceAbsorbedFactor * distanceMassFactor;
                DebugMessage($"PushEffect(caster: {caster}, target: {target}, damageAbsorbedPercent: {damageAbsorbedPercent}): " +
                             $"distanceAbsorbedFactor = absorbedPercentCurve({damageAbsorbedPercent}) = {distanceAbsorbedFactor}; " +
                             $"distanceMassFactor = massCurve({pawnMass}-{inventoryMass}={pawnMass - inventoryMass}) = {distanceMassFactor}; " +
                             $"distance = ({props.knockDistance} => {origDistance}) * {distanceAbsorbedFactor} * {distanceMassFactor} = {distance}");

                var destLoc = PushResult(caster, target, distance, out var actualDistance, out var collision);

                if (props.knockbackThought != null && (collision || actualDistance > 0f) && pawn.RaceProps.Humanlike)
                {
                    pawn.needs.mood.thoughts.memories.TryGainMemory(props.knockbackThought);
                }

                DamageInfo?impactDinfo = null;
                // Always calculate impactDinfo if we need a FlyingObject, in case something exists at destination
                // by the time the FlyingObject arrives at it.
                if (collision || actualDistance > 0f)
                {
                    var distancePercent    = actualDistance / distance;
                    var origImpactDamage   = props.knockImpactDamage.RandomInRange;
                    var impactDamageFactor = props.knockImpactDamageDistancePercentCurve.Evaluate(distancePercent);
                    var impactDamage       = origImpactDamage * impactDamageFactor;
                    DebugMessage($"PushEffect(caster: {caster}, target: {target}, damageAbsorbedPercent: {damageAbsorbedPercent}): " +
                                 $"impactDamageFactor = distanceCurve({actualDistance}/{distance}={distancePercent}) = {impactDamageFactor}; " +
                                 $"impactDamage = ({props.knockImpactDamage} => {origImpactDamage}) * {impactDamageFactor} = {impactDamage}");
                    if (impactDamage > 0f)
                    {
                        impactDinfo = new DamageInfo(props.knockImpactDamageType, impactDamage);
                    }
                }

                if (actualDistance > 0f)
                {
                    var flyingObject =
                        (FlyingObject)GenSpawn.Spawn(MiscDefOf.JT_FlyingObject, target.PositionHeld, target.MapHeld);
                    flyingObject.Props.speed = props.knockbackSpeed;
                    flyingObject.Launch(caster, destLoc.ToIntVec3(), target, impactDinfo);
                    DebugMessage($"PushEffect(caster: {caster}, target: {target}, damageAbsorbedPercent: {damageAbsorbedPercent}): " +
                                 $"flyingObject = {flyingObject}");
                }
                else if (impactDinfo is DamageInfo immediateImpactDinfo)
                {
                    DebugMessage($"PushEffect(caster: {caster}, target: {target}, damageAbsorbedPercent: {damageAbsorbedPercent}): " +
                                 $"immediateImpactDinfo = {immediateImpactDinfo}");
                    target.TakeDamage(immediateImpactDinfo);
                }
            }
        }
Пример #3
0
        private void DrawMass(Rect rect, TransferableOneWay trad, float availableMass)
        {
            if (!trad.HasAnyThing)
            {
                return;
            }
            Thing anyThing = trad.AnyThing;
            Pawn  pawn     = anyThing as Pawn;

            if (pawn != null && !includePawnsMassInMassUsage && !MassUtility.CanEverCarryAnything(pawn))
            {
                return;
            }
            Widgets.DrawHighlightIfMouseover(rect);
            if (pawn == null || includePawnsMassInMassUsage)
            {
                float mass = GetMass(anyThing);
                if (Mouse.IsOver(rect))
                {
                    if (pawn != null)
                    {
                        float gearMass = 0f;
                        float invMass  = 0f;
                        gearMass = MassUtility.GearMass(pawn);
                        if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass))
                        {
                            invMass = MassUtility.InventoryMass(pawn);
                        }
                        TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, 0f, mass - gearMass - invMass, gearMass, invMass), trad.GetHashCode() * 59);
                    }
                    else
                    {
                        TooltipHandler.TipRegion(rect, "ItemWeightTip".Translate());
                    }
                }
                if (mass > availableMass)
                {
                    GUI.color = ColoredText.RedReadable;
                }
                else
                {
                    GUI.color = TransferableOneWayWidget.ItemMassColor;
                }
                Widgets.Label(rect, mass.ToStringMass());
            }
            else
            {
                float cap      = MassUtility.Capacity(pawn, null);
                float gearMass = MassUtility.GearMass(pawn);
                float invMass  = InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass) ? 0f : MassUtility.InventoryMass(pawn);
                float num      = cap - gearMass - invMass;
                if (num > 0f)
                {
                    GUI.color = Color.green;
                }
                else if (num < 0f)
                {
                    GUI.color = ColoredText.RedReadable;
                }
                else
                {
                    GUI.color = Color.gray;
                }
                Widgets.Label(rect, num.ToStringMassOffset());
                if (Mouse.IsOver(rect))
                {
                    TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, cap, 0f, gearMass, invMass), trad.GetHashCode() * 59);
                }
            }
            GUI.color = Color.white;
        }
Пример #4
0
    public static IEnumerable<Gizmo> LaunchAndBombGizmosPassthrough(IEnumerable<Gizmo> __result, Caravan __instance)
    {
      IEnumerator<Gizmo> enumerator = __result.GetEnumerator();
      while (enumerator.MoveNext())
      {
        var element = enumerator.Current;
        yield return element;
        if ((element as Command_Action)?.defaultLabel == "CommandSettle".Translate() && __instance.PawnsListForReading.Any(x => x.inventory.innerContainer.Any(y => y.TryGetComp<CompLaunchableSRTS>() != null)))
        {
          float massUsage = 0f;
          Thing srts = null;
          foreach (Pawn p in __instance.PawnsListForReading)
          {
            foreach (Thing t in p.inventory?.innerContainer)
            {
              if (t.TryGetComp<CompLaunchableSRTS>() != null)
                srts = t;
              else
              {
                massUsage += t.GetStatValue(StatDefOf.Mass, true) * t.stackCount;
              }
            }
            massUsage += p.GetStatValue(StatDefOf.Mass, true);
            massUsage -= MassUtility.InventoryMass(p) * p.stackCount;
          }
          yield return new Command_Action
          {
            defaultLabel = "CommandLaunchGroup".Translate(),
            defaultDesc = "CommandLaunchGroupDesc".Translate(),
            icon = Tex2D.LaunchSRTS,
            alsoClickIfOtherInGroupClicked = false,
            action = delegate ()
            {
              if (massUsage > SRTSMod.GetStatFor<float>(srts.def.defName, StatName.massCapacity))
                Messages.Message("TooBigTransportersMassUsage".Translate(), MessageTypeDefOf.RejectInput, false);
              else
                srts.TryGetComp<CompLaunchableSRTS>().WorldStartChoosingDestination(__instance);
            }
          };
          /* Not Yet Implemented */
          /*yield return new Command_Action
          {
              defaultLabel = "BombTarget".Translate(),
              defaultDesc = "BombTargetDesc".Translate(),
              icon = TexCommand.Attack,
              action = delegate ()
              {
                  if(SRTSMod.mod.settings.passengerLimits)
                  {
                      if(__instance.PawnsListForReading.Count < SRTSMod.GetStatFor<int>(srts.def.defName, StatName.minPassengers))
                      {
                          Messages.Message("NotEnoughPilots".Translate(), MessageTypeDefOf.RejectInput, false);
                          return;
                      }
                      else if(__instance.PawnsListForReading.Count > SRTSMod.GetStatFor<int>(srts.def.defName, StatName.maxPassengers))
                      {
                          Messages.Message("TooManyPilots".Translate(), MessageTypeDefOf.RejectInput, false);
                          return;
                      }
                  }

                  FloatMenuOption carpetBombing = new FloatMenuOption("CarpetBombing".Translate(), delegate ()
                  {
                      srts.TryGetComp<CompBombFlyer>().bombType = BombingType.carpet;
                      srts.TryGetComp<CompBombFlyer>().StartChoosingWorldDestinationBomb(__instance);
                  });
                  FloatMenuOption preciseBombing = new FloatMenuOption("PreciseBombing".Translate(), delegate ()
                  {
                      srts.TryGetComp<CompBombFlyer>().bombType = BombingType.precise;
                      srts.TryGetComp<CompBombFlyer>().StartChoosingWorldDestinationBomb(__instance);
                  });
                  Find.WindowStack.Add(new FloatMenuGizmo(new List<FloatMenuOption>() { carpetBombing, preciseBombing }, srts, srts.LabelCap, UI.MouseMapPosition()));
              }
          };*/

          Command_Action RefuelSRTS = new Command_Action()
          {
            defaultLabel = "CommandAddFuelSRTS".Translate(srts.TryGetComp<CompRefuelable>().parent.Label),
            defaultDesc = "CommandAddFuelDescSRTS".Translate(),
            icon = Tex2D.FuelSRTS,
            alsoClickIfOtherInGroupClicked = false,
            action = delegate ()
            {
              bool flag = false;
              int count = 0;
              List<Thing> thingList = CaravanInventoryUtility.AllInventoryItems(__instance);
              for (int index = 0; index < thingList.Count; ++index)
              {
                if (thingList[index].def == ThingDefOf.Chemfuel)
                {
                  count = thingList[index].stackCount;
                  Pawn ownerOf = CaravanInventoryUtility.GetOwnerOf(__instance, thingList[index]);
                  float num = srts.TryGetComp<CompRefuelable>().Props.fuelCapacity - srts.TryGetComp<CompRefuelable>().Fuel;
                  if ((double)num < 1.0 && (double)num > 0.0)
                    count = 1;
                  if ((double)count * 1.0 >= (double)num)
                    count = (int)num;
                  if ((double)thingList[index].stackCount * 1.0 <= (double)count)
                  {
                    thingList[index].stackCount -= count;
                    Thing thing = thingList[index];
                    ownerOf.inventory.innerContainer.Remove(thing);
                    thing.Destroy(DestroyMode.Vanish);
                  }
                  else if ((uint)count > 0U)
                    thingList[index].SplitOff(count).Destroy(DestroyMode.Vanish);
                  srts.TryGetComp<CompRefuelable>().GetType().GetField("fuel", BindingFlags.Instance | BindingFlags.NonPublic).SetValue((object)srts.TryGetComp<CompRefuelable>(), (object)(float)((double)srts.TryGetComp<CompRefuelable>().Fuel + (double)count));
                  flag = true;
                  break;
                }
              }
              if (flag)
                Messages.Message("AddFuelSRTSCaravan".Translate(count, srts.LabelCap), MessageTypeDefOf.PositiveEvent, false);
              else
                Messages.Message("NoFuelSRTSCaravan".Translate(), MessageTypeDefOf.RejectInput, false);
            }
          };
          if (srts.TryGetComp<CompRefuelable>().IsFull)
            RefuelSRTS.Disable();
          yield return RefuelSRTS;
          yield return new Gizmo_MapRefuelableFuelStatus
          {

            nowFuel = srts.TryGetComp<CompRefuelable>().Fuel,
            maxFuel = srts.TryGetComp<CompRefuelable>().Props.fuelCapacity,
            compLabel = srts.TryGetComp<CompRefuelable>().Props.FuelGizmoLabel
          };
        }
      }
    }