Beispiel #1
0
        private bool IsValidTarget(Thing t)
        {
            Pawn pawn = t as Pawn;

            if (pawn != null)
            {
                if (AttackVerb.ProjectileFliesOverhead())
                {
                    RoofDef roofDef = base.Map.roofGrid.RoofAt(t.Position);
                    if (roofDef != null && roofDef.isThickRoof)
                    {
                        return(false);
                    }
                }
                if (mannableComp == null)
                {
                    return(!GenAI.MachinesLike(base.Faction, pawn));
                }
                if (pawn.RaceProps.Animal && pawn.Faction == Faction.OfPlayer)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #2
0
        protected LocalTargetInfo TryFindNewTarget()
        {
            IAttackTargetSearcher attackTargetSearcher = TargSearcher();
            Faction faction = attackTargetSearcher.Thing.Faction;
            float   range   = AttackVerb.verbProps.range;

            if (Rand.Value < 0.5f && AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) && base.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x)
            {
                float num = AttackVerb.verbProps.EffectiveMinRange(x, this);
                float num2 = (float)x.Position.DistanceToSquared(base.Position);
                return(num2 > num * num && num2 < range * range);
            }).TryRandomElement(out Building result))
            {
                return(result);
            }
            TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat;

            if (!AttackVerb.ProjectileFliesOverhead())
            {
                targetScanFlags |= TargetScanFlags.NeedLOSToAll;
                targetScanFlags |= TargetScanFlags.LOSBlockableByGas;
            }
            if (AttackVerb.IsIncendiary())
            {
                targetScanFlags |= TargetScanFlags.NeedNonBurning;
            }
            return((Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, IsValidTarget));
        }
Beispiel #3
0
        protected void TryStartShootSomething(bool canBeginBurstImmediately)
        {
            if (progressBarEffecter != null)
            {
                progressBarEffecter.Cleanup();
                progressBarEffecter = null;
            }
            if (!base.Spawned || (holdFire && CanToggleHoldFire) || (AttackVerb.ProjectileFliesOverhead() && base.Map.roofGrid.Roofed(base.Position)) || !AttackVerb.Available())
            {
                ResetCurrentTarget();
                return;
            }
            bool isValid = currentTargetInt.IsValid;

            if (forcedTarget.IsValid)
            {
                currentTargetInt = forcedTarget;
            }
            else
            {
                currentTargetInt = TryFindNewTarget();
            }
            if (!isValid && currentTargetInt.IsValid)
            {
                SoundDefOf.TurretAcquireTarget.PlayOneShot(new TargetInfo(base.Position, base.Map));
            }
            if (currentTargetInt.IsValid)
            {
                if (def.building.turretBurstWarmupTime > 0f)
                {
                    burstWarmupTicksLeft = def.building.turretBurstWarmupTime.SecondsToTicks();
                }
                else if (canBeginBurstImmediately)
                {
                    BeginBurst();
                }
                else
                {
                    burstWarmupTicksLeft = 1;
                }
            }
            else
            {
                ResetCurrentTarget();
            }
        }
Beispiel #4
0
 protected void BeginBurst()                     // Added handling for ticksUntilAutoReload
 {
     ticksUntilAutoReload = minTicksBeforeAutoReload;
     AttackVerb.TryStartCastOn(CurrentTarget, false, true);
     OnAttackedTarget(CurrentTarget);
 }
        private void StartRealAttack()
        {
            bool cast = true;
            if (globalTarget.IsValid)
            {
                Log.Message($"Using global target to create local target. ({globalTarget})");
                if (globalTarget.Map == null)
                {
                    if(globalTargetMapLastKnown != null)
                    {
                        Log.Warning($"Global target has null map (most likely missing pawn target). Falling back to last known map ({globalTargetMapLastKnown}).");
                        localTarget = new LocalTargetInfo(lastKnownThingLoc);
                        globalTarget = new GlobalTargetInfo(lastKnownThingLoc, globalTargetMapLastKnown);
                    }
                    else
                    {
                        Log.Error("Global target is valid, but has null map. Last known map is also null. Probably caused by map being unloaded prematurely, or immediately after the updated that added this feature. Strike cancelled to avoid damage to wrong map.");
                        cast = false;
                    }
                }
                else
                {
                    // Convert to local target. Note that Thing may be non-null be destroyed, that is handled below.
                    localTarget = globalTarget.HasThing ? new LocalTargetInfo(globalTarget.Thing) : new LocalTargetInfo(globalTarget.Cell);
                }
            }
            // Make sure that the local target is completely valid: it is possible that thing is destroyed and Target.IsValid is still true.
            if (localTarget.HasThing && localTarget.ThingDestroyed)
            {
                Log.Warning($"M3G_UMIN appears to have been targeting a Thing but that Thing was destroyed. Using last known location: {lastKnownThingLoc}");
                localTarget = new LocalTargetInfo(lastKnownThingLoc);
            }

            // Spawn sky beam of death.
            if (cast)
            {
                bool worked = AttackVerb.TryStartCastOn(localTarget);
                if (!worked)
                {
                    Log.Error("Megumin verb cast failed!");
                    cast = false;
                }
            }

            if (!cast)
            {
                // Cast failed. Stop be beam effect immediately.
                OnStrikeEnd(null);
            }
            

            chargeEffect?.Stop(true, ParticleSystemStopBehavior.StopEmitting);

            // Put on cooldown.
            CooldownTicks = COOLDOWN_TICKS;

            // Delete target position.
            localTarget = LocalTargetInfo.Invalid;
            globalTarget = GlobalTargetInfo.Invalid;
            lastKnownThingLoc = IntVec3.Invalid;
            globalTargetMapLastKnown = null;

            // Spawn a solar flare event on the map that it was fired from.
            if (DoSolarFlare && cast)
            {
                IncidentParms param = new IncidentParms();
                param.forced = true;
                param.target = this.Map;

                bool canFire = AADefOf.SolarFlare.Worker.CanFireNow(param);
                if (!canFire)
                    Log.Warning("SolarFare Worker says that it cannot fire under the current conditions - forcing it to anyway, from M3G_UMIN.");

                bool worked = AADefOf.SolarFlare.Worker.TryExecute(param);
                if (!worked)
                    Log.Error("SolarFare Worker failed to execute (returned false), from M3G_UMIN.");
            }
        }
Beispiel #6
0
 protected void BeginBurst()
 {
     AttackVerb.TryStartCastOn(CurrentTarget);
     OnAttackedTarget(CurrentTarget);
 }
        protected new virtual void TryStartShootSomething(bool canBeginBurstImmediately)
        {
            if (progressBarEffecter != null)
            {
                progressBarEffecter.Cleanup();
                progressBarEffecter = null;
            }
            if (!Spawned || ((bool)AccessTools.Field(typeof(Building_TurretGun), "holdFire")?.GetValue(this) && CanToggleHoldFire) || (AttackVerb.ProjectileFliesOverhead() && Map.roofGrid.Roofed(Position)) || !AttackVerb.Available())
            {
                ResetCurrentTarget();
                return;
            }
            bool isValid = currentTargetInt.IsValid || worldTarget.IsValid;

            if (forcedTarget.IsValid)
            {
                currentTargetInt = forcedTarget;
            }
            else
            {
                currentTargetInt = TryFindNewTarget();
            }
            if (forcedWorldTarget.IsValid)
            {
                worldTarget = forcedWorldTarget;
            }
            else
            {
                //Find new target?
            }
            if (!isValid && (currentTargetInt.IsValid || worldTarget.IsValid))
            {
                SoundDefOf.TurretAcquireTarget.PlayOneShot(new TargetInfo(Position, Map, false));
            }
            if (!currentTargetInt.IsValid && !worldTarget.IsValid)
            {
                ResetCurrentTarget();
                return;
            }
            if (def.building.turretBurstWarmupTime > 0f)
            {
                burstWarmupTicksLeft = def.building.turretBurstWarmupTime.SecondsToTicks();
                return;
            }
            if (canBeginBurstImmediately)
            {
                BeginBurst();
                return;
            }
            burstWarmupTicksLeft = 1;
        }