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 weapon for compatibility with CBM. It goes without saying that you should already have experience with creating weapons for MM8BDM V6B itself.
</aside>
With the release of MM8BDM V6B, as with a lot of other newer mods, CBM is now fully compatible with select weapons and content expansions. 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 the two major mechanics that allow compatibility.
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 weapons, this means that you’ll need a mechanism to do normal damage, except when CBM’s “beefed up” values are loaded, in which case you should multiply that damage by 10. CBMADD.acs
provides a helper function to help us create that mechanism. You should create a script that looks like below for your own weapon pack.
#library "SPRKCBM"
#include "zcommon.acs"
#include "CBMADD.acs"
script "sparkscatter_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. Using Spark Scatter’s DECORATE as an example, this script can be used like below.
actor SparkScatterLob : BasicProjectile
{
-NOGRAVITY
+FORCEXYBILLBOARD
+BRIGHT
Radius 6
Height 6
damage (CallACS("sparkscatter_cbm_damage", 1))
speed 45
gravity 1.8
translation "225:225=229:299"
damagetype "SparkScatter"
Obituary "$OB_SPARKSCATTER"
States
{
Spawn:
SPAS AB 4
loop
Death:
SPAS A 0 A_SpawnItemEx("SparkScatterExplode")
stop
}
}
actor SparkScatterExplode : BasicExplosion
{
scale 3.6
translation "225:225=229:299"
damagetype "SparkScatter"
Obituary "$OB_SPARKSCATTER"
States
{
Spawn:
TNT1 A 0
TNT1 A 0 A_SpawnItemEX("ElectrifyEffect")
TNT1 A 0 A_Explode(CallACS("sparkscatter_cbm_damage", 15), 80, 0, 0, 80)
SPAS AHIJ 1
stop
}
}
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)))
CBM has a few classes which have special mechanics surrounding copy weapons. Universally (barring Maestro), copy weapon classes receive a “copy nerf.” This is a damage debuff which nerfs the damage of their copy weapons to 0.777x as a general baseline. We’ll want to define this debuff for our weapon(s) and use a similar range to keep the damage feeling right for those classes.
Rock doesn’t use copy weapons himself, but he has a mechanic where he can pick them up to receive a corresponding Mega Man 1 inspired variant of Mega Ball. Doc Robot has a special mechanic where while using a weapon, his base, passive stats change to match the robot master which the weapon belongs to. Last but not least, Evil Robot has a mechanic where each copy weapon is associated to one of his Giga Attacks from his Chapter 8 boss battle.
We’ll again use some functions from CBMADD.acs
to set all of these mechanics up.
#library "SPRKCBM2"
#include "zcommon.acs"
#include "CBMADD.acs"
script "sparkscatter_cbm_defines" OPEN {
if (CBMInPlay()) { // Checks that CBM is loaded at all
// Your weapon pack should only use ONE CopyNerf actor
// You can put the damage debuffs for all your weapons into it!
AddCopyNerf("SparkScatter_CopyNerf");
// You will need one of these lines for EACH weapon.
AddCBMWepInfoEX("SparkScatterWep", CBMADD_ELEC, 750, 115, 115, CBMADD_GTC);
}
}
The first CBMADD.acs
function which we use here is CBMInPlay
. Similar to CBMBeefInPlay
, this just checks if CBM is loaded at all.
<aside>
🚨 You should always use CBMInPlay
to determine whether or not to call these functions, they’ll throw errors on OPEN
if you call them when CBM isn’t loaded!
</aside>