25
edits
(adding skeletal example with comments (Thank you Gnarf!)) |
|||
(8 intermediate revisions by 2 users not shown) | |||
Line 7: | Line 7: | ||
<mutations> | <mutations> | ||
<category Name="[CATEGORY]"> | <category Name="[CATEGORY]"> | ||
<mutation Name="[NAME]" Cost="[NUMBER]" MaxSelected="[NUMBER]" Class="[ | <mutation Name="[NAME]" Cost="[NUMBER]" MaxSelected="[NUMBER]" Class="[CS CLASS]" Tile="Mutations/YOUR_IMAGE_HERE" Foreground="COLOR" Background="COLOR" </mutation> | ||
</category> | </category> | ||
</mutations> | </mutations> | ||
Line 39: | Line 39: | ||
The tile you will be using for said mutation in-game. | The tile you will be using for said mutation in-game. | ||
By default most mutations use gold/yellow for | By default most mutations use gold/yellow for background and brown for foreground but this can be customized for any color of your choice, see [[Modding:Tiles]] and [[Modding:Colors_%26_Object_Rendering]] for further info on this. | ||
=== Exclusions === | === Exclusions === | ||
Line 71: | Line 46: | ||
=== BearerDescription === | === BearerDescription === | ||
It appears that this description is used in some of the random generation algorithms for villages and history in the game. For example, if a village reveres mutants with the Multiple Arms mutation, they might use the string defined in Mutations.xml ("the many-armed") to describe them in their praises or monuments. | It appears that this description is used in some of the random generation algorithms for villages and history in the game. For example, if a village reveres mutants with the Multiple Arms mutation, they might use the string defined in Mutations.xml ("the many-armed") to describe them in their praises or monuments. | ||
=== Constructor === | |||
This is used by very few mutations, and its use case is as a string argument (or a comma-delimited string of arguments, if there are more than one) to pass to the mutation's class constructor. All such arguments are received as string parameters in the mutation class constructor. | |||
It should be noted that this parameter is both advance and old, and it shouldn't be necessary and potentially avoided. | |||
== C# Scripting, and Making The Mutation == | == C# Scripting, and Making The Mutation == | ||
Here is an example of a mutation that will add udders to your character, | Here is an example of a mutation that will add udders to your character, which will edit the title of your character to add udders, and make you moo occasionally. | ||
<syntaxhighlight lang="csharp"> | <syntaxhighlight lang="csharp"> | ||
using System; | using System; | ||
Line 90: | Line 71: | ||
[Serializable] | [Serializable] | ||
// This defines the class that you will call in Mutations.XML | // This defines the class that you will call in Mutations.XML | ||
class | class QudWiki_Udders : BaseMutation | ||
{ | { | ||
Line 99: | Line 80: | ||
} | } | ||
// This sets the description for what exactly your mutation does | // This sets the description for what exactly your mutation does. | ||
// It is good idea to make helper functions like the "ChanceToMoo" to make dynamic descriptions for changing rules for a mutation. | |||
public override string GetLevelText(int Level) | public override string GetLevelText(int Level) | ||
{ | { | ||
return " | return "{{rules|You have a " + ChanceToMoo(Level) + "% chance to moo per turn}}"; | ||
} | |||
public int ChanceToMoo(int Level) | |||
{ | |||
return Level; | |||
} | |||
// This is called every time the mutation changes level, and can be used to change things like damage. | |||
// We don't use "ChanceToMoo" in this example so we can allow GetLevelText to use it. | |||
public override bool ChangeLevel(int NewLevel) | |||
{ | |||
return true; | |||
} | |||
// These two are called upon when an object gains said mutation and what happens, and is used to add or remove things as necessary | |||
public override bool Mutate(GameObject MUTANT, int Level) | |||
{ | |||
return base.Mutate(MUTANT, Level); | |||
} | |||
public override bool Unmutate(GameObject MUTANT) | |||
{ | |||
return Base.Unmutate(MUTANT); | |||
} | } | ||
Line 144: | Line 149: | ||
if (E.ID == "EndTurn") | if (E.ID == "EndTurn") | ||
{ | { | ||
// | // Reusing the same method we used in GetLevelText means that both of them will remain accurate. | ||
if ( | if (ChanceToMoo(Level).in100()) DidX("moo"); | ||
} | } | ||
return base.FireEvent(E); | return base.FireEvent(E); | ||
} | } | ||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Bigger Example == | |||
TODO: Re-work the huge file of flaminghands.cs to be have comments and explain it , possibly with Gnarf's help if they are okay/free to do so | TODO: Re-work the huge file of flaminghands.cs to be have comments and explain it , possibly with Gnarf's help if they are okay/free to do so | ||
Line 182: | Line 173: | ||
{ | { | ||
/// <summary> | |||
/// FlamingHands powers the "Flaming Ray" mutation. You can now choose a variant from hands, feet or face. | |||
/// </summary> | |||
[Serializable] | [Serializable] | ||
public class FlamingHands : BaseDefaultEquipmentMutation | public class FlamingHands : BaseDefaultEquipmentMutation | ||
{ | { | ||
public FlamingHands() | |||
{ | |||
DisplayName = "Flaming Ray"; | |||
} | |||
/// <summary>The <see cref="BodyPart.Type" /> we replace (chosen by variant selection.)</summary> | |||
public string BodyPartType = "Hands"; | public string BodyPartType = "Hands"; | ||
/// <summary>Do we still need to create the object? Setup as a public for serialization purposes.</summary> | |||
public bool CreateObject = true; | public bool CreateObject = true; | ||
/// <summary>Sound file to play when attacking.</summary> | |||
public string Sound = "Abilities/sfx_ability_mutation_flamingRay_attack"; | public string Sound = "Abilities/sfx_ability_mutation_flamingRay_attack"; | ||
[NonSerialized] private static GameObject _Projectile; | |||
/// <summary>Create or retrive the already created Projectile game object.</summary> | |||
private static GameObject Projectile | private static GameObject Projectile | ||
{ | { | ||
Line 204: | Line 205: | ||
} | } | ||
} | } | ||
/// <summary>We are request to be re-mutated automatically when our body is rebuilt. Thanks slog.</summary> | |||
public override bool GeneratesEquipment() | public override bool GeneratesEquipment() | ||
{ | { | ||
return true; | return true; | ||
} | } | ||
Line 223: | Line 219: | ||
} | } | ||
/// <summary>Show selected variant in character creation.</summary> | |||
public override string GetCreateCharacterDisplayName() | public override string GetCreateCharacterDisplayName() | ||
{ | { | ||
Line 241: | Line 238: | ||
} | } | ||
public override string GetLevelText(int | public override string GetLevelText(int level) | ||
{ | { | ||
string Ret = "Emits a 9-square ray of flame in the direction of your choice.\n"; | string Ret = "Emits a 9-square ray of flame in the direction of your choice.\n"; | ||
Ret += "Damage: {{rules|" + ComputeDamage( | Ret += "Damage: {{rules|" + ComputeDamage(level) + "}}\n"; | ||
Ret += "Cooldown: 10 rounds\n"; | Ret += "Cooldown: 10 rounds\n"; | ||
Ret += "Melee attacks heat opponents by {{rules|" + GetHeatOnHitAmount( | Ret += "Melee attacks heat opponents by {{rules|" + GetHeatOnHitAmount(level) + "}} degrees"; | ||
return Ret; | return Ret; | ||
} | } | ||
public string GetHeatOnHitAmount(int | public string GetHeatOnHitAmount(int level) | ||
{ | { | ||
return ( | return (level * 2) + "d8"; | ||
} | } | ||
public string ComputeDamage(int | public string ComputeDamage(int level) | ||
{ | { | ||
string Result = | string Result = level + "d4"; | ||
if (ParentObject != null) | if (ParentObject != null) | ||
{ | { | ||
Line 273: | Line 270: | ||
} | } | ||
public string ComputeDamage() | public string ComputeDamage() => ComputeDamage(Level); | ||
public void Flame(Cell C, ScreenBuffer Buffer, bool doEffect = true) | public void Flame(Cell C, ScreenBuffer Buffer, bool doEffect = true) | ||
Line 363: | Line 357: | ||
} | } | ||
} | } | ||
mutation.CooldownMyActivatedAbility(mutation. | mutation.CooldownMyActivatedAbility(mutation.ActivatedAbilityID, Turns: 10); | ||
mutation.UseEnergy(1000, "Physical Mutation Flaming Hands"); | mutation.UseEnergy(1000, "Physical Mutation Flaming Hands"); | ||
mutation.PlayWorldSound(mutation.Sound, combat: true); | mutation.PlayWorldSound(mutation.Sound, combat: true); | ||
Line 386: | Line 380: | ||
{ | { | ||
if( !CreateObject) return true; | if( !CreateObject) return true; | ||
return HasRegisteredSlot(BodyPartType) && GetRegisteredSlot(BodyPartType,false) != null; | return HasRegisteredSlot(BodyPartType) && GetRegisteredSlot(BodyPartType, false) != null; | ||
} | } | ||
Line 416: | Line 410: | ||
CheckObjectProperlyEquipped() | CheckObjectProperlyEquipped() | ||
&& E.GetIntParameter("Distance") <= 9 | && E.GetIntParameter("Distance") <= 9 | ||
&& IsMyActivatedAbilityAIUsable( | && IsMyActivatedAbilityAIUsable(ActivatedAbilityID) | ||
&& ParentObject.HasLOSTo(E.GetGameObjectParameter("Target"), UseTargetability: true) | && ParentObject.HasLOSTo(E.GetGameObjectParameter("Target"), UseTargetability: true) | ||
) | ) | ||
Line 440: | Line 434: | ||
} | } | ||
return base.FireEvent(E); | return base.FireEvent(E); | ||
} | } | ||
private void AddAbility() | private void AddAbility() | ||
{ | { | ||
ActivatedAbilityID = AddMyActivatedAbility( | |||
Name: "Flaming Ray", | Name: "Flaming Ray", | ||
Command: "CommandFlamingHands", | Command: "CommandFlamingHands", | ||
Class: "Physical Mutation", | Class: "Physical Mutation", | ||
Icon: "" + (char) 168 | Icon: "" + (char) 168, | ||
Description: GetLevelText(Level) | |||
); | ); | ||
} | |||
public override bool ChangeLevel(int NewLevel) | |||
{ | |||
var result = base.ChangeLevel(NewLevel); | |||
// Update the ability description | |||
if (MyActivatedAbility(ActivatedAbilityID) is ActivatedAbilityEntry ability) ability.Description = GetLevelText(Level); | |||
return result; | |||
} | } | ||
Line 463: | Line 461: | ||
return variants; | return variants; | ||
} | } | ||
public override void SetVariant(int n) | public override void SetVariant(int n) | ||
Line 476: | Line 473: | ||
} | } | ||
base.SetVariant(n); | base.SetVariant(n); | ||
} | } | ||
Line 552: | Line 544: | ||
public override bool Unmutate(GameObject GO) | public override bool Unmutate(GameObject GO) | ||
{ | { | ||
RemoveMyActivatedAbility(ref | RemoveMyActivatedAbility(ref ActivatedAbilityID); | ||
return base.Unmutate(GO); | return base.Unmutate(GO); | ||
} | } | ||
Line 559: | Line 551: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{Modding Navbox}} | {{Modding Navbox}} |