-
Notifications
You must be signed in to change notification settings - Fork 1
1: Creating modded game objects
You can create modded game objects (such as items and enemies) using Create methods from the Mod class.
These methods return an Entry that allows you to configure the modded object's properties.
Some creation methods take a string parameter that represents the Mod ID of that object. The Mod ID must be unique between objects of the same type and created by the same mod!
It is important that you configure your items before exiting Mod.Load(). Changing the entries after your mod loads is now allowed, and will cause an exception.
AudioEntry audio = CreateAudio();
audio.AddMusic("TestMod", "Intro", "Clash", "DeafSilence");
audio.AddMusic("TestModStuff", "Ripped", "Destiny");You can create at most one audio entry per mod.
GrindScript uses preset wave bank and sound bank names to load audio data. Depending on what you do, you will need the following wave banks in the "Sound" folder:
- {Mod.NameID}Effects.xwb - The wave bank used for effects
- {Mod.NameID}Effects.xsb - The sound bank used for effects
- {Mod.NameID}.xwb - The universal music wave bank. These stay loaded until you exit the game, or reload your mods
- {Mod.NameID}Music.xsb - The sound bank used for music
- Region wave banks - each represents a distinct region of the game, and are loaded / unloaded as needed.
In the list above, {Mod.NameID} is the NameID property of your mod class.
CommandEntry commands = CreateCommands();
commands.SetCommand("HelloWorld", (args, connection) =>
{
if (args.Length >= 2 && args[0] == "TheFirstParam" && args[1] == "SecondAndSoOn")
{
CAS.AddChatMessage("Hello World from GrindScript!");
}
});You can create at most one command entry per mod.
CurseEntry curse01 = CreateCurse("MyUniqueCurseIDHere");
curse01.Name = "Spooky Curse";
curse01.Description = "Very cursed stuff!";
curse01.IsCurse = true;
curse01.ScoreModifier = 0.4f;
curse01.TexturePath = this.AssetPath + "RogueLike/SpookyCurseIcon.xnb";Treats and Curses are the same thing internally, the only difference is the shop that they appear in.
EnemyEntry enemy = CreateEnemy("MyUniqueEnemyIDHere");
enemy.Name = "Modded Slime";
enemy.BaseHealth = 1600;
enemy.Constructor = ModSlimeAI.InstanceBuilder; // Instantiates the slime
enemy.DifficultyScaler = ModSlimeAI.DifficultyScaler; // Scales its stats based on difficulty
enemy.EliteScaler = null; // If not null, the slime can be elite; the method scales the stats
enemy.Category = EnemyDescription.Category.Regular;
enemy.CardDropChance = 75.0f; // 75%
enemy.CardInfo = "Boosts your bamboozling by 420%";
enemy.LootTable.Add(new EnemyEntry.Drop(100f, ItemCodex.ItemTypes._Misc_GiftBox_Consumable));
enemy.LootTable.Add(new EnemyEntry.Drop(75f, ItemCodex.ItemTypes._Misc_GiftBox_Consumable));
enemy.LootTable.Add(new EnemyEntry.Drop(50f, ItemCodex.ItemTypes._Misc_GiftBox_Consumable));
enemy.LootTable.Add(new EnemyEntry.Drop(25f, ItemCodex.ItemTypes._Misc_GiftBox_Consumable));
// Do animation setup, etc.Coming SoonTM.
ItemEntry item = CreateItem("MyUniqueItemIDHere");
item.Name = "Shield Example";
item.Description = "This is a custom shield!";
item.EquipType = EquipmentType.Shield;
item.IconPath = this.AssetPath + "Items/ModShield/Icon";
item.EquipResourcePath = this.AssetPath + "Items/ModShield";
item.ShldHP = 250;Coming SoonTM.
NetworkEntry network = CreateNetwork();
// Process packets of ID 0 on client
network.SetClientSideParser(0, (BinaryReader x) =>
{
string message = x.ReadString();
CAS.AddChatMessage("Mod Message from Server: " + message);
});
// Process packets of ID 0 on server
network.SetServerSideParser(0, (BinaryReader x, long connectionID) =>
{
PlayerView view = Globals.Game.dixPlayers[connectionID];
string message = x.ReadString();
CAS.AddChatMessage($"Mod Message from Client {view.sNetworkNickname}: " + message);
});You can create at most one network entry per mod.
The packet IDs are separate for each mod. You can choose any IDs that you want in the range 0-65535.
PerkEntry perk01 = CreatePerk("MyUniquePerkIDHere");
perk01.Name = "Soul Booster";
perk01.Description = "Gain 10 extra EP.";
perk01.EssenceCost = 15;
perk01.RunStartActivator = (player) =>
{
player.xEntity.xBaseStats.iMaxEP += 10;
player.xEntity.xBaseStats._ichkBaseMaxEP += 10 * 2;
};
perk01.TexturePath = this.AssetPath + "RogueLike/SoulBooster";PinEntry pin;
pin = CreatePin("MYUniquePinIDHere");
pin.Description = "Gain 150 bonus Shield HP with all shields.";
pin.PinSymbol = PinEntry.Symbol.Shield;
pin.PinShape = PinEntry.Shape.Circle;
pin.PinColor = PinEntry.Color.BilobaFlower;
pin.EquipAction = (PlayerView view) =>
{
view.xEntity.xBaseStats.iShieldMaxHP += 150;
};
pin.UnequipAction = (PlayerView view) =>
{
view.xEntity.xBaseStats.iShieldMaxHP -= 150;
};Coming SoonTM.
Coming SoonTM.
StatusEffectEntry status01, status02, status03;
status01 = CreateStatusEffect("DrainDebuff_ASPD");
status02 = CreateStatusEffect("DrainDebuff_CSPD");
status03 = CreateStatusEffect("DrainDebuff_EPReg");Coming SoonTM.