Skip to content

Instantly share code, notes, and snippets.

@ErichDonGubler
Created October 25, 2011 20:06
Show Gist options
  • Save ErichDonGubler/1314071 to your computer and use it in GitHub Desktop.
Save ErichDonGubler/1314071 to your computer and use it in GitHub Desktop.
0.9.6 wiki pages

0.9.6

  • Fixes

  • Changes

    • Values are now copied into the Calculation nests (this includes the [[Calculate routine|Routine: Calculate]]). This is so that damage can be used to potentially factor into, say explosion size. If you're used to using something like 'targeteffect.explode': '4', just change it to 'targeteffect.explode': 'set.4'.

    • The Range routines have been changed from value-setting to additive. The most simple solution to fix this is to use the Set routine, akin to the following snippet:

- 'set': 'range.13.18';
    • The [[Binom routine|Statement: Chance]] has been renamed to "Chance", for semantic reasons. Usage is exactly the same as before, like so:
- 'chance.30': 'set.0' # Has a 30% chance to set the value to 0.
    • For the sake of simplicity in future updates, basic status conditional routines have been changed back to $entity.is$status.
* "Item" aliases are now "Material" aliases. This is because of a new feature that will be introduced with the next major release. :)
  • New features:

    • Plugin integrations:

      • [[Regions|Conditional: Region]] - elRegions and WorldGuard compatible.

      • Permissions - added PermsEx, bPermissions, and SuperPerms support. Added the [[Permission Evaluation|Statement: Permission Evaluation]] conditional.

      • McMMO. New routines are as follows:

        • [[Ability activation conditionals|"Conditional: Ability Enabled (McMMO)]]

        • [[Set Skill calculation|Calculation: Set Skill (McMMO)]]

    • Miscellaneous new routines:

      • [[BlockOver|Conditional: Block Status]]

      • [[BlockUnder|Conditional: Block Status]]

      • [[Calculate|Routine: Calculate]]

      • [[UnknownHurt|Calculation: Unknown Hurt]]

      • [[Delay|Routine: Delay]]

    • Aliasing:

      • Region

      • Routine

    • Dynamic integer references! This brings several new features to the table, listed below. For a complete reference to valid integer properties, see this page

      • Deprecation of the hardcoded comparison routines in favor of a single one that uses the new integer references. Some examples:

        • target.health.lessthan.attacker.health

        • target.y.greaterthanequals.attacker.y

      • Now you can use these in Message routines! Simply encapsulate entity references or routine aliases in percentage signs to use this. For instance:

        • message.attacker.You did %event.value% damage!
    • Events:

      • Tame

      • ProjectileHit

    • Projectile entity reference (in addition to currently existing "attacker" and "target")

    • Message routines have had a massive upgrade! Now you can use dynamic variables, strings, and colors to greatly speed along debugging and perhaps even use for RPG-type messaging. See [[the Message routine|Routine: Message]] for more details.

    • Arithmetic expressions!

  • Indev features

    • Implemented an experimental tagging system. See the [[FAQ|FAQ: How do I use tagging?]] for more details.

0.9.5

Changes:

  • For what should be the last time, major syntax changes have occurred in MD. Gone now are the strange nodes - ModDamage is now entirely conditionally driven. The new configuration scheme is like follows:
Event:
    - SOME.ROUTINE
    - PERHAPS.A.CONDITIONAL:
        - SOME.ROUTINE
    - EVEN.A.SWITCH:
        FIRSTCASE:
        SECONDCASE:
        ANOTHERCASE:

These routines are run every time the relevant event is fired - conditional evaluations are now necessary for situational dynamics.

  • Modified $entity$op syntax in conditionals to be split with a period - syntax reference has been updated accordingly in the tuts and reference on the wiki

  • Renamed "MobHealth" to "Spawn".

Fixes:

  • Fixed events throwing NPEs when Permissions was not present. Oops.

  • Fixed EntitySetOnFireTicks routine not working.

  • Fixed EntityReflect (now renamed to EntityHurt) causing explosions, instead of hurting entities magically.

  • Changed EntityExposedToSky conditional to ignore more blocks. Current list:

    • Air

    • Torch

    • Ladder

    • Fire

    • Lever

    • Button

    • WallSign

    • Glass

  • Fixed ArmorSet comparisons to work as intended - I know there are some edge cases out there that suffered because of this. :(

  • Added an "empty" ArmorSet so it's possible to determine whether a player is wearing any piece of armor or not. This is literally the string "EMPTY", case-insensitive.

  • Removed the EntityTargetedByOther routine - this seemed a very limited-application routine.

  • Changed the Binom base routine to operate as a Conditional statement.

New features:

  • Overloaded the Set base routine to operate as a Calculation - this shouldn't break any old configs.

  • Added "switch" statements. Switch statements are the final step in effectively replacing the Offensive/Defensive paradigms and DET configuration with a more dynamic model that should be more intuitive and simple to use - see above and/or the wiki.

  • Drastically modified configuration reports ingame and on the console - characters are now counted for proper line output, and the entire configuration is essentially read back, including colored error/warning strings. Much more functional than the last config checking.

  • Tweaked Conditionals syntax - they can now use basic boolean operators, though operation is strictly linear. There are no plans for parenthetical encapsulation. See the new tutorial for more details!

  • Aliasing for the following:

    • Armor sets

    • Biomes

    • Entity types

    • Groups

    • Items

    • Message - see the Message routine for more details [[here|Routine: Message]].

    • Worlds

  • Added the following routines:

    • AddItem (Effect, aliasable)

    • DropItem (Effect, aliasable)

    • HasRangedElement (Conditional)

    • SetItem (Effect)

    • PlayerSleeping (Conditional)

    • PlayerSneaking (Conditional)

    • WorldEvaluation (Conditional, aliasable)

  • Added sub-elements for Spider: Spider_Jockey and Spider_Riderless.

  • Added Death and Food events. :D

  • Changed the Elements hierarchy to have a "Living" and "Nonliving" category - the former including mobs, animals, and humans, while the latter covers everything else.

The following were suggested by lucent (thanks!):

* *Added the "fishingrod" ranged damage element.*

* *Added states for certain mobs (Slime size, Wolf angry/wild/tame, Creeper normal/charged, Human NPC/Player) - refer to wiki for more information.*

* Added EntityX and EntityZ comparisons - for consistency, EntityAltitude has been renamed to "EntityY".

The following were suggested by TheSquishyDitto. Thanks!:

* *Added the "trap" generic MD element and "dispenser" as a child element.*

* Changed configuration so that single-property configuration works in those cases you don't want to use another line.
  • The following were suggested by Ranzear - much obliged!

    • Added the EntitySpawn Calculation.

0.9.4

  • Made several types of nested calculations, which include the following:

    • Conditionals! These offer powerful ways to evaluate damage situations and has enormous potential for a robust override of Minecraft damage mechanics. See the [[wiki|Home]] for more details, as there's simply too many to make mention here.

    • Effects - these do something that simple damage changing cannot. For instance, 'attackereffect.explode', or 'effect.reflect'. The reason these are nested is because there may be situations where person configuring may want something other than a static value for the effect input.

  • Fixed casing for item names - now you don't have to be anal about having everything capitalized for Bukkit, though personally I'd keep things that way so that it's easier to read your configuration.

  • Added "fist" and "other" nodes to the melee damage category - I'm still open to suggestion for classification here. :P

  • Implemented server-level globals - thanks to nsko for a great idea! It should be noted that this WILL break old configurations, in addition to the structural change made to the MobHealth node. The changes are small, but that's all it takes. Just move your world configurations from:

Offensive:
    world:
        someconfig:
            - 'some.config'
Defensive:
    world:
        someconfig:
            - 'some.config'
MobHealth:
    world:
        someconfig: 'some.config'
Scan:
    world:
        - 'SOME.CONFIG'

...to:

Offensive:
    worlds:
        world:
            someconfig:
                - 'some.config'
Defensive:
    worlds:
        world:
            someconfig:
                - 'some.config'
MobHealth:
    worlds:
        world:
            someconfig: 
                - 'some.config'   #TAKE NOTE OF THIS. MOBHEALTH CONFIGURATION HAS CHANGED.
Scan:
    worlds:
        world:
            - 'SOME.CONFIG'
  • Re-added the Permissions 2.x support, since I realize that 3.x can be a pain for some admins to deal with right now.

  • Modified some console output while loading so that it gives you more information.

  • Modified the "check" command so that it now displays configuration right off the top - use the last page(s) to check the load status of your worlds/groups!

0.9.3

  • Fixed addition and negativeHeal not working properly - thanks to Deolin for pointing this out!

  • Fixed nonliving entities throwing an NPE when they were damaged and passed to MD

  • Added chainmail to the armor generics list - thanks to embty for the suggestion!

  • Fixed some erroneous documentation for the armor set delimiter

  • Added some more "verbose" messages that should be more helpful when online support is not available

  • Cleaned up startup config output that can still be revealed with verbose debugging (default health/damage and negative healing)

  • Implemented the "check" command for the console - this will make "quiet" mode more viable

  • Added some Permissions checks that will send warnings to console if a player involved in a damage event hasn't been assigned to a group (instead of an ugly stacktrace)

  • Finished implementation of the "check" commands

  • Added the "enable" and "disable" commands

0.9.2

  • Fixed a nice fat NPE error getting thrown every time a mob spawned. Oops.

  • Finished the "/md reload" and the basic "/md check" commands

  • Documented the "/md debug" command.

  • Changed "range.#base.#range" to "range.#lower.#upper" - see config reference for more information. Thanks to Digi for his suggestion here!

0.9.1

  • Added an experimental noDamageTicks check that cancels the event if 40 ticks remain- not sure how this will affect other plugins yet.

  • Added armor sets (see wiki for more details)

  • Fixed PvP string fetching - PvP relationships should work now.

  • Changed "item" to be split into "ranged" and "melee" (this breaks configs that use "item"!), fixing the long-range exploit. However, long range still clashes when the target is struck, and the long-range item is still in hand, and a melee node is defined for it. This is because of a double-firing of the damage event that needs to be looked into.

  • Changed to Permissions 3.0. My only suggestion for adapting to this change is that the configuration be carefully considered if one plans on using multigroup.

0.9

  • Introduced ModDamage! Indev, though.

Aliases: Material: pickaxe: - WOOD_PICKAXE - STONE_PICKAXE - IRON_PICKAXE - GOLD_PICKAXE - DIAMOND_PICKAXE spade: - WOOD_SPADE - STONE_SPADE - IRON_SPADE - GOLD_SPADE - DIAMOND_SPADE hoe: - WOOD_HOE - STONE_HOE - IRON_HOE - GOLD_HOE - DIAMOND_HOE axe: - WOOD_AXE - STONE_AXE - IRON_AXE - GOLD_AXE - DIAMOND_AXE sword: - WOOD_SWORD - STONE_SWORD - IRON_SWORD - GOLD_SWORD - DIAMOND_SWORD Damage: - 'switch.attacker.type': #Begin major Offensive tree mob: #Let's make everything nastier with this first number. 2 is decent, 4-6 is pushing past 'hard mode'. - '2' - 'if Attacker.Y.lessthan.48': #Get deep, take extra damage - 'roll.2' - 'if Attacker.Y.lessthan.24': #Get deeper, take even more damage - 'roll.2' - 'if event.hasrangedelement': #This handles skeletons because I'm lazy. - '-1' - 'roll.4' NPC: - 'if Attacker.Y.lessthan.42': #Just in case HeroBrine shows up. - 'roll.2' - 'if Attacker.Y.lessthan.24': - 'roll.3' Player: #Flatten all damage, recant some portion of it per Tool or AIR (bare fist). - '-5' - 'if attacker.wielding.AIR': - '4' - 'roll.4' - 'if target.type.ZombiePigman': #Compensate blunt/slashing damage, etc - 'div.2' - '-2' - 'roll.2' - 'if target.type.Zombie and target.fireticks.lessthan.20': - 'div.2' - 'roll.2' - 'if target.type.Skeleton': - '1' - 'roll.2' - 'if attacker.wielding._sword': - '6' - 'roll.4' - 'if target.type.ZombiePigman': - '3' - 'roll.2' - 'if target.type.Zombie': - '3' - 'roll.2' - 'if target.fireticks.greaterthan.1': - '3' - 'if target.type.Skeleton': - 'div.2' - '-6' - 'roll.2' - 'if attacker.wielding._axe': #Let's make these useful since mcMMO has some neat axe effects and a melee skill that never gets used. - '8' - 'roll.4' - 'if target.type.ZombiePigman': #I quantify axes as 'blunt damage', just for balance purposes so they can be crazy player slayers but not so good against zombies. - 'div.2' - '-5' - 'roll.2' - 'if target.type.Zombie and target.fireticks.lessthan.20': - 'div.2' - '-4' - 'roll.2' - 'if target.type.Skeleton': - '3' - 'roll.2' - 'if attacker.wielding.BOW': #A little randomization for player arrows. - '-2' - 'roll.4' - 'if target.type.ZombiePigman': #and some reduction for 'piercing' types, but more just a down-randomizer. - '-2' - 'roll.2' - 'if target.type.Zombie and target.fireticks.lessthan.20': - '-2' - 'roll.2' - 'if target.type.Skeleton': #Except skeletons, who laugh at your arrows going right through them. - 'div.2' - '-2' - 'roll.2' - 'if Target.Y.lessthan.48': #Players do less damage when 'deep' as well - '-1' - 'if Target.Y.lessthan.24': #Players do less damage when 'deep' as well - '-2' - 'if attacker.wielding._pickaxe': #Covering the rest of the tools, picks do 'piercing' like arrows, so get an extra hitch against skellies. - '3' - 'roll.2' - 'if target.type.Skeleton': - '-4' - 'roll.2' - 'if attacker.wielding._spade': #Shovels suck. Use it to dig your own grave! Except against zombies - '2' - 'if target.type.Zombie': #Easter eggs - '4' - 'roll.4' - 'if chance.5': - "message.attacker. Ed, this is serious!" - 'if chance.5': - "message.attacker. Don't forget to kill Philip!" - 'if attacker.wielding._hoe': #This makes more sense with my server's texture pack, hoes look like scythes! - 'roll.4' - 'if target.type.Skeleton': - '-2' - 'if target.type.ZombiePigman': - 'roll.6' - 'if target.type.Zombie': - 'roll.8' - 'if attacker.wielding.DIAMOND_AXE': #High Crit! - 'if chance.40': - 'roll.12' - "message.attacker.Critical Hit!" - "message.target.You've been critically hit!" - 'if attacker.wielding.DIAMOND_SWORD': #Crit! - 'if chance.30': - 'roll.8' - "message.attacker.Critical Hit!" - "message.target.You've been critically hit!" - 'if attacker.wielding.IRON_AXE': #Less Crit! - 'if chance.20': - 'roll.6' - "message.attacker.Critical Hit!" - "message.target.You've been critically hit!" - 'if attacker.wielding.IRON_SWORD': #Bitty Crit! - 'if chance.15': - 'roll.4' - "message.attacker.Critical Hit!" - "message.target.You've been critically hit!" - 'if attacker.wielding.GOLD_SWORD': #FIRE! Gold stuff is magical btw. - 'if chance.60 and target.fireticks.lessthan.20': - 'targeteffect.addfireticks': - '60' - 'if chance.100 and target.fireticks.greaterthanequals.20': - 'targeteffect.addfireticks': - '20' - 'if attacker.wielding.GOLD_AXE': #Magic or just insane, idk. - 'if chance.50': - 'targeteffect.explode': '2' - 'if attacker.falldistance.greaterthanequals.1 and !event.hasrangedelement': #High ground has advantage in melee? Why not. - '3' - "message.attacker.Leap Attack!" - "message.target.You've been sundered by a Leap Attack!" - 'if attacker.wielding.DIAMOND_HOE': #Now we just need cloaks and skull masks... - 'if chance.3': - '10' - 'roll.20' - "message.attacker.Reaped!" - "message.target.You've been reaped!" - 'if attacker.wielding.GOLD_HOE': #Higher rate because of stupid low durability, but does slightly less insane damage. - 'if chance.5': - 'roll.30' - "message.attacker.Reaped!" - "message.target.You've been reaped!" - 'if attacker.wielding.IRON_HOE': #Just to keep the trend - 'if chance.1': - 'roll.18' - "message.attacker.Reaped!" - "message.target.You've been reaped!" - 'if attacker.wielding.WOOD_HOE': #Keep this our little secret! - 'if chance.1': - 'if chance.1': - 'targeteffect.explode': '1' - 'roll.60' - "message.attacker.SUPER REAPED!" - "message.target.You've been SUPER REAPED!" - 'if attacker.wearing.LEATHER_CHESTPLATE': #Deal less damage if wearing armor! - '-1' #- 'if attacker.wearing.LEATHER_HELMET': Just gonna negate these trivial pieces - 'if attacker.wearing.LEATHER_LEGGINGS': - '-1' #- 'if attacker.wearing.LEATHER_BOOTS': - 'if attacker.wearingonly.LEATHER_HELMETLEATHER_CHESTPLATELEATHER_LEGGINGSLEATHER_BOOTS': #Leather switches to a teeny damage bonus if wearing full set, larger bonus if shooting a bow or even if throwing eggs or snowballs! - '4' - 'if event.hasrangedelement': - '3' - 'roll.2' - 'if attacker.wearing.IRON_CHESTPLATE': #Iron really slows you down if you want that damage reduction... - '-2' - 'if attacker.wearing.IRON_HELMET': - '-1' - 'roll.1' - 'if attacker.wearing.IRON_LEGGINGS': - '-2' - 'roll.1' - 'if attacker.wearing.IRON_BOOTS': - '-1' - 'roll.1' - 'if attacker.wearingonly.IRON_HELMETIRON_CHESTPLATEIRON_LEGGINGSIRON_BOOTS': #Wearing whole set negates a little penalty - '2' - 'if attacker.wearing.GOLD_CHESTPLATE': #Gold breaks the mould! Random damage bonus! - 'roll.3' - 'if attacker.wearing.GOLD_HELMET': - 'roll.1' - 'if attacker.wearing.GOLD_LEGGINGS': - 'roll.2' - 'if attacker.wearing.GOLD_BOOTS': - 'roll.1' - 'if attacker.wearingonly.GOLD_HELMETGOLD_CHESTPLATEGOLD_LEGGINGSGOLD_BOOTS': #and a little guaranteed bonus with full set, with a chance of fire damage with any weapon! - '2' - 'if chance.10': - 'targeteffect.addfireticks': '20' - 'if attacker.wearing.DIAMOND_CHESTPLATE': #Diamond's pieces will randomly negate the penalty - '-2' - 'if chance.50': - '2' - 'if attacker.wearing.DIAMOND_HELMET': - '-1' - 'if chance.50': - '1' - 'if attacker.wearing.DIAMOND_LEGGINGS': - '-2' - 'if chance.50': - '2' - 'if attacker.wearing.DIAMOND_BOOTS': - '-1' - 'if chance.50': - '1' - 'if attacker.wearingonly.DIAMOND_HELMETDIAMOND_CHESTPLATEDIAMOND_LEGGINGSDIAMOND_BOOTS': #Full set gives a little random life leech. - 'attackereffect.addhealth': 'roll.2' animal: #Same 'deep' thing, but on wolves if they get down there... - 'if Attacker.Y.lessthan.48': - 'roll.2' - 'if Attacker.Y.lessthan.24': - 'roll.2' lightning: #Boosh! - '-2' - 'roll.6' lava: #I'd rather the lava kill me than the fire ticks afterward - '2' - 'if target.wearing.DIAMOND_BOOTS': #Direct exposure reduction. Could probably wade through lava for a short time with gold boots and iron damage reduction... which is AWESOME! - '-4' - 'if target.wearing.GOLD_BOOTS': - '-6' - 'if target.wearing.IRON_BOOTS': - '-2' - 'if target.wearing.LEATHER_BOOTS': - '-1' explosion: #Helmets reduce this. Gold is extra good of course. - 'if target.wearing.DIAMOND_HELMET': - '-3' - 'if target.wearing.GOLD_HELMET': - 'div.2' - 'if target.wearing.IRON_HELMET': - '-2' - 'if target.wearing.LEATHER_HELMET': - '-1' fall: #Boots reduce fall damage. Not by too much though... - 'if target.wearing.DIAMOND_BOOTS': - '-2' - 'if target.wearing.GOLD_BOOTS': - '-6' - 'if target.wearing.IRON_BOOTS': - '-1' - 'if target.wearing.LEATHER_BOOTS': - '-3' void: #Get on with it! - 'set.20' burn: #Tick damage reduction. Gold practically negates. - 'if target.wearing.DIAMOND_LEGGINGS': - '-3' - 'if target.wearing.GOLD_LEGGINGS': - '-5' - 'if target.wearing.IRON_LEGGINGS': - '-2' - 'if target.wearing.LEATHER_LEGGINGS': - '-1' - '2' fire: #Direct exposure reduction. - 'if target.wearing.DIAMOND_BOOTS': - '-4' - 'if target.wearing.GOLD_BOOTS': - '-6' - 'if target.wearing.IRON_BOOTS': - '-2' - 'if target.wearing.LEATHER_BOOTS': - '-1' - '2' drowning: #Changes drowning dynamic. Won't get stuck underwater because of constant damage taken, but still drown just as fast. - '3' - 'targeteffect.addairticks': '40' cactus: #This is more to reduce damage to mobs. Player's armor handles the rest. - '-2' - 'roll.3' ZombiePigman: - '2' - 'roll.4' - 'if event.environment.NETHER': #Make em extra nasty! - '2' - 'targeteffect.addfireticks': '20' Creeper_Normal: #Damage reduced when wearing a helmet, gold is extra good. - 'if target.wearing.DIAMOND_HELMET': - '-3' - 'if target.wearing.GOLD_HELMET': - 'div.2' - 'if target.wearing.IRON_HELMET': - '-2' - 'if target.wearing.LEATHER_HELMET': - '-1' Creeper_Charged: #Creeper cluster bombs? - 'targeteffect.explode': '2' - 'if target.wearing.DIAMOND_HELMET': - '-3' - 'if target.wearing.GOLD_HELMET': - 'div.2' - 'if target.wearing.IRON_HELMET': - '-2' - 'if target.wearing.LEATHER_HELMET': - '-1' Spider: #Spiders are less hax but will always do a half heart (You'll see later in this config). - '-3' #They definitely still chew up your armor fast though. - 'roll.7' Giant: - 'roll.4' Zombie: #Zombies heal by biting things! - '2' - 'roll.2' - 'attackereffect.addhealth': '5' Slime: - 'roll.8' - 'if event.value.greaterthan.7': - 'attackereffect.setsize': '8' - '-4' #Skeleton: Handled earlier cause I'm lazy. Ghast: - '2' Wolf_Wild: #Similar to spiders, slightly less damage because they hit fast but chew up your armor. - '-4' - 'roll.4' - 'if world.time.lessthan.14000': #Normalized damage at night - '2' - 'if event.environment.NETHER': #Wolves spawned in the nether by AngryWolves in place of pigzombies are flaming hellhounds. - 'targeteffect.setfireticks': #So let's make them really firey. - '40' Wolf_Tame: #A little randomization but no bonus because wolves are a little OP anyway. - '-2' - 'roll.4' - 'if target.type.Spider': #Punching spiders gets you bitten. Makes up for their occasionally floored hits. 'if attacker.wielding.AIR': - 'attackereffect.Hurt': '1' - 'if target.type.Player': #Player defensive tree - 'if event.value.lessthanequals.0': #Always take at least half a heart to apply armor damage. - 'set.1' - 'if attacker.type.player': #Unless it's a player punching us with an item maybe - 'set.0' - 'if attacker.wielding.AIR': #So we'll check for fists and tools too! Tried an 'or' statement but didn't seem to work... - 'set.1' - 'if attacker.wielding._sword': - 'set.1' - 'if attacker.wielding._axe': - 'set.1' - 'if attacker.wielding.BOW': - 'set.1' - 'if attacker.wielding._pickaxe': - 'set.1' - 'if attacker.wielding._spade': - 'set.1' - 'if attacker.wielding._hoe': - 'set.1' - 'if target.wearing.LEATHER_CHESTPLATE': #Leather makes you dodge, tweaked to ignore some environmentals - '-1' #All chestplates and leggings give a little bit of 100% damage reduction - 'if chance.6 and !attacker.type.fire and !attacker.type.lava and !attacker.type.fall and !attacker.type.burn': - 'set.0' - "message.target.Dodged!" - "message.attacker.Your attack was dodged!" - 'if target.wearing.LEATHER_HELMET': - 'if chance.2 and !attacker.type.fire and !attacker.type.lava and !attacker.type.fall and !attacker.type.burn': - 'set.0' - "message.target.Dodged!" - "message.attacker.Your attack was dodged!" - 'if target.wearing.LEATHER_LEGGINGS': - '-1' - 'if chance.3 and !attacker.type.fire and !attacker.type.lava and !attacker.type.fall and !attacker.type.burn': - 'set.0' - "message.target.Dodged!" - "message.attacker.Your attack was dodged!" - 'if target.wearing.LEATHER_BOOTS': - 'if chance.2 and !attacker.type.fire and !attacker.type.lava and !attacker.type.fall and !attacker.type.burn': - 'set.0' - "message.target.Dodged!" - "message.attacker.Your attack was dodged!" - 'if target.wearingonly.LEATHER_HELMETLEATHER_CHESTPLATELEATHER_LEGGINGSLEATHER_BOOTS': #Set bonus totals out to ~30% dodge rate - 'if chance.20 and !attacker.type.fire and !attacker.type.lava and !attacker.type.fall and !attacker.type.burn': - 'set.0' - "message.target.Dodged!" - "message.attacker.Your attack was dodged!" - 'if target.wearing.IRON_CHESTPLATE': #Iron gives straight damage reduction chance - '-1' - 'if chance.25': - '-3' - 'if target.wearing.IRON_HELMET': - 'if chance.10': - '-1' - 'if target.wearing.IRON_LEGGINGS': - '-1' - 'if chance.15': - '-2' - 'if target.wearing.IRON_BOOTS': - 'if chance.10': - '-1' - 'if target.wearingonly.IRON_HELMETIRON_CHESTPLATEIRON_LEGGINGSIRON_BOOTS': #Set bonus is ~60% total chance to reduce an average of ~4 hearts of damage - 'if chance.20': - '-2' - 'if target.wearing.GOLD_CHESTPLATE': #Gold set is like gold weapons, sets attackers ON FIRE! - '-1' - 'if chance.30': - 'attackereffect.addfireticks': - '60' - 'if target.wearing.GOLD_HELMET': - 'if chance.10': - 'attackereffect.addfireticks': - '20' - 'if target.wearing.GOLD_LEGGINGS': - '-1' - 'if chance.20': - 'attackereffect.addfireticks': - '40' - 'if target.wearing.GOLD_BOOTS': - 'if chance.10': - 'attackereffect.addfireticks': - '20' - 'if target.wearingonly.GOLD_HELMETGOLD_CHESTPLATEGOLD_LEGGINGSGOLD_BOOTS': #Even more fire duration, with a chance of a little extra 'kick'! - 'attackereffect.addfireticks': - '80' - 'if chance.10': - 'attackereffect.explode': '1' - 'if target.wearing.DIAMOND_CHESTPLATE': #Diamond reflects damage back at the attacker. - '-2' - 'if chance.30': - 'attackereffect.Hurt': '3' - 'if target.wearing.DIAMOND_HELMET': - 'if chance.10': - 'attackereffect.Hurt': '1' - 'if target.wearing.DIAMOND_LEGGINGS': - '-1' - 'if chance.20': - 'attackereffect.Hurt': '2' - 'if target.wearing.DIAMOND_BOOTS': - 'if chance.10': - 'attackereffect.Hurt': '1' - 'if target.wearingonly.DIAMOND_HELMETDIAMOND_CHESTPLATEDIAMOND_LEGGINGSDIAMOND_BOOTS': #Guaranteed damage to attacker with full set, and should average 3.5 hearts reflected. - 'attackereffect.Hurt': '2' - 'if target.light.lessthanequals.5': #Players take extra damage in the darkness! - 'roll.4' # mob: # armor: # ranged: # humans: # melee: # animal: # Creeper: # Spider: # Giant: # Slime: # Ghast: # snowball: # bow: # egg: # fireball: # other: # pickaxe: # AIR: # spade: # hoe: # axe: # sword:

animal:

# Chicken:
# Sheep:
# Pig:
# Squid:
# Wolf:
# Cow:

Death: Food: debugging: normal Spawn: - 'switch.target.type': #A little extra health for animals too because of lethality running rampant. Underground spawns get bonus health. Creeper: - 'if !target.isexposedtosky and target.Y.lessthanequals.64': - 'roll.4' Chicken: - '2' Sheep: - '6' # Giant: Slime: - '2' ZombiePigman: - 'range.44.50' Spider: - 'range.14.16' - 'if !target.isexposedtosky and target.Y.lessthanequals.64': - 'roll.8' Pig: '3' # Squid: Wolf: - 'range.16.18' - 'if !target.isexposedtosky and target.Y.lessthanequals.64': #Never a natural spawn underground, only AngryWolves spawns which are hostile, so let's make this consistent! - '4' - 'roll.2' - 'if target.isexposedtosky and world.time.lessthan.14000': #Outside spawns at night, particulary on the 'full moons' that AngryWolves does. - '2' #No point on other mobs, because most mobs spawn at night anyway. Zombie: - 'range.36.40' - 'if !target.isexposedtosky and target.Y.lessthanequals.64': - 'roll.12' Cow: #Bovines are tough mofos! - '8' Ghast: #Because I hate them SO MUCH... and arrows kinda suck now. - '-4' Skeleton: - 'range.12.18' - 'if !target.isexposedtosky and target.Y.lessthanequals.64': - 'roll.6'

**Syntax:** *$entityeffect.knockback.#X.#Y*
Nested elements:
* *Direct Knockback*
* Using only routines for a Knockback nest will apply the result to a knockback vector.
* *Parameterized Knockback*
* X: Affects the horizontal velocity relative to the knockback vector.
* Y: Affects the absolute vertical velocity of the knockback vector.
**Description:** Applies a velocity whose power is calculated with nested elements and direction is determined by the following cases:
* Target-only events:
* Multiple-entity events: For Projectile-only events (as of 10/23/2011, only the ProjectileHit node), the vector is between the projectile and the shooter. For attacker-target events, it is between the attacker and the target.
**Examples:**
```yaml
Damage: # Apply a basic knockback to targets of attacks from members of the group Brute.
- 'if attacker.group.Brute':
- 'targeteffect.knockback': 'set.40'
```
```yaml
Damage: # Screwball attack, anybody?
- 'if projectile.type.egg and attacker.group.metroid':
- 'targeteffect.knockback':
X: 'set.0'
Y: 'set.30'
```
The following configuration snippets are distinct possibilities for the use of the Knockback routine, but require some testing and/or tinkering:
```yaml
Damage: # Hookshot effect with a tag and an arrow?
- 'if attacker.haspermission.hookshot.use':
- 'attackereffect.knockback':
- 'set.0'
```

Introduction

Welcome to the ModDamage tutorial! If you're looking to start messing with damage mechanics in Minecraft, you've come to the right place!

So. First things first. This tutorial is intended to be an interactive, hands-on experience. If you don't already have ModDamage downloaded and placed in your Bukkit plugins folder, it's recommended you do so now.

Got that all done? Okay. Here goes.

ModDamage, by itself, does nothing upon installation. You may have noticed this if you just dropped the ModDamage JAR into your server plugins folder without a configuration...and nothing happened. This is because ModDamage configuration doesn't have any routines defined in its configuration (which, if this is a fresh installation, should have generated automagically for you)! Without routines, ModDamage can literally do nothing - it's up to you to put everything you want into ModDamage. ModDamage will never do anything you do not explicitly tell it to. Thus, our first question for this tutorial is: "how do we configure ModDamage?"

Note: The sample configurations in this tutorial should be easily pastable into ModDamage, though in some cases you may have to adapt them to fit your setup. If you're wanting to tinker with one, you can use this online YAML parser to sanity-check your config files when you write your own configuration. Just sayin'.

The Tutorial

Routines: MD's Configuration Basis

Base Routines

To begin, we present the concept of routines. These are string patterns written into the config.yml that ModDamage interprets as...well, routines to be executed for the relevant event that is fired. Routines serve as extensions of game mechanics themselves, and the most effective way to demonstrate them is with example. That said, consider the following configuration in ModDamage:

Damage:  '2'

A simple integer string applies the Addition base routine - that is, it will add its value to a damage event's current value when the routine is executed. In this sample configuration, ALL damage events will have their damage values raised by a value of 2. Contrast with this next configuration:

Damage: 'set.2'

This is another base routine called "Set". It literally sets an event's value to the specified value whenever executed. Both Add and Set routines are examples of "base" routines in ModDamage - which require no instructive components besides themselves. The ModDamage routine library has a handful of base routines that permits most simple math and simple pseudo-random calculations, some of which will be discussed in later parts of this tutorial.

Conditional Routines

As base routines are otherwise fairly self-explanatory, we shall now discuss routines that affect other routines, or "nested" routines. The most immediately useful of these are Conditional routines. Conditionals control the flow of routine execution by virtue of simple propositional logic that most people are familiar with - again, explaining this is best done by virtue of demonstration. Consider the following configuration with a single Conditional routine:

Damage:
    - 'if attacker.type.Creeper':
        - 'set.200'
        - 'if target.group.Admin': 'set.0'

The value of any damage event involving an attacking Creeper will always be 200, the max health possible in any LivingEntity in Minecraft - unless the target is a member of the group Admin, in which case damage will be set to 0. Therefore, only Admins could possibly survive MC's favorite suicidal shrubs on this server.

Retrospectively it's easy to see the use of the "attacker.type" conditional in Minecraft. With the deprecation of the Elements trees that were used in early releases of ModDamage, the EntityType conditional is a crucial part of any reasonably complicated configuration. Those who are new to ModDamage should become acquainted with the ModDamage Elements hierarchy, an internal interpretative structure used by ModDamage. This hierarchy can be found at the [[config reference|Configuration Reference]] - it's strongly recommended you take a look at the relevant section if you plan on doing any tinkering with Type control routines.

Here's another example of the Entity Type conditional put to use, this time with multiple statements in the routine:

Damage:
    - 'if attacker.type.human': 
        - 'set.4'
        - 'if attacker.group.Admins and target.group.Default': 'mult.2' # Same-line configuration. :D
    - 'if target.group.Default': '2' 

Note: single-line configuration can only be done with a single BASE routine string - nested routine types MUST be formally placed underneath and indented..

The characteristics of this configuration can be readily summed up in English:

  1. All humans have a base attack damage of 4, regardless of item in hand.
  2. Any member of the group Admins deals (base_damage * 2) to any member of the group Default, which in this case is 8 (a hefty four hearts!).
  3. Any member of the group Default takes an additional 2 damage from all damage sources.

So, if a member of the group Admin were to attack a member of the group Default, then it would be calculated as (4 * 2 + 2) = 10. Likewise, if a member of any other group attacked a member of Default, the calculation would simply be (4 + 2) = 6 damage.

With the introduction of control branching it is very important to note here that the order of operation for MD configuration is exactly in the order you place it.

Switch Routines

Switch routines complement Conditional statements with a different method of control commonly referred to as "branching". Switches are designed to work very similarly to switch statements in Java, and have relatively simple syntax:

- 'switch.something':
    FirstCase:
        - SOME STATEMENTS
    SecondCase:
        - SOME STATEMENTS
    #...etc.

We shall also introduce the Spawn event node into our MD repertoire with yet another example. The Spawn configuration controls event values for creature spawn events - and this works for players too.

#Sample Spawn config
Spawn:
    - 'switch.target.type':       # You can use "attacker" in this EntityType conditional without complaint, 
                                  #   but semantically you'll always want to use "target" for Spawn.
        Pig: 'set.200'
        Creeper:
            - 'set': 'range.3.7'  # A simple equation that defines an upper and lower bound that randomly assigns
                                  #   a value between that range. In this example, Creepers now spawn with 
                                  #   health between 3 and 7.
                                  
        Ghast: 'set.0'            # If a nonpositive result is calculated for spawning, then it simply cancels the event. :D
        
        Human: 'set.22'           # Wee power boost. :)
        Player: 'set.12'

There is a problem with this configuration - that is, the Player case never gets executed! If you refer to the ModDamage Elements table in the [[config reference|Configuration Reference]], you'll notice that Player is a subcategory of Human - and thus any Player would get caught by the Human case. Be wary of these types of mistakes as you configure MD.

Calculations

Calculation routines are not control-type routines - rather, they use nested routines to calculate an input value for the effect. Functionally, they are similar to base routines in usage - however, they differ in the respect that subroutines do not directly affect event values. The routines that may be of immediate interest in this tutorial shall, as usual, be demonstrated by example:

Damage:
    - 'switch.attacker.group':
        RedWizards:
            - 'switch.attacker.wielding':
                Book: # Heal any ol' schmuck for 1 heart.
                    - 'if target.health.greaterthan.18':
                        - 'targeteffect.sethealth': '20'
                    - 'if target.health.lessthanequals.18':
                        - 'targeteffect.addhealth': '2'
                Bookshelf:
                    -'if target.group.RedTeam': # Multigroup is awesome this way - only allow this to heal teammates.
                            - 'targeteffect.heal': '6'
                Coal:
                    -'if_not target.group.RedTeam and !target.isonfire':
                        - 'targeteffect.addfireticks': 'range.300.500' # Sets the target on fire, though this is a fairly random number. :D

There is a single Calculation routine used here: the [[ChangeProperty Calculation|Calculation: Change Property]] used for fire ticks and health. This configuration allows for RPG-type healing and, more importantly, lets players of the RedWizard group set people outside of that group on fire.

Hopefully by this point you have a gist of what ModDamage syntax is like, and should be able to write a bit yourself. There are several major

Wrapping It All Up: Testing Your Configuration

With any feature on a server, it's a good idea to test thoroughly so you don't have any surprises. Refer to [[this FAQ page|FAQ: How do I debug in MD?]] to learn how to debug your configurations in MD!

That's about all there is to basic ModDamage usage. Pat yourself on the back! You finished the first tutorial! With these basics alone, you should be able to configure ModDamage to suit most common needs. If you're ready to start tinkering now, a complete reference to ModDamage routines is available at the [[Configuration Reference page|Configuration Reference]]. If you're looking to get tap the more powerful features of MD, check out [[the next tutorial|Tutorial 2: Advanced MD]].

Aliasing

Our first example for Aliasing in this tutorial will be a redux of the configuration we used for Calculations in the first tutorial. Remember this?

Damage:
    - 'switch.attacker.group':
        RedWizards:
            - 'switch.attacker.wielding':
                Book:
                    - 'targeteffect.heal': '2' # Heal any ol' schmuck for 1 heart. Note that single-line nesting can be done here too.
                Bookshelf: 
                    -'switch.target.group':
                        RedTeam:             # Multigroup is awesome this way - only allow this to heal teammates.
                            - 'targeteffect.heal': '6'
                Coal:
                    -'if_not target.group.RedTeam':
                        - 'targeteffect.setfireticks': 'range.3000.5000' # Sets the target on fire, though this is a fairly random number. :D

Now let's say you wanted to implement a class of sword-wielders, too, which have some common skills. We'd use aliasing to reduce the volume of our configuration, like so:

Damage:
    - 'if attacker.group.Wizard':
        - 'switch.attacker.wielding':
            Book:
                - 'targeteffect.heal': '2' # Heal any ol' schmuck for 1 heart. Note that single-line nesting can be done here too.
            Bookshelf: 
                -'switch.target.group':
                    RedTeam:             # Multigroup is awesome this way - only allow this to heal teammates.
                        - 'targeteffect.heal': '6'
            Coal:
                -'if_not target.group.RedTeam':
                    - 'targeteffect.setfireticks': 'range.3000.5000' # Sets the target on fire, though this is a fairly random number. :D

Aliases:
    swordies:
	    - 'Red'
		- 'BlueWizard'

Now, we'll provide with a much more complex example, which also serves to demonstrate the flexibility and power of MD to change Minecraft. Suppose that there's a server with two factions: nether dwellers called Firebreathers, and those of the overworld called...well, the Overlanders. :P

Damage:
    - 'switch.environment':
        nether:
            - 'switch.attacker.type':
                Human:
                    - 'set.0'
                    - 'roll.7'
                    - 'if event.value.greaterthanequals.4': 
                        - 'binom.30': 'set.0'
                    - 'switch.attacker.group':
                        FireBreathers:
                            - 'if attacker.wielding._sword':
                                - '2'
                                - 'if attacker.wielding.DIAMOND_SWORD': '3'
                            - 'if target.group.Overlanders': '3' # PvP bonus against the Overlanders. :D
                        Overlanders:
                            - 'if target.group.FireBreathers': 'div.2' # Divide by 2.
                Ghast:
                    - 'set.4'
                    - 'roll.4'
                    - 'binom.20': '2' # Binomial calculation - define a percentage chance of executing 
                                      #   another calculation string, here it's '2'
                ZombiePigman:
                   - 'set': 'roll.12'# The 'roll' function gives an even probability distribution 
                                     #   all positive output values <= the specified value (12)
                                     # It's also worth noting that "set" is also a calculated routine here - more on this later.
            - 'switch.target.group':
                Firebreathers:
                    - 'switch.attacker.type':
                        burn: 'set.0'
                        fire: '2'
                        lava: '4'
                                              
        normal:
            - 'switch.attacker.group':
                Overlanders:
                    - 'binom.5': '10'         # Basically a 5% chance for a 5-heart hit. D:
                    - 'if target.type.mob or target.type.animal': '1'
                    - 'switch.attacker.wielding':
                        _farmtool: '2'        
                FireBreathers: '-4' # Pretty bad debuff. :<
            - 'switch.target.group':
                Firebreathers: '1' # Another mean debuff, but not so bad.
                
Aliases:
    item:
        axe:
            - 'WOOD_AXE'
            - 'STONE_AXE'
            - 'IRON_AXE'
            - 'GOLD_AXE'
            - 'DIAMOND_AXE'
        hoe:
            - 'WOOD_HOE'
            - 'STONE_HOE'
            - 'IRON_HOE'
            - 'GOLD_HOE'
            - 'DIAMOND_HOE'
        pickaxe:
            - 'WOOD_PICKAXE'
            - 'STONE_PICKAXE'
            - 'IRON_PICKAXE'
            - 'GOLD_PICKAXE'
            - 'DIAMOND_PICKAXE'
        spade:
            - 'WOOD_SPADE'
            - 'STONE_SPADE'
            - 'IRON_SPADE'
            - 'GOLD_SPADE'
            - 'DIAMOND_SPADE'
        sword:
            - 'WOOD_SWORD'
            - 'STONE_SWORD'
            - 'IRON_SWORD'
            - 'GOLD_SWORD'
            - 'DIAMOND_SWORD'
        farmtool:                # You can use other aliases to define aliases - just make sure all dependent aliases
            - '_axe'             #   you're using are defined above, since aliases are read sequentially.
            - '_hoe'
            - '_pickaxe'
            - '_spade'
    

Some syntax here may not be completely obvious - [*1]

First and foremost is that for most conditionals with a wide variety of possible comparison values, switch statements have been implemented

A full analysis won't be broached here, but rough basis of the configuration is as follows:

  • A FireBreather is much more powerful in the Nether - an Overlander attacked by a FireBreather with a diamond hoe would be killed instantly (with normal player health settings). Resistance to fire-based damage is also a bonus.

  • FireBreathers have significant negative buffs associated with being in the world "normal".

  • An Overlander wielding a farming tool (spade, hoe, pickaxe) has a definite offensive advantage in the "normal" (non-Nether-type) world, and a slight defensive bonus against mobs when in world "normal".

  • Overlanders in the world "normal" have a 5% chance for a critical-type strike in which they deal 10 damage (5 hearts).

With this in mind, one can see how quickly a relatively small configuration can vastly orient damage relationships in Minecraft in different directions. And there are still two more major configurations in ModDamage to go! :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment