Creating a Custom Disaster
You can create your own custom disasters using a CustomDisaster
class, provided by RogueLibs. You can configure the disaster's name, description and both of the messages that are displayed at the beginning of the floor. And, of course, you can determine the conditions that the disaster can (or must) happen under, and what happens at the start of and during this disaster. Additionally, you can quickly and easily create a removal mutator that removes your disaster from the pool.
CustomDisaster
class
To make a custom disaster, you need to create a class deriving from CustomDisaster
:
public class MyCustomDisaster : CustomDisaster
{
/* ... */
}
There are 3 methods that you need to implement:
public class MyCustomDisaster : CustomDisaster
{
public override void Start() { /* ... */ }
public override void Finish() { /* ... */ }
public override IEnumerator? Updating() { /* ... */ }
}
Start
is called when the disaster starts. Finish
is called when the disaster ends.
Start
and Finish
methodsThese methods are called between levels, so some stuff might not be available at the time they're called.
Updating
returns the updating coroutine for the disaster. It starts after the disaster's notification. It is stopped automatically, when the disaster ends. If your disaster doesn't need updating, you can just return null
.
Disaster Conditions
If you want your disaster to appear only under certain conditions, override the Test
method:
public class MyCustomDisaster : CustomDisaster
{
public override bool Test()
{
// for example, if it's a Park level
return CurrentDistrict == 2;
}
}
CustomDisaster
exposes several useful properties for that:
CurrentDistrict
- index of the current level's district. (0
- Slums,1
- Industrial,2
- Park,3
- Downtown,4
- Uptown,5
- Mayor Village)CurrentFloor
- index of the current level's floor of the district. (0
,1
or2
in a normal playthrough, and0
or1
with "Quick Game" mutator on)CurrentLevel
- index of the current level. (0-2
- Slums,3-5
- Industrial,6-8
- Park,9-11
- Downtown,12-14
- Uptown,15
- Mayor Village) (or0-1
,2-3
,4-5
,6-7
,8-9
,10
if Quick Game is on), and more in Endless mode)
And, if you want to force your disaster onto a level, override the TestForced
method.
public class MyCustomDisaster : CustomDisaster
{
public override bool TestForced()
{
// for example, if there's a Mayor on the level
return gc.agentList.Exists(a => a.agentName === VanillaAgents.Mayor);
}
}
At the moment, TestForced
cannot force a disaster onto a non-disastrous level. It only works on levels that normally have disasters: *-3 (or *-2 with Quick Game on), or every level with the Disasters Every Level mutator.
Disaster Settings
Normally, you can't teleport during disasters, but you can change that by overriding the AllowTeleport
property:
public class MyCustomDisaster : CustomDisaster
{
public override bool AllowTeleport => true;
}
The property is accessed constantly, so you can change the return value with time.
Initialization
Just call the CreateCustomDisaster
method with your disaster's type as a parameter:
public class MyCustomDisaster : CustomDisaster
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomDisaster<MyCustomDisaster>();
}
}
See more about the RLSetup
attribute here.
You can set your disaster's name and description using WithName
and WithDescription
methods:
public class MyCustomDisaster : CustomDisaster
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomDisaster<MyCustomDisaster>()
.WithName(new CustomNameInfo("My Custom Disaster"))
.WithDescription(new CustomNameInfo("My Custom Disaster is very cool and does a lot of great stuff"));
}
}
Plus, you can add two messages (they are displayed at the same time, on two lines):
public class MyCustomDisaster : CustomDisaster
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomDisaster<MyCustomDisaster>()
.WithName(new CustomNameInfo("My Custom Disaster"))
.WithDescription(new CustomNameInfo("My Custom Disaster is very cool and does a lot of great stuff"))
.WithMessage(new CustomNameInfo("My Custom Disaster!"))
.WithMessage(new CustomNameInfo("Watch out for... uh, something dangerous!"));
}
}
See Custom Names for more info.
You can also create a removal mutator automatically:
public class MyCustomDisaster : CustomDisaster
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomDisaster<MyCustomDisaster>()
.WithName(new CustomNameInfo("My Custom Disaster"))
.WithDescription(new CustomNameInfo("My Custom Disaster is very cool and does a lot of great stuff"))
.WithMessage(new CustomNameInfo("My Custom Disaster!"))
.WithMessage(new CustomNameInfo("Watch out for... uh, something dangerous!"))
.WithRemovalMutator();
}
}
Examples
- New Health Order
A simple disaster that just gives everyone Resurrection after the notification.
using System.Collections;
namespace RogueLibsCore.Test
{
public class NewHealthOrder : CustomDisaster
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomDisaster<NewHealthOrder>()
.WithName(new CustomNameInfo
{
English = "New Health Order",
})
.WithDescription(new CustomNameInfo
{
English = "Where is this line used?!",
})
.WithMessage(new CustomNameInfo
{
English = "N.H.O. - New Health Order",
})
.WithMessage(new CustomNameInfo
{
English = "Resurrection for everyone!",
})
.WithRemovalMutator();
}
public override void Start() { }
public override void Finish() { }
public override IEnumerator Updating()
{
foreach (Agent agent in gc.agentList)
if (!agent.dead && !agent.electronic && !agent.inhuman)
{
agent.statusEffects.AddStatusEffect(VanillaEffects.Resurrection, false);
}
yield break;
}
}
}