So I tried to clone the Heat Wave event

Started by RemingtonRyder, May 03, 2015, 08:22:21 PM

Previous topic - Next topic

RemingtonRyder

It didn't go so well!

I'm using Xamarin Studio (because it's a bit lighter than VS). When I cloned the heat wave from Rimworld (map condition and the event firer) there was a base..ctor() and base..ctor( MapConditionDefOf.VariableHeatWave, duration ) in two of the functions. They wouldn't compile. I'm guessing they do something, or nothing, but I don't know.

Latta

#1
They are construCTORs. If you decompiled, they are (usually?) subjects to be removed as real constructors will get deconpiled separately.

But I see parameters with it! You should do the same, base(MapConditionDefOf...)

1000101

#2
I use Xamarin Studio for dev but ILSpy and jetBrains dotPeek for decompiling, they seem to do a better job.  You shouldn't have too much issue extending the existing alerts, I've extended a couple for my own personal mods.

example, my extension of the hopper alert to allow any building with "CompHopper": public class Alert_BuildingNeedsHopper : Alert_PasteDispenserNeedsHopper
{
public Alert_BuildingNeedsHopper()
{
baseLabel = "NeedHopperAttached".Translate();
baseExplanation = "NeedHopperAttachedDesc".Translate();
}

public override AlertReport Report
{
get
{
//string derp;
foreach( Building building in Find.ListerBuildings.allBuildingsColonist )
{
bool thisNeedsHopper = false;
//derp += building.def.defName + " - wantsHopperAdjacent == " + building.def.building.wantsHopperAdjacent ) + "\n";
if( building.def.building.wantsHopperAdjacent )
{
thisNeedsHopper = true;
foreach( IntVec3 c in GenAdj.CellsAdjacentCardinal( building ) )
{
Building hopper = GridsUtility.GetEdifice( c );
if( ( hopper != null )&&
( hopper.GetComp<CompHopper>() != null ) )
{
//derp += building.def.defName + " - Has hopper\n" );
thisNeedsHopper = false;
break;
}
}
}
if( thisNeedsHopper ){
//Log.Message( derp );
return AlertReport.CulpritIs( building );
}
}
return false;
}
}
}
(2*b)||!(2*b) - That is the question.
There are 10 kinds of people in this world - those that understand binary and those that don't.

Powered By

Tynan

public class MapCondition_HeatWave : MapCondition
{
//Constants
private int LerpTicks = 12000;
private float MaxTempOffset = 20;

//Properties
public float TemperatureOffset
{
get
{
float lerpValue;
if( TicksPassed < LerpTicks )
lerpValue =  (float)TicksPassed / (float)LerpTicks;
else if( ticksToExpire < LerpTicks )
lerpValue =  (float)ticksToExpire / (float)LerpTicks;
else
lerpValue =  1f;

return Mathf.Lerp( 0, MaxTempOffset, lerpValue );
}
}

public MapCondition_HeatWave(){}
public MapCondition_HeatWave( int duration ) : base( MapConditionDefOf.HeatWave, duration ){}

public override void PreEnd()
{
Messages.Message( "HeatWaveOver".Translate() );
}
}

public class IncidentWorker_HeatWave : IncidentWorker
{
public override bool StorytellerCanUseNow()
{
if( GenTemperature.SeasonalTemp < 20 )
return false;

return !Find.MapConditionManager.ConditionIsActive( MapConditionDefOf.HeatWave );
}

public override bool TryExecute( IncidentParms parms )
{
if( Find.MapConditionManager.ConditionIsActive(MapConditionDefOf.HeatWave) )
return false;

int duration = Rand.Range(2,5) * GenDate.TicksPerDay;
Find.MapConditionManager.RegisterCondition( new MapCondition_HeatWave(duration));

        Find.LetterStack.ReceiveLetter("LetterLabelHeatWave".Translate(), "LetterHeatWave".Translate(), LetterType.BadNonUrgent);

return true;
}
}
Tynan Sylvester - @TynanSylvester - Tynan's Blog

RemingtonRyder

Thanks Tynan, that should be really helpful. :)

RemingtonRyder

#5
So still a little bit of a snag, but I think I understand what the problem is.

I have a new map condition with a temperature offset, but in the MapConditionManager class, heat wave and cold snap are checked to get the current active temperature offset. So I need to add a similar provision to check for a custom map condition causing a temperature offset, right?

Anyway, I tried, but I keep getting this:

NullReferenceException: Object reference not set to an instance of an object
  at RimWorld.MapCondition.get_Label () [0x00000] in <filename unknown>:0

  at RimWorld.MapCondition.get_LabelCap () [0x00000] in <filename unknown>:0

  at RimWorld.MapConditionManager.TotalHeightAt (Single width) [0x00000] in <filename unknown>:0

  at RimWorld.GlobalControls.GlobalControlsOnGUI () [0x00000] in <filename unknown>:0

  at RimWorld.UIRoot_Map.UIRootOnGUI () [0x00000] in <filename unknown>:0

  at Verse.Root.OnGUI () [0x00000] in <filename unknown>:0



RemingtonRyder

I even tried just overriding the original heat wave event, which doesn't generate a whole heap of errors. However, it seems that I'm only able to affect the length of the heatwave, not its intensity. Indeed, because heatwave intensity is sort of linked to duration, they ended up being quite tame. :P