Anything is possible with the referee!
You’ll be overriding some things from within the referee, which, is a little hacky, but once you understand how it all works, anything is possible. Here are some references where stuff like this has been done:
Double click on the well in any of those levels and find the ‘referee’ component within. Search the code for performCollect
and look how we override it.
# The referee always has a direct reference to the hero using @hero
# @ is CoffeeScript for 'this', which is currently referring to the referee.
@hero.oldCollect = @hero.performCollect # Create a reference to the old collection function
@hero.performCollect = (item) -> # Overwrite the old function with a new one
# Replace with your own stuff here here!
if item.type is "spiked-ball"
@takeDamage 10, null
# Note we are in the scope of the hero, so @ refers to hero, not referee
@oldCollect item
As JavaScript, to help if you are more familiar with it:
this.hero.oldCollect = this.hero.performCollect;
this.hero.performCollect = function(item) {
if(item.type == "spiked-ball") {
this.takeDamage(9999, null);
}
this.oldCollect(item);
}
Now, the next step is spawning these items. Inside the referee component, you’ll want to include the Thang-types inside of the Spawns component as well as create buildable references for these Thangs inside of the Builds component. The Spawns component makes sure these Thangs are loaded when the level is loaded, but the Builds component allows for the creation of these Thangs during the level. Below is an example of the two ways to define a buildable. You can create a template to reference inside the level (in Continuous Alchemy we created templates of the poison and water, usually when we need to do custom components that aren’t easy to hook up when spawning them (in this case, we color them)). However, when spawning a Headhunter, we just point directly to the ThangType because he can rampage as normal without any changes required.
Now to build these items you’ll write code like this:
# Inside of the referee again:
posX = 23
posY = 42
# Note, for this to work, we need a a buildable with the object key: "spike-ball" for this to be created.
@instabuild "spike-ball", posX, posY # Instantly place this item onto the field.
Again in JavaScript:
var posX = 23;
var posY = 42;
this.instabuild("spike-ball", posX, posY);
And finally since we’re delving into the referee, I’ll touch on what the default functions inside of the referee do/mean:
setUpLevel: ->
# This happens once before everything is loaded. Note: this can happen before the hero is fully loaded!
for i in [0...10]
@buildRandomWall()
onFirstFrame: ->
# This happens once at the start of the level, after everything has loaded, but unreliably at the start of everything
munchkin = @world.findThangByID "Grog"
munchkin.say "Fight me!"
chooseAction: ->
# This happens once every frame. You can use it to spawn items at regular intervals:
if @world.age % 3 is 0
# Spawn an item every 3 seconds.
checkVictory: ->
# Happens once every frame, at the end of the frame (I believe).
if @world.age > 50
if (munchkin for munchkin in @world.thangs when munchkin.type is 'munchkin' and munchkin.health > 0).length is 0
@world.setGoalState "killed-munchkins", "success"
I hope the level example and my code samples help point you in the right direction! Ask away in the Slack, and we’ll try our best to help you out.