Author Topic: Duplicating an existing faction more easily  (Read 4154 times)

Offline RocketAssistedPuffin

  • Arcen Volunteer
  • Sr. Member
  • *****
  • Posts: 260
Duplicating an existing faction more easily
« on: August 09, 2018, 04:33:38 pm »
In several modding attempts, in things like making a Copycat Macrophage for Astrotrains to spawn, or a Devourer variant, I've...always tried copying those factions over, so they can be separate. However this causes a lot of errors, I think just due to things being defined in multiple locations? I've tried renaming the class definitions, and this fixes a fair number, but then adds even more, of all kinds that I don't really understand. These factions were going to use the existing code, essentially as is, and only have XML changes. Is there a simpler way to get a separate one for this purpose? I've tried watching Keiths modding tutorial on the C++ part but found it hard to follow or understand, and googling anything hasn't gone well so far, because well...I'm not particularly good at programming, never had much interest until this game.

If I'm in over my head, please say so! It'd get me to stop trying this repeatedly at least!

Autistic, so apologies for any communication difficulties!

Offline x4000

  • Chris McElligott Park, Arcen Founder and Lead Dev
  • Arcen Staff
  • Zenith Council Member Mark III
  • *****
  • Posts: 31,651
Re: Duplicating an existing faction more easily
« Reply #1 on: August 09, 2018, 04:41:04 pm »
What I would typically do is do a global case-sensitive rename in that file that you've copied.

So if you copied something that is MacrophageBlahBlah, and it has a bunch of classes in it named MacrophageThis and MacrophageThat, and some variables named macrophageVar... you want to go in and replace "Macrophage" with "RocketAssistedJelly" and "macrophage" with "rocketAssistedJelly".

At that point, assuming that all of the relevant things are in that one file, things should compile.  There are some other files that then reference this, such as the xml files with the ships in them, but you just then copy those and do the same replace again.  At that point you have a working copy that you can add to as you like.

Hope that helps!
Have ideas or bug reports for one of our games?  Mantis for Suggestions and Bug Reports. Thanks for helping to make our games better!

Offline BadgerBadger

  • Arcen Volunteer
  • Hero Member Mark III
  • *****
  • Posts: 1,229
  • BadgerBadgerBadgerBadger
Re: Duplicating an existing faction more easily
« Reply #2 on: August 09, 2018, 05:12:17 pm »
Doing a case sensitive rename just in Macrophage.cs is going to break confusingly, because many of the those classes are also referred to elsewhere in the code (and the XML).

Keith's tutorials are intended to be introductory (and some of the logic is out of date). Most of the complex techniques I'm using aren't really covered in there.

To have it look like a Minor Faction is spawned by the Astro Trains, the simplest thing to do would be to start the game with your RocketPropelledFaction enabled and with defined behaviour, but that starts without any units. Then define an AstroTrain Depot that would create some RocketPropelled units that would follow the logic you have. This is quite similar to how the Instigators work, but their units are created on a Time basis instead of an Astro Train arriving basis.

In more detail. Lets say you want to create RocketPropelledBadgers that would attack the player when an Astro Train arrives at the right depot.
First, imitate the Instigators to create an Always-On faction that's hostile to the player but friendly to the AI (note that the definition requires both XML and C# components). Then write DoLongRangePlanning code to say "If I have any RocketPropelledBadgers, send them to the player's home planet" (you can again look at the Instigators to see how to do this). Then create a Depot whose rules say "When a train arrives, create X RocketPropelledBadgers that belong to the RocketPropelledFaction". Finally, define some RocketPropelledBadgers in the XML.

I would start with something simple like that (leaning heavily on the Instigators code as a model), and if that's fun then you can define more complex factions. I would not recommend starting with more complex minor factions like the Macrophage unless you are an experienced coder.

You might also be interested in the "Mayhem Consultant" perk on backerkit ;-)
« Last Edit: August 09, 2018, 05:20:26 pm by BadgerBadger »

Offline RocketAssistedPuffin

  • Arcen Volunteer
  • Sr. Member
  • *****
  • Posts: 260
Re: Duplicating an existing faction more easily
« Reply #3 on: August 09, 2018, 07:31:03 pm »
Well thank you both for this. The classes being referenced elsewhere was the problem I got after the simple renames. Because of that, and Badger using Instigators as an example, I decided to poke the Devourer with a stick (as Instigators aren't out yet).

So far he's renamed the Cookie Monster, has his own name, description, faction description, game entity and unit tags, as well as his own named long term planning, though it's just the same as the original. Been trying to replace it with that of an Enraged Macrophage Harvester, but it doesn't want to be angry. Think on that front I'll wait for Instigators, as that's a pretty simple code from what you're saying, so it should fit in much more easily.

Also figured out how to make it not spawn anything at game start, too, in the C code.

The only other oddities I encountered was, I tried to make the Monsters XML data as a mod to be loaded, but it never did. I've been able to get the game to load in things very similar to the example mod (a Thanatos speed change to "Blitzer"), but adding in a new SpecialFaction to the list didn't work, so I just threw him in the...main? file, and he's happy enough there. I tried having an XML of just  him put into that folder, and a copied version of VanillaEntries with him added in, but neither worked. No errors, he just never showed up.

Second, I tried to give him the Fighters gun...but he very stubbornly hugged his DevourerGun close. I imagine this is a moot problem though, since this is changing in the Era of Discovery update. Still, curious.
« Last Edit: August 09, 2018, 09:15:31 pm by RocketAssistedPuffin »
Autistic, so apologies for any communication difficulties!

Offline BadgerBadger

  • Arcen Volunteer
  • Hero Member Mark III
  • *****
  • Posts: 1,229
  • BadgerBadgerBadgerBadger
Re: Duplicating an existing faction more easily
« Reply #4 on: August 09, 2018, 09:33:43 pm »
The Anger of the enraged harvesters is in here in DoLongRangePlanning in Macrophage.cs
Code: [Select]
                else if(entity.TypeData.GetHasTag("MacrophageEnragedHarvester"))                                                                                                                                       
                {     
                    //if this unit is an enraged harvester                                                                                                                                                                                                 
                    entity.EntitySpecificOrders.SetBehavior( EntityBehaviorType.Attacker, -1 );                                                                                                                       
                    //find a target kingPlanet
                    Planet kingPlanet = BadgerFactionUtilityMethods.findHumanKing();                                                                                                                                   
                    if(humanAllied)                                                                                                                                                                                   
                        kingPlanet = BadgerFactionUtilityMethods.findAIKing();                                                                                                                                         
                    if(kingPlanet == null && debug)                                                                                                                                                                   
                    {                                                                                                                                                                                                 
                        ArcenDebugging.ArcenDebugLogSingleLine("The king is dead, so just chill", Verbosity.DoNotShow );                                                                                               
                        return DelReturn.Continue;                                                                                                                                                                     
                    }                                                                                                                                                                                                 
                    if(debug)                                                                                                                                                                                         
                        ArcenDebugging.ArcenDebugLogSingleLine("Enraged Macrophage " + entity.PrimaryKeyID + " on " + entity.Planet.Name + " is heading for a human king at " + kingPlanet.Name, Verbosity.DoNotShow )\
;                                                     
                     //find the path to that planet (the path is a List of Planets that need to be traversed between where the entity Is and where it wants to go                                                                                                                                                                 
                    List<Planet> path = faction.FindPath( entity.Planet, kingPlanet, Context );                                                                                                                       
                    if ( path.Count > 0 )                                                                                                                                                                             
                    { 
                        //units are told where to go via these GameCommand objects. This is necessary to keep things in sync for multiplayer                                                                                                                                                                                               
                        command = GameCommand.Create( BaseGameCommand.CommandsByCode[BaseGameCommand.Code.SetWormholePath], null );                                                                                   
                        command.RelatedEntityIDs.Add( entity.PrimaryKeyID );                                                                                                                                           
                        for ( int k = 0; k < path.Count; k++ )                                                                                                                                                         
                            command.RelatedPlanetIndices.Add( path[k].PlanetIndex );                                                                                                                                   
                        Context.QueueCommandForSendingAtEndOfContext( command );                                                                                                                                       
                    }                                                                                                                                                                                                 

Offline RocketAssistedPuffin

  • Arcen Volunteer
  • Sr. Member
  • *****
  • Posts: 260
Re: Duplicating an existing faction more easily
« Reply #5 on: August 10, 2018, 10:16:49 am »
Thanks Badger (again)! I was using that bit, just didn't think of the bit "below" it.

Now Cookie Monster beelines for the homeworld, destroys it then hangs out as he has no targets. It's a bit...cobbled together? But it doesn't error, and still gives the "Human King is dead" debug line. Helped me understand a fair chunk of the logic here.

Next thing might be to try and make him into a Doomsday timer, i.e don't seed at start, instead use the Zenith Traders respawn mechanic to get him in the game at a later time. Then beelines for the player and kills them. Think I can do that easily.

Don't think I need anything else, thanks again.
Autistic, so apologies for any communication difficulties!