Created
June 26, 2019 20:44
-
-
Save CrazyPython/b865f297846713b2add391cda6540a84 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** START GAMEMODE FILE **/ | |
// gamemode files would be best in CoffeeScript | |
// real width is 3000 | |
// food was originally 800, food would add an element of dodging | |
// this mode should have the leaderboard disabled on the client | |
// npm install driftless for more accurate timing | |
// also could npm install driftless help make arras faster, by maing gameloop execute more accurately? | |
gamemode = {} | |
gamemode.flagCarriers = [] | |
gamemode.flagTimes = {} | |
gamemode.flagTimes[-1] /*blue*/ = 5*60*1000 | |
gamemode.flagTimes[-3] /*red*/ = 5*60*1000 | |
gamemode.minimapInterval = 5000 | |
const isFlag = e => e.type === 'flag' | |
/* enact the countdown for the flag carrier's team*/ | |
class flagCarrier_io { | |
constructor(body) { | |
this.body = body; | |
this.acceptsFromTop = true; | |
this.body.health._amount = this.body.health.amount | |
this.intervalCode = setInterval( | |
() => {gamemode.flagTimes[-this.body.team] -= 10} | |
, 10) | |
Object.defineProperty(this.body.health, 'amount', { | |
set: v => { | |
this.body.health._amount = v | |
if (v <= 0) { | |
clearInterval(this.intervalCode) | |
} | |
}, | |
get: v => this.body.health._amount | |
}) | |
} | |
think() {} | |
} | |
function broadcastCarrierData() { | |
/* wasteful way to broadcast flag status */ | |
let status | |
if (gamemode.flagCarriers.length == 0) { | |
status = 0 // no one's holding the flag | |
} else { | |
status = gamemode.flagCarriers[0].team // -1 if blue holds the flag, -3 if red holds the flag | |
} | |
console.log(gamemode.flagTimes) | |
sockets.broadcast(`%%CTF::STATUS ${status} ${gamemode.flagTimes[-1]} ${gamemode.flagTimes[-3]}`) | |
} | |
function createFlagAt(x, y) { | |
let flag = new Entity({x, y}) | |
flag.color = 4 | |
flag.define(Class.flag) | |
} | |
gamemode.setup = (Entity, Class, room) => { | |
createFlagAt(room.width/2, room.height/2) | |
} | |
function giveFlag(newOwner, Entity, Class, room, sockets) { | |
newOwner.hasFlag = true | |
console.log(newOwner.label, ':', newOwner.name) | |
newOwner.sendMessage('You have the flag.') | |
room.topPlayerID = newOwner.id // this way "usurped" messages show | |
const oldDestroy = newOwner.destroy.bind(newOwner) | |
gamemode.flagCarriers.push(newOwner) | |
newOwner.destroy = function() { | |
// this code should be moved to flagCarrier_io | |
// Inside this closure, newOwner is the *owner that is now dead* | |
// if `this` works inside here newOwner should be replaced with this | |
oldDestroy() | |
if (!newOwner.hasFlag) return | |
newOwner.hasFlag = false | |
gamemode.flagCarriers.splice(gamemode.flagCarriers.indexOf(newOwner), gamemode.flagCarriers.indexOf(newOwner)+1) | |
const viableNewOwners = newOwner.killCount.killers.filter(e => e.type === 'tank') | |
const nextOwner = viableNewOwners[0] | |
let message; | |
if (viableNewOwners.length > 0) { | |
giveFlag(nextOwner[0], Entity, Class, room, sockets) | |
message = `${nextOwner.name} captured the flag from ${newOwner.name}!` | |
} else { | |
createFlagAt(newOwner.x, newOwner.y) | |
broadcastCarrierData() | |
message = `${newOwner.name} has died and dropped the flag.` | |
} | |
sockets.broadcast(message) | |
}.bind(newOwner) | |
newOwner.controllers.push(new flagCarrier_io(newOwner)) | |
broadcastCarrierData() | |
} | |
let origType = null | |
gamemode.initializeNewSocket = socket => { | |
broadcastCarrierData() | |
} | |
gamemode.collide = (me, other, Entity, Class, room, sockets) => { | |
if (!origType) { | |
origType = room.randomType | |
room.randomType = () => origType('norm') | |
} | |
// io_hasFlag | |
let flag, notflag | |
if (me === null || other === null) { | |
return | |
} | |
if (isFlag(other)) { | |
flag = other | |
notflag = me | |
} else if (isFlag(me)) { | |
flag = me | |
notflag = other | |
} else { | |
return | |
} | |
if (notflag.type === 'tank') { | |
flag.color = 4 //9 //13 // gold colored | |
flag.kill() | |
sockets.broadcast(newOwner.name + ` captured the flag!`) | |
giveFlag(notflag, Entity, Class, room, sockets) | |
} | |
} | |
gamemode.shouldBeVisibleOnMinimap = me => { | |
if (me.hasFlag || isFlag(me)) { | |
return 17 | |
} | |
} | |
gamemode.customizeLeaderboard = defaultLeaderboard => { | |
// make the flag carriers the first ones | |
let leaderboard = defaultLeaderboard | |
/* for (let flagCarrier of gamemode.flagCarriers) { | |
if (leaderboard.indexOf(flagCarrier)) | |
leaderboard.splice(leaderboard.indexOf(flagCarrier)) | |
leaderboard.unshift(flagCarrier) | |
}*/ | |
return leaderboard | |
} | |
const util = require('./lib/util.js'); | |
const invariant = require('invariant') | |
class test { | |
setup() { | |
c.BOTS = 50 | |
} | |
assert() { | |
if (util.time() > 1000) { | |
invariant(entitiesNoFood.filter(isFlag).filter(e => e.health.amount > 0).length ^ gamemode.flagCarriers.length, 'Only one flag or flag carrier') | |
} | |
} | |
} | |
gamemode.test = new test() | |
gamemode.shouldEndGame = () => { | |
} | |
// Alpha version of gamemode.js, the scalable toolkit for developing gamemodes in Arras. | |
/** END GAMEMODE FILE **/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment