codecombat/app/lib/world/systems/collision.coffee

51 lines
2.2 KiB
CoffeeScript
Raw Normal View History

2014-01-03 13:32:13 -05:00
# http://codingowl.com/readblog.php?blogid=124
module.exports.CollisionCategory = class CollisionCategory
2014-06-30 22:16:26 -04:00
@className: 'CollisionCategory'
2014-01-03 13:32:13 -05:00
constructor: (name, @superteamIndex=null, @collisionSystem) ->
2014-06-30 22:16:26 -04:00
# @superteamIndex is null for 'none', 'obstacles', and 'dead'.
# It's 0 for 'ground', 'air', and 'ground_and_air' units with no superteams.
2014-01-03 13:32:13 -05:00
# It's 1, 2, or 3 for the superteams it gets after that. We can only have 16 collision categories.
2014-06-30 22:16:26 -04:00
@ground = name.search('ground') isnt -1
@air = name.search('air') isnt -1
2014-01-03 13:32:13 -05:00
@name = CollisionCategory.nameFor name, @superteamIndex
@superteamIndex ?= 0 if @ground or @air
@number = 1 << @collisionSystem.totalCategories++
2014-06-30 22:16:26 -04:00
if @collisionSystem.totalCategories > 16 then console.log 'There should only be 16 collision categories!'
2014-01-03 13:32:13 -05:00
@mask = 0
@collisionSystem.allCategories[@name] = @
for otherCatName, otherCat of @collisionSystem.allCategories
if @collidesWith otherCat
@mask = @mask | otherCat.number
otherCat.mask = otherCat.mask | @number
collidesWith: (cat) ->
2014-06-30 22:16:26 -04:00
# 'none' collides with nothing
return false if @name is 'none' or cat.name is 'none'
2014-01-03 13:32:13 -05:00
2014-06-30 22:16:26 -04:00
# 'obstacles' collides with everything; could also try letting air units (but not ground_and_air) fly over these
return true if cat.name is 'obstacles' or @name is 'obstacles'
2014-01-03 13:32:13 -05:00
2014-06-30 22:16:26 -04:00
# 'dead' collides only with obstacles
return cat.name is 'obstacles' if @name is 'dead'
return @name is 'obstacles' if cat.name is 'dead'
2014-01-03 13:32:13 -05:00
2014-06-30 22:16:26 -04:00
# 'ground_and_air_<team>' units don't hit ground or air units on their team (so missiles don't hit same team)
2014-01-03 13:32:13 -05:00
sameTeam = @superteamIndex and cat.superteamIndex is @superteamIndex
return false if sameTeam and @ground and @air
2014-05-06 19:58:08 -04:00
2014-06-30 22:16:26 -04:00
# actually, 'ground_and_air<team>' units don't hit any ground_and_air units (temp missile collision fix)
return false if @ground and @air and cat.ground and cat.air
2014-01-03 13:32:13 -05:00
2014-06-30 22:16:26 -04:00
# 'ground' collides with 'ground'
2014-01-03 13:32:13 -05:00
return true if cat.ground and @ground
2014-06-30 22:16:26 -04:00
# 'air' collides with 'air'
2014-01-03 13:32:13 -05:00
return true if cat.air and @air
2014-06-30 22:16:26 -04:00
# doesn't collide (probably 'ground' and 'air')
2014-01-03 13:32:13 -05:00
false
@nameFor: (name, superteamIndex=null) ->
2014-06-30 22:16:26 -04:00
return name unless name.match('ground') or name.match('air')
name + '_' + (superteamIndex or 0)