Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - Xnope

#1
Trying to package a core library with my mods, but I don't want to double load it if several of my mods exist in the same mods list. Double loading works fine, the game plays, but a slew of errors come about and I have a hunch it's not very good practice.

Any way to use HugsLib (or just Verse) to detect if an assembly is already loaded, then halt loading it again?
#2
It's used in many pieces of source code that have to do with random events occurring. I believe there are also some values represented in defs. I think it might mean 'minimum time before', but in some cases this doesn't make sense, i.e. with mtbDays for parties being 40 yet in-game you can have way more parties within 40 days than just one. I dunno. If anyone knows more, I'd appreciate the knowledge :)
#3
Help / [C#] How to get a pawn's health as float
July 19, 2017, 08:43:24 AM
This may be a dumb question, but I've been pouring through the source for a half hour now. How the hell do you get any given pawn's health value as a float > 0f? I'm trying to use TryRandomElementByWeight() with a weight selector for pawns' health values, but I get errors because apparently Pawn.HitPoints returns -1. Currently the only way I can find is to programmatically calculate a pawn's health via Hediff injuries, but even that doesn't give me quite what I want AND it's pretty inefficient.

Halp.
#4




POST UNDER CONSTRUCTION.
UPDATE: An alpha is ready! See attachment or GitHub page for download.


An Introduction



At its core, CARNIVÀLE adds a set of new incidents and a new faction type: roaming carnivals.

But it's more than that.

The carnival coming to town is a special event that you want desperately to happen to you. You will sit patiently waiting, sometimes for seasons, years, for it to happen to you. You want it because life on the rimworlds is dreary and dark and any thing to distract you from the harsh realities that stand between you and survival is a warmly welcomed thing; and when it does happen to you, when the carnival does come to town, it will inevitably have to move on, and you will be left counting the days until the next one.

You might fall in love with a carny, or you might make mortal enemies. You might find a rare curiosity that could save your life one day, or you might be ripped off by a particularly clever vendor. You might win a prize shooting milk bottles, or you might lose your favourite pair of shoes in a game of chance.

For some of you, the promise of return will be the only reason to carry on. Whatever the carnival brings to town, it is a much-needed respite from the day-to-day life of a rimworlder.




I made this mod because I wanted a more interesting mood booster than the vanilla psychic soothe. I wanted to add colour to RimWorld, while at the same time preserving its grimy, wild-west, space-cowboy feel. For this, I decided to base the concept and aesthetics off of the long-cancelled HBO show of the same name, 'CARNIVÀLE'. Hopefully, I will succeed in my goals, and this mod will not only mesh well with the vanilla game, but also give psychological survival more depth.





Features, Ordered by Completeness




  • Carnival factions will request to visit your colony over radio (can happen with or without a Comms Console). If you accept, they will arrive the next day. The chance of this occurrence is the same as vanilla Psychic Soothe — that is, a base chance of 1.0 and a minimum of 15 days between occurrences.


  • Upon arrival, carnies will set up their buildings some distance away from your colony. If they do not need rest afterward, they will be open to colonists between the hours of 10:00 and 22:00. They will pack up and leave from two to four days later.


  • Tents are buildings with walls and a roof that pawns can go inside of. Colonists cannot enter some kinds of tents, but others (like the 'chapiteau') are accessible for a small silver fee per colonist. (Chapiteau functionality not implemented yet).


  • While setting up, they may have to cut down a few plants in order to construct their buildings. Carnies can't take most of the products of these plants with them, so they will be hauled to a 'trash' location designated by a sign. These items are free for colonists to take.


  • While open, vendors will stand in stalls and be available to trade with. There are currently three types of vendors: food, curios, and surplus.


  • Carnies have many unique backstories and traits, often suited to their roles in the carnival.


  • While in town, most colonists and visitors will get a mood boost (+10 currently). Pessimists and Depressives will get a very minor mood boost (+1).


  • Vendors and announcers now throw randomised text motes! Things like, 'Get your lavish meals, right here!', where 'lavish meal' can be replaced by any random higher-value item within that vendor's goods.


  • The first game (High Striker) is fully textured (with jumping striker graphic included!), is able to be played, and awards prizes if the striker hits the bell. Your chance to win this game is influenced by melee skill, and the 'luckiness' statistic. Future games will touch on skills like shooting and social. Currently, all pawns except certain carnies have +1% luckiness. In the future, pawns will be initially assigned a small random luckiness stat, which would increase slightly each time they survive a deadly ailment or win carnival games.


  • In order to play games, you must first pay the entry fee by right-clicking on the entrance sign. The price per colonist ranges between 9 and 30 silver, which scales based on how big the carnival is and how many colonists you have. Vendors can be traded with without paying this fee.


  • (v0.0.6+) They defend themselves quite intelligently when threats arise. If they have enough time, they will build an additional sandbag wall or two between them and the hostiles.


  • (v0.0.8+) Shows occur randomly throughout their open hours. If a colonist has paid the entrance fee that day, they will automatically attend the show if they have no other orders. Attending the show gives a stacking mood buff based on how long the colonist stays watching the show. This buff lasts 10 days.


  • (v0.0.8+) Greatly improved cell finding. Should not be any more issues with where or how they set up. Also reduced their radius, so it's not such a hike to get to and fro.


  • For a full, but messy, list of planned features and more, visit the GitHub page.




Screenshots



Some currently working things:


The 'chapiteau', or main event tent:


Radio contact and mood boost!


Pay at the entrance sign:


Play games to win prizes:




Downloading



Remember that this mod is in its first alpha releases. I mostly need testers to tell me if they find any bugs, if they find any incompatibilities with other mods, if the event triggers too often or not often enough, if they have any suggestions, etcetera. To my knowledge, the mod is fairly stable and I've tested it against several mods and with existing saves, all without any issues so far. Note that I may have accidentally left some testing code in the mod, things like log messages and insta-winning games, but any of it should only have an effect if you are in dev mode.

So download below! It now comes packaged with XnopeCore, so you don't need two separate downloads. Also, requires HugsLib, but what doesn't nowadays?

As of v0.0.9, the only difference is it has the nuke mod setting. You MUST use this function before uninstalling.

TO UNINSTALL:

  • Go to mod settings in options and click the red X next to 'Nuke Everything'.
  • Return to the main menu and deactivate the mod.
  • Load the generated save file with the appendix '_Nuked'
  • Voila. Save from this game from then on.
  • You can also use this nuke function without deactivating the mod to fix some bugs with the mod, i.e. if they showed up and never leave. Reloading the map will regenerate new factions.

Disclaimer: While this works with pre-existing saves, I'm not responsible for messing anything up. This is not to be treated as a release. If in doubt, don't use this mod yet (especially if you have a long mods list) unless you want to give it a whirl and leave feedback. Release is nigh!

[attachment deleted by admin due to age]
#5
EDIT: I found the problem, see below reply if interested. Big ol' never mind.

Alright so I've moved a lot of my data structures to a MapComponent, but after the move I'm getting errors with ExposeData() while loading (but not saving).

The problem is with any collection containing ILoadReferenceables. Here is what one example looks like in a save file:


<li Class="Carnivale.CarnivalInfo">
...
<carnivalBuildings>
<li>Thing_Carn_StallSurplus15063</li>
<li>Thing_Carn_SignTrash15069</li>
<li>Thing_Carn_StallSurplus15071</li>
<li>Thing_Carn_TentMedBed15079</li>
<li>Thing_Carn_StallFood15109</li>
<li>Thing_Carn_TentSmallMan15112</li>
<li>Thing_Carn_SignEntry15135</li>
<li>Thing_Carn_TentMedBed15197</li>
</carnivalBuildings>
...
</li>


No apparent problems while saving. Each element of the list is a valid reference ID to a thing that is deep-saved elsewhere in the save file. When loading, however, I get errors like this:


Could not get load IDs list. We're asking for something which was never added during LoadingVars. pathRelToParent=/carnivalBuildings, parent=Carnivale.CarnivalInfo
Verse.Log:Error(String)
Verse.LoadIDsWantedBank:TakeList(String, IExposable)
Verse.CrossRefHandler:TakeResolvedRefList(String, IExposable)
Verse.CrossRefHandler:TakeResolvedRefList(String)
Verse.Scribe_Collections:Look(List`1&, Boolean, String, LookMode, Object[])
Verse.Scribe_Collections:Look(List`1&, String, LookMode, Object[])
Carnivale.CarnivalInfo:ExposeData()
Verse.CrossRefHandler:ResolveAllCrossReferences()
Verse.ScribeLoader:FinalizeLoading()
Verse.Game:LoadGame()
Verse.SavedGameLoader:LoadGameFromSaveFile(String)
Verse.Root_Play:<Start>m__84F()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__84C()


And then if I save again, of course the references were never reconstructed so I get blank entries in the save file.


<li Class="Carnivale.CarnivalInfo">
...
<carnivalBuildings />
...
</li>


This is what my ExposeData() looks like:


public override void ExposeData()
{
...
Scribe_Collections.Look(ref this.carnivalBuildings, "carnivalBuildings", LookMode.Reference);
...
}


As I've said I recently moved my data structures over to a MapComponent. I wasn't getting errors like this before with the same ExposeData() code, so my guess is that MapComponents are somehow exposed differently, or else I'm going nuts.

Any help or ideas as to what's going on would be awesome. I'll post what happened if I find out first, for anyone else curious.
#6
EDIT:
I agree with Fluffy that this was a bad idea to begin with. I suppose I treat all of my coding projects as learning opportunities, and I just wanted to see if I could do something clever/complicated that may or may not actually be clever, but at least uses coding concepts new to me. I once spent two or three months twiddling with bits just to optimise a data structure in Java that merely dealt with a set of enums.
It was a ridiculous example of ignoring the ol' coding adage "Optimise never, except later."
Anyway, paz.
END EDIT.

I'm trying to optimise ruin some of my code by using Dictionary<int, bool> instead of Dictionary<Pawn, bool>, where the int key for the former dictionary is Pawn.thingIDNumber. This works for checking if a Pawn is in the dictionary without any fuss, but I have other applications where I would need to retrieve a loaded ILoadReferenceable by its unique ID. In writing this utility function, I get stuck here:


public static bool TryGetThingByLoadIDNumber(int id, string defName, out Thing thing)
{
    string uniqueLoadId = "Thing_" + defName + id;
    // ???
   
}


Any help?

Edit 1: I know I should somehow use Verse.LoadedObjectDirectory.ObjectWithLoadID<T>(string LoadID), but it is an instance method and I have no idea where to access the probably singleton instance of this class. I found it referenced in Verse.CrossRefHandler, but there it is private and it is also an instance field. I can't seem to find out where to access these instances.

Edit 2: Would it be feasible to use a Harmony Traverse helper to access hidden fields? Also to access specific instances of these classes?
#7
Hey guys. I'm somewhat new to the RimWorld modding crowd, so here goes my first post that might help a few of you creators out there.

I made a core mod that you can pick up on GitHub. This mod allows for a few new things for modders:

       
  • Add custom backstories with Defs
  • Inject custom spawnCategories into existing backstories with Defs

    •       
    • This means you could create a custom backstory MyBackstory and give it a custom spawnCategory MySpawnCategory, and then inject this new spawn category into the existing backstory 'Con artist' for example, or the existing spawnCategory 'Civil', for example.
  • Adds extended functionality to factions, currently including:

    •       
    • Roaming factions: they roam about in caravans, but do not have any settlements. Similar to a hidden faction, only you can track and maintain relations with them via the Factions tab or the Comms Console.

    •       
    • Dynamically-named factions: a faction can be named dynamically based on what its leader's name is. Must have a custom RulePackDef namer that includes the string 'LNAME' to be replaced by the generated leader's name. This currently works, however more extensive work will be done on this feature later.
  • And most importantly, the Defs folder of this mod contains example .txt files that thoroughly outline how to use this mod for creating purposes. Please remember that these .txt files must be renamed to .xml files if you want to edit them directly into a usable Def.
Here are some examples of usage that are taken from my currently work-in-progress mod, Carnivale.

Creating a new backstory with a custom spawn category:

<!-- Gypsy Child-->
  <Xnope.Defs.BackstoryDef>
    <defName>XnopeBS_GypsyChild</defName>
   <slot>Childhood</slot>
   <title>Gypsy child</title>
   <titleShort>Gypsy</titleShort>
   <baseDescription>Folks used to say that gypsies are an ancient human culture often gifted with powers of foresight, and that is why they have been fortunate enough in their wanderlust to have survived the eons since their genesis on Earth. NAME was raised by HIS mother, a rare woman fabled to have descended from these great wandering folk.</baseDescription>
   
   <skillGains>
     <li><defName>Social</defName><degree>2</degree></li>
     <li><defName>Medicine</defName><degree>4</degree></li>
   </skillGains>
   
   <forcedTraits>
     <li><defName>PsychicSensitivity</defName><degree>2</degree></li>
     <li><defName>Luckiness</defName><degree>1</degree></li>
   </forcedTraits>
   
   <spawnCategories>
     <li>Carnivale</li>
     <li>Slave</li>
   </spawnCategories>
   
  </Xnope.Defs.BackstoryDef>


(Worth noting that the 'Luckiness' forced trait is a trait that my mod adds as well.)

Injecting the new spawn category into existing backstories:

  <Xnope.Defs.SpawnCategoryInjectorDef>
    <defName>SCI_Carnivale</defName>
   
    <newCategory>Carnivale</newCategory>
   <injectToBackstories>
     <li>Actor</li>
     <li>Con artist</li>
     <li>Courtesan</li>
     <li>Escaped convict</li>
     <li>Musician</li>
     <li>Medieval doctor</li>
     <li>Medieval minstrel</li>
     <li>Bodyguard</li>
     <li>Caravaneer</li>
     <!-- childhood -->
     <li>Apocalypse survivor</li>
     <li>Caravan traveler</li>
     <li>Mute</li>
     <li>Refugee</li>
     <li>Child slave</li>
     <li>Circus performer</li>
     <li>Medieval thief</li>
     <li>Sickly child</li>
   </injectToBackstories>
  </Xnope.Defs.SpawnCategoryInjectorDef>


Doing this populates my new custom spawn category so that more than just the custom backstories I've added will show up when a pawn in this category is spawned. This is great for immersion and variability, as we don't want every pawn with the 'Carnivale' spawn category to have the same childhood.

Here is an example of how to add or modify a PawnKindDef to utilise this new spawn category:

  <PawnKindDef Name="PawnKinds_Core" Abstract="True">
    <race>Human</race>
    <backstoryCategory>Carnivale</backstoryCategory>
  </PawnKindDef>


I had a problem with the vanilla code for generating pawns, and that is that the <backstoryCategory> field in PawnKindDefs was essentially ignored and never used for anything; a pawn's faction's <backstoryCategory> was always used to decide a pawn's backstory. I changed this with a Harmony patch, so now pawn generation prefers using a PawnKindDef's <backstoryCategory> over a FactionDef's, which it will only revert to if there is no <backstoryCategory> in a pawn's PawnKindDef. So, it's worth noting that only with my mod can you make PawnKindDef's <backstoryCategory> do anything meaningful.

I would very much like to write up more in-depth tutorials, but I first want to focus on getting my mod Carnivale to release. I just thought I'd share this here so that other creators out there can make use of the minor changes and additions I've made.

Cheers
#8
Help / [A17] XML Patch causes black screen
May 24, 2017, 02:59:35 PM
After "InitializingInterface" but before "Loading Defs" appears, this patch causes the game screen to go black and the music doesn't even start playing:


<Patch>
  <Operation Class="PatchOperationReplace">
    <xpath>//StatDef[defName = "MiningYield"]/</xpath>
<value>
  <maxValue>1.15</maxValue>
</value>
  </Operation>
</Patch>


Perhaps I just don't quite understand how patching works? I was using a def override before but decided since I was changing just his one value to give xml patching a stab.