Starting raid attack

Started by SourceVG, May 31, 2014, 09:02:51 PM

Previous topic - Next topic

SourceVG

Can somebody shed some light on how to correctly start a raider attack? This is the code that is used to start one (found in Assembly-CSharp):


public override bool TryExecute(IncidentParms parms)
{
this.ResolveRaidPoints(parms);
if (!this.TryResolveRaidFaction(parms))
{
return false;
}
this.ResolveRaidStyle(parms);
this.ResolveRaidArrivalMode(parms);
this.ResolveRaidArriveCenter(parms);
TargetPack letterTarget = TargetPack.Invalid;
List<Pawn> list = PawnGroupMaker.GenerateArrivingPawns(parms, parms.faction, true).ToList<Pawn>();
if (parms.raidArrivalMode == RaidArrivalMode.CenterDrop || parms.raidArrivalMode == RaidArrivalMode.EdgeDrop)
{
DropPodUtility.DropThingsNear(parms.spawnCenter, list.Cast<Thing>(), parms.raidPodOpenDelay, true);
letterTarget = parms.spawnCenter;
}
else
{
foreach (Pawn current in list)
{
IntVec3 loc = GenSquareFinder.RandomStandableLOSSquareNear(parms.spawnCenter, 8);
ThingMaker.Spawn(current, loc);
letterTarget = current;
}
}
Find.LetterStack.ReceiveLetter(this.GetLetter(parms, letterTarget));
SquadBrain.MakeNewSquadBrain(parms.faction, this.GetSquadBrainStartState(parms), list);
Find.ConceptTracker.TeachOpportunity(ConceptDefOf.EquippingWeapons, OpportunityType.Critical);
return true;
}


An example or directions on the proper parameters to use, etc., would be very appreciated. Thank you.




mrofa

Write what do you want to do, its kinda hard to tell you which param to change if you dont specify what do you want do to :D

All i do is clutter all around.

SourceVG

Quote from: mrofa on May 31, 2014, 09:44:37 PM
Write what do you want to do, its kinda hard to tell you which param to change if you dont specify what do you want do to :D

I just don't know what the syntax is at all. Can you give me a basic example just to get a basic raid. If I see how it's supposed to be done then I can learn and edit it.




Justin C

Here is a quick rundown of everything happening in that function:
Quotepublic override bool TryExecute(IncidentParms parms)
{
   // This function gets the number of points for the raid. Points are used to determine how many raiders there are and of what kinds.
   this.ResolveRaidPoints(parms);
   
   // This attempts to get a hostile faction to set as the raiding faction. If it is successful, it returns true. Otherwise it returns false. The faction is set inside the parms object.
   if (!this.TryResolveRaidFaction(parms))
   {
      // If it was unsuccessful, return false, preventing the raid from happening.
      return false;
   }
   
   // This decides the raid style. Raiders can either attack immediately or stage for a bit before attacking.
   this.ResolveRaidStyle(parms);
   
   // This decides the arrival mode. Raiders can either drop in from orbit or walk in through the edge of the map.
   this.ResolveRaidArrivalMode(parms);
   
   // This decides the arrival center. All raiders will be spawned around this center point.
   this.ResolveRaidArriveCenter(parms);
   
   // The letterTarget is the pawn or location that the camera will move to when you click the "Go to event" button in the alert.
   TargetPack letterTarget = TargetPack.Invalid;
   
   // This generates a list of raiders for the chosen faction based on the number of points we have to spend.
   List<Pawn> list = PawnGroupMaker.GenerateArrivingPawns(parms, parms.faction, true).ToList<Pawn>();
   
   // If raiders are dropping in from orbit (there are two kinds that decide exactly where they drop in)
   if (parms.raidArrivalMode == RaidArrivalMode.CenterDrop || parms.raidArrivalMode == RaidArrivalMode.EdgeDrop)
   {
      // Call the function that drops the raiders in list onto the map
      DropPodUtility.DropThingsNear(parms.spawnCenter, list.Cast<Thing>(), parms.raidPodOpenDelay, true);
      
      // This means that when you click the "Go to event" button in the alter, the camera will focus on the center of the drop location
      letterTarget = parms.spawnCenter;
   }
   else   // If the raiders are walking in from the edge of the map
   {
      // For each raider we generated in the list
      foreach (Pawn current in list)
      {
         // Get a location that is 8 squares within the chosen spawn center
         IntVec3 loc = GenSquareFinder.RandomStandableLOSSquareNear(parms.spawnCenter, 8);
         
         // Spawn the currently selected raider at that location
         ThingMaker.Spawn(current, loc);
         
         // Set the letter target to the current pawn. Since this is set for every single pawn, at the end of the spawn
         // it will be the very last raider spawned that the camera is going to focus on when you click the "Go to event" button.

         letterTarget = current;
      }
   }
   
   // Once the raiders are all spawned, send an alert.
   Find.LetterStack.ReceiveLetter(this.GetLetter(parms, letterTarget));
   
   // Generate a squad brain to control the raiders. This keeps track of the status of the raiders and decides when they should flee or give up, among other things.
   SquadBrain.MakeNewSquadBrain(parms.faction, this.GetSquadBrainStartState(parms), list);
   
   // This just shows a tutorial message if the player has not yet equipped any weapons.
   Find.ConceptTracker.TeachOpportunity(ConceptDefOf.EquippingWeapons, OpportunityType.Critical);
   
   // Return true so the function calling this one knows it was successful.
   return true;
}

As you can see, when this function is called it pretty much handles generating the entire raid for you. Factions, along with their raider spawn groups, are defined in the XML. So I'd go look at the FactionDefs to get an idea of how they work if you plan on customizing raids or something. And if you need more help you should be more specific about what you are trying to accomplish so we know where to begin.

SourceVG

Thanks for the break-down.I just want to simply call the raid to happen. For instance, what code should be written to have a group of raiders spawn on the side of the map and attack the colony immediately.

I don't know how to call the TryExecute() function or what to put in the arguments (the "parms"). I don't want to customize raids at all, just execute one to happen.




Justin C

Quote from: SourceVG on May 31, 2014, 10:08:06 PM
Thanks for the break-down.I just want to simply call the raid to happen. For instance, what code should be written to have a group of raiders spawn on the side of the map and attack the colony immediately.

I don't know how to call the TryExecute() function or what to put in the arguments (the "parms"). I don't want to customize raids at all, just execute one to happen.
The storyteller normally handles that stuff automatically. Incidents are defined in the IncidentDefs, and the storyteller picks incidents based on a number of different variables you can set in the XML, like the threat level, the minimum fire interval, etc. If you want to force an event to happen instead of waiting for the storyteller to make it happen you will have to do it in a library.

Something along these lines should work. You will have to experiment a bit yourself.
IncidentDef raidDef = IncidentDef.Named("RaidEnemy");
Find.Storyteller.incidentQueue.AddQueuedIncident(new QueuedIncident(raidDef));

But there are checks in place to make sure the game isn't firing incidents when it's not supposed to, so those might get in the way if you are trying to use incidents in a way Tynan didn't intend for them to be used.

SourceVG

Thanks! That is exactly what I needed. I'll start experimenting and I'll get back to you with the results  :D




Tynan

Amazing writeup by Justin C!

You can actually hard-execute any incident and completely bypass the storyteller like this:


IncidentParms parms = new IncidentParms();
parms.points = 500; //Or whatever you want

//Can configure other fields of parms here to get a specific faction, etc.

IncidentDef.Named("RaidEnemy").Worker.TryExecute( parms );
Tynan Sylvester - @TynanSylvester - Tynan's Blog

Justin C

Quote from: Tynan on June 01, 2014, 08:54:03 PM
Amazing writeup by Justin C!

You can actually hard-execute any incident and completely bypass the storyteller like this:


IncidentParms parms = new IncidentParms();
parms.points = 500; //Or whatever you want

//Can configure other fields of parms here to get a specific faction, etc.

IncidentDef.Named("RaidEnemy").Worker.TryExecute( parms );

Oh, nice. That's very useful to know. ;D

SourceVG

Thanks, Tynan. Going to edit my code now  :)