File: gameplay\spell-casting\spell-invoking\System.js
/**
System which allows entities to combine colors to cast spells. Combining happens via the input system triggering the 'useCyan', 'useMagenta' or
'useYellow' events. Casting spells happens via the 'invoke' event. For an entity to invoke a spell, it needs to have a combination
of colors in the color queue that matches a pattern stored on the SpellInvoking component. No other components are required for this,
however actually casting a spell requires its own set of components specified by the SpellSystem.
@class SpellInvokingSystem
@constructor
@param entitySystemManager {Manager} The entity system manager whose entities this system will be working on.
@param inputSystem {KeyboardInputSystem}
@param spellSystem {SpellSystem}
*/
function SpellInvokingSystem(entitySystemManager, inputSystem, spellSystem){
//Color strings.
var cyan = 'c',
magenta = 'm',
yellow = 'y';
function useCyanEventCallback(entity){
var spellInvoking = entity.get(SpellInvoking);
if(!spellInvoking){
return;
}
//Prevents Cyan from being repeatedly queued by holding the use button.
spellInvoking._inputWasCyanUsed = true;
if(!spellInvoking._inputCanUseCyan){
return;
}
//Check if this entity can invoke spells and is permited to use the cyan color.
if(spellInvoking._canUseCyan){
//Shift the color queue.
for(var i=0; i<spellInvoking._colorQueue.length-1; ++i){
spellInvoking._colorQueue[i] = spellInvoking._colorQueue[i+1];
}
//Add cyan at the end.
spellInvoking._colorQueue[i] = cyan;
}
}
function useMagentaEventCallback(entity){
var spellInvoking = entity.get(SpellInvoking);
if(!spellInvoking){
return;
}
//Prevents Magenta from being repeatedly queued by holding the use button.
spellInvoking._inputWasMagentaUsed = true;
if(!spellInvoking._inputCanUseMagenta){
return;
}
//Check if this entity can invoke spells and is permited to use the magenta color.
if(spellInvoking._canUseMagenta){
//Shift the color queue.
for(var i=0; i<spellInvoking._colorQueue.length-1; ++i){
spellInvoking._colorQueue[i] = spellInvoking._colorQueue[i+1];
}
//Add magenta at the end.
spellInvoking._colorQueue[i] = magenta;
}
}
function useYellowEventCallback(entity){
var spellInvoking = entity.get(SpellInvoking);
if(!spellInvoking){
return;
}
//Prevents Yellow from being repeatedly queued by holding the use button.
spellInvoking._inputWasYellowUsed = true;
if(!spellInvoking._inputCanUseYellow){
return;
}
//Check if this entity can invoke spells and is permited to use the yellow color.
if(spellInvoking._canUseYellow){
//Shift the color queue.
for(var i=0; i<spellInvoking._colorQueue.length-1; ++i){
spellInvoking._colorQueue[i] = spellInvoking._colorQueue[i+1];
}
//Add yellow at the end.
spellInvoking._colorQueue[i] = yellow;
}
}
function invokeEventCallback(entity){
var spellInvoking = entity.get(SpellInvoking);
if(spellInvoking && spellInvoking._invokingPatterns){
var queueCyanColorCount = 0,
queueMagentaColorCount = 0,
queueYellowColorCount = 0;
//Calculate how much of each color is in the color queue.
for(var i=0; i<spellInvoking._colorQueue.length; ++i){
switch(spellInvoking._colorQueue[i]){
case cyan : queueCyanColorCount++;
break;
case magenta : queueMagentaColorCount++;
break;
case yellow : queueYellowColorCount++;
}
}
var invokingPatterns = spellInvoking._invokingPatterns,
patternCyanColorCount, patternMagentaColorCount, patternYellowColorCount;
//Try to match the colors in the queue to the color patterns for the spells.
//A pattern is in the form 'ccy'. It's a string, where each individual letter describes a color.
for(var pattern in invokingPatterns){
//Reset the pattern color counters.
patternCyanColorCount = 0;
patternMagentaColorCount = 0;
patternYellowColorCount = 0;
//Calculate how much of each color the pattern requires.
for(var j=0; j<pattern.length; ++j){
switch(pattern.charAt(j)){
case cyan : patternCyanColorCount++;
break;
case magenta : patternMagentaColorCount++;
break;
case yellow : patternYellowColorCount++;
break;
}
}
//If a match is found, cast the spell and return.
if(patternCyanColorCount === queueCyanColorCount &&
patternMagentaColorCount === queueMagentaColorCount &&
patternYellowColorCount === queueYellowColorCount){
spellSystem.castSpell(entity, invokingPatterns[pattern]);
return;
}
}
}
}
inputSystem.subscribe('useCyan', useCyanEventCallback);
inputSystem.subscribe('useMagenta', useMagentaEventCallback);
inputSystem.subscribe('useYellow', useYellowEventCallback);
inputSystem.subscribe('invoke', invokeEventCallback);
var spellInvokingEntities = entitySystemManager.createAspect([SpellInvoking]);
/**
@method update
*/
this.update = (function(){
function updateSpellInvokingEntity(entity){
var spellInvoking = entity.get(SpellInvoking);
//Prevents Cyan from being repeatedly queued by holding the use button.
if(spellInvoking._inputWasCyanUsed){
spellInvoking._inputCanUseCyan = false;
}else{
spellInvoking._inputCanUseCyan = true;
}
spellInvoking._inputWasCyanUsed = false;
//Prevents Magenta from being repeatedly queued by holding the use button.
if(spellInvoking._inputWasMagentaUsed){
spellInvoking._inputCanUseMagenta = false;
}else{
spellInvoking._inputCanUseMagenta = true;
}
spellInvoking._inputWasMagentaUsed = false;
//Prevents Yellow from being repeatedly queued by holding the use button.
if(spellInvoking._inputWasYellowUsed){
spellInvoking._inputCanUseYellow = false;
}else{
spellInvoking._inputCanUseYellow = true;
}
spellInvoking._inputWasYellowUsed = false;
}
return function(){
spellInvokingEntities.iterate(updateSpellInvokingEntity);
};
})();
/**
@method destroy
*/
this.destroy = function(){
inputSystem.unsubscribe('useCyan', useCyanEventCallback);
inputSystem.unsubscribe('useMagenta', useMagentaEventCallback);
inputSystem.unsubscribe('useYellow', useYellowEventCallback);
inputSystem.unsubscribe('invoke', invokeEventCallback);
spellInvokingEntities.destroy();
}
}