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

Messages - MoreCowbell

#1
Hi there, so I'm learning how to mod rimworld and am loving it so far as I just love to code in general. The C# code I am great at, and almost really have no issues relating to that in specific. XML is however unfortunately not my strongest suit but I am working on it, and I had some questions that would help me greatly.

1. What is a Def: I understand the basic concept of a def, how xml reads it. Basically if I am right something has a "def" that determines the properties of that object. And for defs to be used either a new instance needs to be created with new MyDef(); and added to an object as a field. OR initialized via the in game def makers. When done via the second way it would seem that it does not create a new instance of the def, but an object referencing the def. As for my questions...

a) Is it possible to create a new instance of a def that is loaded from XML. Say for example I want to do some minor modifications to the def of Mote_Smoke during run time. I have tried to make an object itself and then modify the properties of the def after it is initialized from ThingMaker. However this seems to still use a reference to the graphics data of Mote_Smoke as well as its def.mote properties. As if I change them "vanilla" smoke functions like the changed smoke.

So onto my questions about each thing, I'll try to keep them organized. Sorry for my noobiness.

**Defs**


  • Is it possible to create instances of defs declared in XML and in C# in WhateverDefOf?
  • Is it possible to save a def created on runtime if given a unique defName?
  • Similar to Above, will the properties of that def save if they are modified for a certain object
  • Is it only possible to add defs to the database during the defloading phase?


**Things**


  • What "is" a thing: Say I want with just a texture or mote effect but no "world interaction properties" like say a plain red orb that draws on the map and follows the nearest pawn slowly, would that be a thing as it has a position?
  • Is it Possible for thing to exist without a map, say its a thing that should be persistent but cannot be moved with the colonist on colony transfer, can that thing exist with no map until a new one to place it is found?
  • Drawing of things: What determines where and what layer the thing is drawn on/in the map. Referring to the previous red orb say I want it to draw above floors but "under" walls and pawns, is there a way to do that?. Would I assign the visibility of the object during runtime based on what is in it's cell, or is there a better way using drawing layers?
  • Collision of things: Referring again to the orb example, will just moving the orb by its position every x ticks allow the orb to have "no collision". While I would like this thing to become invisible "under" certain objects. I do not want it to affect the objects it passes through in anyway.
  • When should you use Thing vs WorldObject vs Comps: I know that things have more data with regards to position and other things relating to the map. But say I want to create an object that ticks, and is attached to a pawn and persists from map to map. Would it be best to use a comp in that situation or a world object? 

**WorldObjects**


  • WorldObject Tick Tracking: What determines how world objects tick? I see an override method here but TickManager.RegisterThings() only takes a Thing and not a WorldObject



Thanks again for all the help, you guys are a great community and I'm loving learning to mod for the game and hope to publish something soon!
#2
Bugs / [Typo] Found a code Typo in Pawn_MindState
March 22, 2017, 03:50:30 PM
Heya Tynan, In pawn mind state isCombatEnhancingDrug is spelled as isCombat[Enan]cingDrug mostly throughout. While not huge just thought you should know.

Also I might be missing something but does that drug_comp actually do anything? I can't seem to find somewhere else it links to in the code.
#3
Help / [UI/Food] Making another action for corpses
March 22, 2017, 02:54:39 PM
Hi there, I was wondering how you would go about making another action for corpses. Such as a consume as drug action.

I am trying to make a vampire mod where a vampire can "consume" a corpse, destroying it instantly to recover some of his "blood" need.

The 2 ways I am thinking of doing it at the moment are if I can, modifying the foodtype of the vampire race to corpse/vampire only. and making "blood" based off of hunger. But to do that I need to modify the base "max" hunger of the race so a vampire eating a human corpse would do so in one go as opposed to several. Is doing so possible?

The other way is by using a drug addiction, which works already in the mod from which I am drawing most of my inspiration. But the issue is that to actually "make blood" the corpse has to be drained at a specific workbench which I dislike, is there a way to make the corpse itself consumable as a drug?

Ideally either would work, but knowing how to make an action for a corpse definitely would help for some stuff I am working on in the future as well.

Thanks a ton for any help.
#4
Just got it crazy enough, I made a simple no detour needed test tab mod. And it seems to work. Issue was that I was checking for typeof(Pawn) when psychology changed it to PsychologyPawn. I'm somewhat new to C# is there a way to check if it extends Pawn or is pawn? Otherwise I sorta figured out that one.
#5
I'm looking to make a spell mod and while I can seem to figure out most of the effect stuff, I cannot for the life of me add a "Spells" tab to the inspect pane of all pawns who have a hediff. Like I just can't get my tab to show up no matter what I do, I set up a DrawTabs override, a ITab_Pawn_Spells class and SpellsCardUtility class. Basically following from outfitter and psychology's code as an attempt to learn, but like I said I can't get it to show up.

Anyone kind enough to either walk me through the process or post an example code of say, creating a blank tab named like "Test" or something that pops a blank window up? Or one with options if that isnt hard. That shows up either in order (is that possible? my outfitter shows on the top right and is the only tab on that row) Or just at a fixed position.

PS: I am using HugsLib

Thanks a ton for any help, I've looked around and decompiled and all I just can't seem to get this part so any help would be amazing.


Q2:I'm pretty lost, but I sorta know the code for searching through the hediffs and using IsVisable() in itab. But is there something wrong with just doing that for visability?

Q3: Is there an easy way to attach another effect to a corpse other than consume such as making it a drug (like would that work?)? And would it be consumed as a drug then.

Edit: Just realized I should attach my code, like I said I'm not sure why its not working and all.

AssemblyInfo.cs: I copied the guid, is that a problem?
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.

[assembly: AssemblyTitle("VampireMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VampireMod")]
[assembly: AssemblyCopyright("${AuthorCopyright}")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("91fe8442-bf33-48f7-9112-78844a2a366d")]

// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion("1.0.*")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]



VampireModeBase.cs
using HugsLib;
using HugsLib.Settings;
using RimWorld;
using RimWorld.Planet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;
using Verse;
using Verse.AI.Group;
using Verse.Grammar;

namespace VampireMod
{
public class VampireModBase : ModBase
{




public override string ModIdentifier
{
get
{
return "VampireMod";
}
}




public override void DefsLoaded()
{
if (base.ModIsActive)
{
foreach (ThingDef current in DefDatabase<ThingDef>.AllDefsListForReading)
{
if (current.thingClass == typeof(Pawn))
{
current.inspectorTabs.Add(typeof(ITab_Pawn_Spells));
try
{
current.inspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(typeof(ITab_Pawn_Spells)));
}
catch (Exception ex)
{
Log.Error(string.Concat(new object[]
{
"Could not instantiate inspector tab of type ",
typeof(ITab_Pawn_Spells),
": ",
ex
}));
}

}
}
}
}


}
}



ITab_Pawn_Spells.cs
using RimWorld;
using System;
using UnityEngine;
using Verse;
using HugsLib.GuiInject;

namespace VampireMod
{
public class ITab_Pawn_Spells : ITab
{
//public static readonly ITab_Pawn_Spells.<>c <>9 = new ITab_Pawn_Spells.<>c();
public override bool IsVisible
{
get
{

foreach (Hediff current in this.PawnToShowInfoAbout.health.hediffSet.hediffs)
{
bool flag1 = current.Label.ToString().ToLower().Equals("secret of mana");
if (flag1)
{
return true;
}
}
return false;
//return true;
}


}

private Pawn PawnToShowInfoAbout
{
get
{
Pawn pawn = null;
if (base.SelPawn != null)
{
pawn = base.SelPawn;
}
else
{
Corpse corpse = base.SelThing as Corpse;
if (corpse != null)
{
pawn = corpse.InnerPawn;
}
}
if (pawn == null)
{
Log.Error("Character tab found no selected pawn to display.");
return null;
}
base.SelThing.def.inspectorTabs.Add(typeof(ITab_Pawn_Spells));
base.SelThing.def.inspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(typeof(ITab_Pawn_Spells)));
return pawn;
}
}

public ITab_Pawn_Spells()
{
this.size = new Vector2(500f, 550f);
this.labelKey = "TabSpells";
this.tutorTag = "Spells";
}

protected override void FillTab()
{
Pawn pawnForSpells = this.PawnToShowInfoAbout;
if (pawnForSpells == null)
{
Log.Error("Spell tab found no selected pawn to display.");
return;
}
Rect outRect = new Rect(0f, 20f, this.size.x, this.size.y - 20f);
SpellCardUtility.DrawPawnSpellCard(outRect, this.PawnToShowInfoAbout);

}
}
}


SpellCardUtility.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
using RimWorld;

namespace VampireMod
{
public class SpellCardUtility
{

public static void DrawPawnSpellCard(Rect outRect, Pawn pawn)
{
outRect = outRect.Rounded();
Rect rect = new Rect(outRect.x, outRect.y, outRect.width, outRect.height).Rounded();
rect.yMin += 11f;
DrawSpellList(rect, pawn);
}




public static void DrawSpellList(Rect inRect, Pawn pawn)
{
var buttonSize = new Vector2(inRect.x/1.5f, inRect.y/7f);
var newRect = new Rect(0, inRect.height - buttonSize.y, buttonSize.x, buttonSize.y).CenteredOnXIn(inRect);
if (Widgets.ButtonText(newRect, "Hello",true,false,true))
{
// do stuff
}

}
}
}