MARS Combat Statistics
From Multiverse
| MARS |
| Mob Server |
| Object Manager |
| Combat Server |
|
Abilities and Combat Plugin • Combat Statistics • Extending the MARS Combat System • Group System • Trainer Plug-in • Professions • Experience System |
| Tutorials |
| Other Examples |
|
Triggering an Action with a Mouseclick • Scheduled Execution • Working with Sound • Creating a Teleporter |
Contents |
Overview
MARS combat statistics ("stats") are numerical values that describe the properties of a mob or PC. Stat values may depend on other stats and may have temporary modifiers added to them. The script multiverse/config/sampleworld/combat.py defines stats for Sampleworld; for your world, use multiverse/config/worldname/combat.py.
Each stat must have a definition object (derived from multiverse.mars.objects.MarsStatDef) registered with the CombatPlugin to define the behavior of that stat. Base stats simply register a MarsStatDef, while calculated stats must define a new class that extends MarsStatDef with the code specific to that stat.
multiverse.mars.objects.MarsStat objects contain the minimum, maximum, base value and current value (after modifiers) of a stat. Each mob and template has a MarsStat for each stat.
Templates for mobs must include a MarsStat object to specify the starting value for each base stat.
Defining combat stats
To define a combat stat:
- Define a Python class that:
- Subclasses
multiverse.mars.objects.MarsStatDefobject. This object defines how the value of that stat is calculated, and provides a mechanism for triggering actions when certain condition flags for the stat are triggered. - Overrides the
update()method - If your combat stat needs to trigger events when it changes, also override the
notifyFlags()method
- Subclasses
- Register your stat object by calling
CombatPlugin.registerStat()with your class.
registerStat
CombatPlugin.registerStat(MarsStatDef stat) CombatPlugin.registerStat(MarsStatDef stat, String... dependencies)
Registers the stat (and its dependencies, if present) with the combat plugin.
Returns
None
Parameters
| Parameter | Datatype | Description |
|---|---|---|
| stat | MarsStatDef | The stat to be registered. |
| dependencies | varargs list of String (array of String in python) | A list of the names of the stats that this stat depends on. |
Examples
Stamina is a base stat that. It behaves as a simple value that has no extra behavior associated with it. It can have its base value modified or a temporary modifier added to it (by an ability, for example).
CombatPlugin.registerStat(MarsStatDef("stamina"))
Health-max is a stat dependent on stamina. As you'll see below, health-max has a mathematical relationship with stamina.
CombatPlugin.registerStat(HealthMaxStat("health-max"), [ "stamina" ])
Health is a stat dependent on health-max, but it's a bit more complicated, as you'll see in later examples.
CombatPlugin.registerStat(HealthStat("health"), [ "health-max" ])
Accuracy is slightly more complex calculated stat. It's dependent on multiple other stats.
CombatPlugin.registerStat(AccuracyStat("accuracy"), [ "offense skill", "strength", "agility" ])
MarsStatDef
Defines how a statistic's value is calculated and any actions it may trigger. This class should be subclassed for any stat that needs to define specific behavior. This will generally include any stat that is dependent on some other stat's value, or any stat that must trigger actions based on its own value.
MarsStatDef is stateless and should include only the logic for how a stat behaves. The actual stat values for a particular mob are stored in properties on the combat subobject (multiverse.mars.objects.CombatInfo) as multiverse.mars.objects.MarsStat objects.
Constructor
MarsStatDef(String name)
Constructs a new MarsStatDef object for the stat name.
update()
public void update(MarsStat stat, CombatInfo info)
Recalculate the value of an instance of this stat. Override this method in a subclass to define how the value of the stat is calculated. Always call MarsStatDef.update() at the end of this method to propagate updates to dependent stats and recalculate condition flags.
This method is called by the combat plugin whenever any stat changes.
Returns
None
Parameters
| Parameter | Datatype | Description |
|---|---|---|
| stat | MarsStat | The stat instance being updated. |
| info | CombatInfo | The combat subobject that owns the stat instance being updated. |
Examples
This is the logic for the health-max stat. As you can see, the base value of health-max is calculated as 10 * stamina. If there are any modifiers applied to the stat, they will be added to the current value when it's updated. The call to setDirty() indicates that the value of the stat has been modified and should be propgated to other stats that depend on it. Finally, MarsStatDef.update() is called to propagate changes and update condition flags.
class HealthMaxStat (MarsStatDef):
def update(self, stat, info):
stam = info.statGetCurrentValue("stamina")
stat.base = stam * 10
stat.setDirty(True);
MarsStatDef.update(self, stat, info)
This is the definition for the health stat. It's a little different in that it has a max value which is set to the value of the health-max stat and a min value which is set to zero. This affects the legal range of the base and current values for the stat as well as how condition flags are set for the stat. Any change to health-max will result in a change to the legal range for the health.
class HealthStat (MarsStatDef):
def update(self, stat, info):
healthMax = info.statGetCurrentValue("health-max")
stat.max = healthMax
stat.min = 0
if(info.dead()):
stat.base = 0
stat.setDirty(True);
MarsStatDef.update(self, stat, info)
notifyFlags()
public void notifyFlags(MarsStat stat, CombatInfo info, int oldFlags, int newFlags)
This method is called when the flags for a stat change. It can be used to trigger actions such as regeneration or death.
Returns
None
Parameters
| Parameter | Datatype | Description |
|---|---|---|
| stat | MarsStat | The stat instance that this notification is about. |
| info | CombatInfo | The combat subobject that is associated with the stat instance. |
| oldFlags | int | The old value of the condition flags for the stat instance. |
| newFlags | int | The new value of the condition flags for the stat instance. |
Flags
Valid flags are listed below. These are bit fields.
| flag | value | description |
|---|---|---|
| MarsStatDef.MARS_STAT_FLAG_MIN | 1 | The current value of the stat is at the min value. |
| MarsStatDef.MARS_STAT_FLAG_MAX | 2 | The current value of the stat is at the max value. |
Examples
This is the notifyFlags() implementation for the health stat. The most important thing to notice here is how regeneration is handled for this stat. Whenever the stat drops from its max value, regeneration is started and when it returns to its max value, regeneration is stopped. Similarly, when the stat reaches its min value, the mob is dead and there is logic to handle that case as well.
def notifyFlags(self, stat, info, oldFlags, newFlags):
if (info.dead()):
CombatPlugin.stopRegen(info, stat.getName())
return
if ((oldFlags ^ newFlags) & MarsStatDef.MARS_STAT_FLAG_MAX):
if (newFlags & MarsStatDef.MARS_STAT_FLAG_MAX):
CombatPlugin.stopRegen(info, stat.getName())
else:
regenEffect = Mars.EffectManager.get("health regen effect")
CombatPlugin.startRegen(info, stat.getName(), regenEffect)
if (((oldFlags ^ newFlags) & MarsStatDef.MARS_STAT_FLAG_MIN)
and (newFlags & MarsStatDef.MARS_STAT_FLAG_MIN)):
CombatPlugin.stopRegen(info, stat.getName())
info.setDeadState(True)
WorldManagerClient.setObjectProperty(info.getOwnerOid(),
WorldManagerClient.WORLD_PROP_NOMOVE, Boolean(True))
WorldManagerClient.setObjectProperty(info.getOwnerOid(),
WorldManagerClient.WORLD_PROP_NOTURN, Boolean(True))
if (info.isMob()):
WorldManagerClient.setObjectProperty(info.getOwnerOid(),
"lootable", Boolean(True))
Object Creation
When a combat subobject (multiverse.mars.objects.CombatInfo) is created, all of the MarsStats from the template are copied to the subobject. Also, a new MarsStat is created for any derived statistics that do not have an entry in the template. This allows you to create templates that only specify the base statistics for your combat system.
MarsStat
A multiverse.mars.objects.MarsStat object represents the current state of a combat statistic for a particular object. MarsStats support base, min and max values for the stat, as well as temporary modifiers to generate a current value for the statistic.
Constructor
MarsStat(String statName) MarsStat(String statName, int value)
Creates a new MarsStat for statName with initial base value of value.
Members
| member | description |
|---|---|
| base | The base value of the statistics, before modifiers are applied. |
| min | The minimum possible value for the statistic. Current and base values are clipped to this min value. |
| max | The maximum possible value for the statistic. Current and base values are clipped to this max value. |
| current | The current value of the statistic, after modifiers are applied. |
