Class Based Modification (CBM) is the community’s longest running and most notable class mod, introducing a class for just about every mainline robot master in the Mega Man series. It’s been in the works for over 10 years and has been passed between multiple groups of developers over time, making it one of the most varied modded experiences.
<aside> ⚠️ **Warning: This tutorial details extra steps that should be taken when creating a class for compatibility with CBM. It goes without saying that you should already have experience with creating classes for MM8BDM V6B itself.
It is also useful to go ahead and look at the tips for custom weapons with CBM!**
</aside>
With the release of MM8BDM V6B, as with a lot of other newer mods, CBM is now largely compatible with content expansions such as additional classes. Using CBM’s CBMADD.acs
ACS library, which can be found inside of its file at acs_source/cbm_dt/CBMADD.acs
, you’ll be able to follow along with this page and implement a class which is compatible with standalone MM8BDM, CBM, and even potentially the forks of CBM to come.
The class that we’ll be making as an example is Megaman X as a copy weapon class. For that reason, we’ll be using ClassBase
as our class’s inherited actor and BaseMM8BDMWep
as our weapons’ inherited actor. However, all the same rules as standalone MM8BDM classes apply when extending the compatibility to CBM.
CBM is one of the community’s mods which has “beefed up” damage and HP values, meaning that it multiplies every original damage and HP value by 10. While in base MM8BDM, the default HP range is 100 and the Mega Buster deals 10 damage, in CBM, the default HP range is 1000 and the Mega Buster deals 100 damage.
It does this to enable some steeper damage and defense multipliers which would be unviable or cause unintended consequences in the standard range of values due to limitations of the Zandronum engine.
For your class, this means that you’ll need a mechanism to have normal HP and do normal damage, except when CBM’s “beefed up” values are loaded, in which case you should multiply the class’s HP and their damage by 10. We’ll discuss how to handle the HP in the next section, but for the damage, CBMADD.acs
provides a helper function to help us create that mechanism. You should create a script that looks like below for your own class(es).
#library "XACS"
#include "zcommon.acs"
#include "CBMADD.acs"
script "MMX_CBM_Damage" (int dmg) {
if(CBMBeefInPlay()) { // Checks for beefed up values
dmg *= 10;
}
SetResultValue(dmg);
}
This script is fairly simple in concept, it takes in a damage value and returns back a damage value using SetResultValue
. If CBM’s beefed up values are loaded, it’ll return the damage given but multiplied by 10. We’ll use this script in our class’s DECORATE like below.
actor X_Shot1 : BasicProjectile
{
damagetype "Buster"
Obituary "$OB_XBUSTER"
+BRIGHT
Damage (CallACS("MMX_CBM_Damage", 10))
radius 10
height 5
Speed 35
States
{
Spawn:
TNT1 A 2
BUST A 1
wait
}
}
actor X_Shot2 : X_Shot1
{
Damage (CallACS("MMX_CBM_Damage", 15))
radius 15
height 5
Speed 40
States
{
Spawn:
TNT1 A 2
X1AB JKLMN 2
Goto Spawn+1
}
}
actor X_Shot3 : X_Shot2
{
Damage (CallACS("MMX_CBM_Damage", 35))
radius 18
height 25
speed 40
States
{
Spawn:
TNT1 A 0
TNT1 A 1
X1AB ABC 2
goto Spawn+2
}
}
Notably, every instance where a damage value is defined, we’ve substituted it with CallACS
using our new script. If you’re experienced with regex and use a more advanced code editor (such as VSCode), you can use the below regex to find all common instances of where damage values would be specified.
(a_explode\\s*\\()|(damage((\\s*\\()|(thing)))|(core_((propexplode)|(teamexplode)|(damageowner)|(damageactor)))
In addition to dealing with the class’s starting HP, we’ve also got their starting inventory to resolve. If you recall, a class made for standalone MM8BDM should always have BaseFlagPack
as a starting item. CBM has its own variant of this inventory named CBM_BaseFlagPack
which adds additional behavior in addition to giving BaseFlagPack
. Additionally, CBM has its copy weapon nerf actors which need to be given if you’re designing a class intended to use copy weapons.
This means for best practices, we’ll need to be able to give BaseFlagPack
in standalone MM8BDM but CBM_BaseFlagPack
and potentially copy weapon nerf actors whenever CBM is loaded. To accomplish this as well as the issue of starting HP. We’ll do the following:
actor MegamanXC : ClassBase
{
Player.ScoreIcon "XMUGSHT1"
player.displayname "MegamanX"
player.soundclass "megamanx"
player.maxhealth 1000
health 1000
player.jumpz 10
player.forwardmove 0.8, 0.8
player.sidemove 0.78, 0.78
player.startitem "X_StartingInventory"
...
}
actor X_StartingInventory : CustomInventory
{
States
{
Pickup:
TNT1 A 0 ACS_NamedExecuteWithResult("MMX_StartingInventory", true)
stop
}
}
We’ll first pretend that CBM is always loaded and give our class their intended HP value but multiplied by 10. Instead of giving BaseFlagPack
or CBM_BaseFlagPack
, we’ll actually give our own defined actor which calls an ACS script. The ACS script is defined below.
#library "XACS2"
#include "zcommon.acs"
#include "CBMADD.acs"
script "MMX_StartingInventory" (int copynerf) {
if(!CBMBeefInPlay()) {
SetActorProperty(0, APROP_Health, GetActorProperty(0, APROP_Health) / 10);
SetActorProperty(0, APROP_SpawnHealth, GetActorProperty(0, APROP_SpawnHealth) / 10);
}
if(CBMInPlay()) {
GiveInventory("CBM_BaseFlagPack", 1);
if(copynerf) {
GiveInventory("CopyNerfGiver_P", 1);
}
} else {
GiveInventory("BaseFlagPack", 1);
}
}