Skip to content

Commit

Permalink
highlights for unit status
Browse files Browse the repository at this point in the history
  • Loading branch information
lmartel committed Sep 8, 2013
1 parent 60cccc6 commit 60047bb
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 78 deletions.
85 changes: 42 additions & 43 deletions client.js
Expand Up @@ -34,23 +34,7 @@ if (Meteor.isClient) {
var msg = getMessage();
// msg = "a really long status message just so I can test exactly how this should be rendered in dat dere sidebar";
if(!msg) return undefined;
msg = msg.split(" ");
var formatted = "";
var chars = 0;
for(var i = 0; i < msg.length; i++){
var word = msg[i];
if(chars + word.length > MESSAGE_CHAR_WRAP){
formatted += "\n";
chars = 0;
} else {
formatted += " ";
}
formatted += word;

// +1 for space
chars += word.length + 1;
}
return ">> " + formatted.trim().split("\n").join(" <<<br>>> ") + " <<";
return "=====<br>" + msg + "<br>=====";
};

/**
Expand Down Expand Up @@ -118,7 +102,8 @@ if (Meteor.isClient) {
var replayData = {};
var count = 0;
Actions.find({ gameId: getGame()._id}, {sort: { timestamp: 1 } }).forEach(function(action){
if(action.round > maxRound) maxRound = action.round;
var baseRound = Math.floor(action.round);
if(baseRound > maxRound) maxRound = baseRound;

// Setup round is not set on a timeout, to avoid flickering of pieces
if(action.round === 0){
Expand All @@ -130,7 +115,7 @@ if (Meteor.isClient) {
replayData[count] = action._id;
replayData[action._id] = setTimeout(function(){
actionReplayDone(action);
message("Instant replay: ROUND " + action.round);
message("Instant replay: ROUND " + baseRound);
renderAction(action, board);
//TODO: might be a bug around here with the path callback. Call draw() after a timeout?
}, action.round * ROUND_MILLISECONDS);
Expand Down Expand Up @@ -327,8 +312,7 @@ if (Meteor.isClient) {
var start = board.get(unit.location);
var path = start.getPathTo(end);

// TODO: query database for max unit speed, use that as the divisor. Set as constant 5, override using startup()
var duration = Math.min(MOVE_MILLISECONDS * path.length, ROUND_MILLISECONDS);
var duration = Math.min(MOVE_MILLISECONDS * path.length, MAX_MOVE);
var move = board.action().get(unit.location).movePayloadAlongPath(
board.action().get(unit.location).getPathTo(
board.action().get(end.getLocation())
Expand Down Expand Up @@ -361,13 +345,18 @@ if (Meteor.isClient) {
var enemy = Units.findOne(end.getPayloadData());
setDefender(enemy);

Meteor.call("attack", getGame()._id, unit, enemy, function(err, hits){
if(hits > 0){
message("Attack successful!");
} else if(hits === 0) {
Meteor.call("attack", getGame()._id, unit, enemy, function(err, results){
if(results.hits > 0){
var str = "Attack successful!\n";
str += getCard(enemy).name + " was ";
if(results.status === UnitStatus.DAMAGED) str += UnitStatus.DISRUPTED + " and ";
str += results.status + ".";
// TODO render rolls
message(str);
} else if(results.hits === 0) {
message("Attack failed.");
}
// Units.update(unit._id, {$set: {used: true } });
toggleUnitSelection(unit);

});

Expand Down Expand Up @@ -431,36 +420,46 @@ if (Meteor.isClient) {
function unusedUnits(){
var board = getBoard();
if(board && isReplayOver()){
var unused = 0;
Units.find({_id: {$in: this.unitIds}}).forEach(function(unit){
if(unit.used){
board.get(unit.location).setHighlight(UNIT_USED, true).draw();
} else {
unused++;
}
});
return unused;
return Units.find({_id: {$in: this.unitIds}, used: false}).count();
}

return undefined;
}

Template.movement.unitStatus = function(){
unitStatus(false);
highlights(false);
};

function unitStatus(canAttack){
function highlights(canAttack){
var board = getBoard();
if(!board) return;

var bgs = [UNIT_SELECTED, CAN_MOVE_TO, ENEMY_SELECTED];
if(notYourTurn()){
bgs.push(UNIT_USED);
}
var bgs = [UNIT_SELECTED, CAN_MOVE_TO, ENEMY_SELECTED, UNIT_USED];
if(canAttack){
bgs = bgs.concat( [CAN_SEE, CAN_ATTACK, CAN_MOVE_TO_AND_SEE] ); //TODO: can't see?
}
clearHighlights(bgs);

Units.find({_id: {$in: getArmy().unitIds}, used: true }).forEach(function(unit){
board.get(unit.location).setHighlight(UNIT_USED, true).draw();
});

// Highlight all statuses. Pending takes precedence over active.
Armies.find({gameId: getGame()._id}).forEach(function(army){
Units.find({_id: {$in: army.unitIds} }).forEach(function(unit){
var hex = board.get(unit.location);
var used = hex.getHighlightColor() === UNIT_USED;
var hl;
if(unit.pendingStatus){
hl = getHighlightArgsForStatus(unit.pendingStatus, false);
} else if(unit.status){
hl = getHighlightArgsForStatus(unit.status, true);
}
if(!hl) return;
if(used) hl[1] += 0.3;
hex.setHighlight(hl[0], hl[1], hl[2]).draw();
});
});

var active = getUnit();
if(!active){
setCanMoveTo(undefined);
Expand Down Expand Up @@ -527,7 +526,7 @@ if (Meteor.isClient) {
};

Template.assault.unitStatus = function(){
unitStatus(true);
highlights(true);
};

Template.unitCard.events({
Expand Down
5 changes: 3 additions & 2 deletions init.js
Expand Up @@ -12,9 +12,10 @@ SELECT = "." + KLASS;
CONTENT_WIDTH = 0.75;
CONTENT_MARGIN = 0.10;
MESSAGE_CHAR_WRAP = 20;
ROUND_MILLISECONDS = 2000;
ROUND_MILLISECONDS = 3000;
TICK_MILLISECONDS = ROUND_MILLISECONDS / 60;
MOVE_MILLISECONDS = TICK_MILLISECONDS * 12;
MOVE_MILLISECONDS = TICK_MILLISECONDS * 8;
MAX_MOVE = ROUND_MILLISECONDS / 2;

DEPLOYMENT_ZONE_WIDTH = 3;

Expand Down
39 changes: 32 additions & 7 deletions lib/external/hex.money.js
Expand Up @@ -1097,12 +1097,30 @@ H$ = {};
function HexGrid_destroyDetachedAsset(asset, selectString){
selectString = selectString || "." + asset.klass;
delete asset.animating;
d3.select(selectString).remove();
var i = this.detachedAssets.indexOf(asset);
this.detachedAssets.splice(i, 1);
d3.selectAll(selectString).remove();
var assets = this.detachedAssets;
var keep = [];
for(var i = 0; i < assets.length; i++){
if(assets[i].klass !== asset.klass) keep.push(assets[i]);
}
this.detachedAssets = keep;
return this;
}

// H$.HexGrid.prototype.interruptAnimations = HexGrid_interruptAnimations;
// function HexGrid_interruptAnimations(){
//
// // slice to copy array to avoid concurrent modification issues
// var rogue = this.detachedAssets.slice(0);
// for(var i = 0; i < rogue.length; i++){
// console.log(rogue[i])
// if(rogue[i].animating) this.destroyDetachedAsset(rogue[i]);
// }
// this.detachedAssets = rogue;
// return this;
// }


/**
* The move animations are designed to be as interruptable as possible; the payload
* and asset are loaded into the destination at the beginning of the animation,
Expand All @@ -1117,7 +1135,7 @@ H$ = {};
// slice to copy array to avoid concurrent modification issues
var rogue = this.detachedAssets.slice(0);
for(var i = 0; i < rogue.length; i++){
if(rogue[i].animating) this.destroyDetachedAsset(rogue[i]);
if(rogue[i].animating || true) this.destroyDetachedAsset(rogue[i]);
}
return this;
}
Expand Down Expand Up @@ -1185,7 +1203,7 @@ H$ = {};

if(this.highlight && !this.highlightOver){
renderHex(this, highlightClass, this.highlight, this.highlight)
.style("fill-opacity", 0.5);
.style("fill-opacity", this.highlightOpacity);
}

if(Array.isArray(this.payload)){
Expand All @@ -1197,7 +1215,7 @@ H$ = {};

if(this.highlight && this.highlightOver){
renderHex(this, highlightClass, this.highlight, this.highlight)
.style("fill-opacity", 0.5);
.style("fill-opacity", this.highlightOpacity);
}

function renderHex(context, klass, stroke, fill){
Expand Down Expand Up @@ -1366,7 +1384,14 @@ H$ = {};
.attr("x1", startWillTravel.x()).attr("y1", startWillTravel.y())
.attr("x2", target.x()).attr("y2", target.y())
.each("end", function(){
if(destroy) grid.destroyDetachedAsset(asset, "#" + uniqueId);

// is flag has been disabled, stop
if(!asset.animating) return;
if(destroy){
grid.destroyDetachedAsset(asset, "#" + uniqueId);
} else {
asset.animating = false;
}
if(iterations > 1){
options.iterations = iterations - 1;
startHex.drawLineTo(targetHex, options);
Expand Down
59 changes: 52 additions & 7 deletions lib/helpers/util.js
Expand Up @@ -102,9 +102,9 @@ getAttacks = function(attacker, defender){
};

hasStatus = function(unit, status){
var stat = unit.statuses;
if(status) return stat.indexOf(status) !== -1;
return stat.indexOf(UnitStatus.DISRUPTED) !== -1 || stat.indexOf(UnitStatus.DAMAGED) !== -1
var stat = unit.status;
if(status) return stat === status;
return status !== null;
};

countHits = function(attacks, defender){
Expand All @@ -129,7 +129,7 @@ countHits = function(attacks, defender){
}
};

hasCover = function(gameId, unit){
rollCover = function(gameId, unit){
var loc = unit.location;
var layout = Maps.findOne(Games.findOne(gameId).mapId);
var bg;
Expand All @@ -141,19 +141,64 @@ hasCover = function(gameId, unit){
}
}

var type = getCard(unit).type;
var terrain = Terrain[bg];
var canRoll;
switch(terrain){
case Terrain.HOLES:
case Terrain.MARSH:
return getCard(unit).type === UnitType.SOLDIER;
canRoll = (type === UnitType.SOLDIER);
break;
case Terrain.FOREST:
case Terrain.HILL:
case Terrain.TOWN:
return true;
canRoll = true;
break;
default:
return false;
canRoll = false;
break;
}
if(canRoll){
var roll = Math.floor((Math.random() * 6) + 1);
if(type === UnitType.SOLDIER){
return roll >= 4;
} else {
return roll >= 5;
}
}
return false;
};

isDisrupted = function(unit){
return unit.status === UnitStatus.DISRUPTED || unit.status === UnitStatus.DISRUPTED_AND_DAMAGED;
};

isDamaged = function(unit){
return unit.status === UnitStatus.DAMAGED || unit.status === UnitStatus.DISRUPTED_AND_DAMAGED;
};

getHighlightArgsForStatus = function(status, isActive){
var color;
var highlightOver = false;
var opacity = 0.1;
switch(status){
case UnitStatus.DISRUPTED:
color = "yellow";
break;
case UnitStatus.DAMAGED:
color = "darkred";
break;
case UnitStatus.DISRUPTED_AND_DAMAGED:
color = "red";
break;
case UnitStatus.DESTROYED:
color = "black";
opacity = 0.3;
break;
}
if(isActive){
opacity = 0.5;
highlightOver = true;
}
return [color, opacity, highlightOver];
};
13 changes: 11 additions & 2 deletions lib/unit.js
Expand Up @@ -53,8 +53,8 @@ function _Unit(unitCard){
this.cardId = unitCard._id;
this.location = null;
this.used = false;
this.statuses = [];
this.pendingStatuses = [];
this.status = null;
this.pendingStatus = null;
}

UnitCard = _UnitCard;
Expand Down Expand Up @@ -99,6 +99,14 @@ function _UnitCard(options){
} else throw "unit creation: options hash missing required field: vehicleAttacks (format: [short, med, long] )";
}

CombatResults = _CombatResults;
function _CombatResults(rolls, hits, cover, status){
this.rolls = rolls;
this.hits = hits;
this.cover = cover;
this.status = status;
}

Faction = null;
(function(){
var faction = {
Expand All @@ -123,6 +131,7 @@ UnitStatus = null;
(function(){
var unitStatus = {
DISRUPTED: "Disrupted",
DISRUPTED_AND_DAMAGED: "Disrupted and Damaged",
DAMAGED: "Damaged",
DESTROYED: "Destroyed"
};
Expand Down

0 comments on commit 60047bb

Please sign in to comment.