2014-06-22 09:58:25 -07:00
|
|
|
var AISprite = function(game, x, y, key, frame) {
|
|
|
|
|
this.viewRectangle = function() {
|
|
|
|
|
var offset = [];
|
|
|
|
|
var size = [];
|
|
|
|
|
var multiplier = 1.0;
|
|
|
|
|
if ( hasState(this, STATE_ALERTED) ) {
|
|
|
|
|
multiplier = 2.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( hasState(this, STATE_FACE_LEFT) ) {
|
|
|
|
|
offset = [0, -32 * multiplier];
|
|
|
|
|
size = [-this.view_distance, 96];
|
|
|
|
|
} else if ( hasState(this, STATE_FACE_RIGHT) ) {
|
|
|
|
|
offset = [32, -32 * multiplier];
|
|
|
|
|
size = [32 + this.view_distance, 96];
|
|
|
|
|
} else if ( hasState(this, STATE_FACE_DOWN) ) {
|
|
|
|
|
offset = [-32 * multiplier, 32];
|
|
|
|
|
size = [96, this.view_distance];
|
|
|
|
|
} else if ( hasState(this, STATE_FACE_UP) ) {
|
|
|
|
|
offset = [-32 * multiplier, 0];
|
|
|
|
|
size = [96, -this.view_distance];
|
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
size[0] *= multiplier;
|
|
|
|
|
size[1] *= multiplier;
|
|
|
|
|
return positiveRectangle(this.x + offset[0],
|
|
|
|
|
this.y + offset[1],
|
|
|
|
|
size[0],
|
|
|
|
|
size[1]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.canSeeSprite = function(spr, debug) {
|
|
|
|
|
var vd = this.view_distance;
|
|
|
|
|
if ( hasState(this, STATE_FACE_LEFT) ||
|
|
|
|
|
hasState(this, STATE_FACE_UP) ) {
|
|
|
|
|
// Without this the player can stand in our view distance
|
|
|
|
|
// but as long as their left edge is 1 px out we won't see them,
|
|
|
|
|
// with this we see their near edge
|
|
|
|
|
vd = vd + 32;
|
|
|
|
|
}
|
|
|
|
|
if ( hasState(this, STATE_ALERTED) )
|
|
|
|
|
vd = vd * 2;
|
|
|
|
|
|
|
|
|
|
var distance = (new Phaser.Line(spr.x, spr.y, this.x, this.y).length);
|
|
|
|
|
if ( distance > vd ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var viewrect = this.viewRectangle();
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(viewrect) == false ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
var sprrect = positiveRectangle(spr.x, spr.y, 32, 32);
|
|
|
|
|
if ( viewrect.intersects(sprrect) || viewrect.containsRect(sprrect) ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.enableAwarenessChange = function(state) {
|
|
|
|
|
this.awareness_change_enabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.startAwarenessTimer = function() {
|
|
|
|
|
this.awareness_change_enabled = false;
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.awareness_timer) )
|
2014-06-22 09:58:25 -07:00
|
|
|
this.awareness_timer.stop();
|
|
|
|
|
this.awareness_timer = game.time.create(false);
|
|
|
|
|
this.awareness_timer.add(this.sprite_awareness_duration,
|
|
|
|
|
this.enableAwarenessChange,
|
|
|
|
|
this);
|
|
|
|
|
this.awareness_timer.start()
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-28 17:38:50 -07:00
|
|
|
this.runGlintEffect = function() {
|
|
|
|
|
if ( this.sprite_has_treasure == true ) {
|
|
|
|
|
this.glint_effect = game.state.states.game.add.sprite(
|
|
|
|
|
this.x + 16,
|
|
|
|
|
this.y + 24,
|
|
|
|
|
'glint',
|
|
|
|
|
0,
|
|
|
|
|
game.state.states.game.aiSpriteEffects
|
|
|
|
|
);
|
|
|
|
|
addAnimation(this.glint_effect, 'glint');
|
|
|
|
|
this.glint_effect.anchor.setTo(0.5, 0.5);
|
|
|
|
|
this.glint_effect.play('glint', null, false, true);
|
|
|
|
|
this.glint_timer = game.time.create(false);
|
|
|
|
|
this.glint_timer.add(game.rnd.integerInRange(5000, 15000),
|
|
|
|
|
this.runGlintEffect,
|
|
|
|
|
this);
|
|
|
|
|
tween = game.add.tween(this.glint_effect);
|
|
|
|
|
tween.to({angle: 180}, 1000, null);
|
|
|
|
|
tween.start();
|
|
|
|
|
this.glint_timer.start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 09:58:25 -07:00
|
|
|
this.setAwarenessEffect = function(state) {
|
|
|
|
|
var animkey = "";
|
|
|
|
|
|
2014-06-26 23:39:32 -07:00
|
|
|
if ( state == STATE_NONE )
|
|
|
|
|
return;
|
|
|
|
|
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( hasState(this, state) == true ) {
|
|
|
|
|
// restart the awareness timer
|
|
|
|
|
this.startAwarenessTimer();
|
|
|
|
|
return;
|
|
|
|
|
} else if ( (state == STATE_LOSTHIM) &&
|
|
|
|
|
(hasState(this, STATE_ALERTED) == false) &&
|
|
|
|
|
(hasState(this, STATE_CONCERNED) == false) ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( this.awareness_change_enabled == false &&
|
|
|
|
|
state != STATE_ALERTED ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2014-06-28 08:48:26 -07:00
|
|
|
awardPlayerScoreByState(state);
|
2014-06-26 07:05:10 -07:00
|
|
|
this.state_changed_at = new Phaser.Point(this.x, this.y);
|
2014-06-22 09:58:25 -07:00
|
|
|
this.startAwarenessTimer();
|
|
|
|
|
setAwarenessState(this, state);
|
|
|
|
|
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.awareness_effect) ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
this.awareness_effect.alive = false;
|
|
|
|
|
this.awareness_effect.destroy();
|
|
|
|
|
this.awareness_effect = null;
|
|
|
|
|
}
|
|
|
|
|
if ( state == STATE_ALERTED ) {
|
|
|
|
|
animkey = "alerted";
|
|
|
|
|
} else if ( state == STATE_CONCERNED ) {
|
|
|
|
|
animkey = "concerned";
|
|
|
|
|
} else if ( state == STATE_LOSTHIM ) {
|
|
|
|
|
if ( this.sprite_group == "townsfolk-guard" ) {
|
|
|
|
|
animkey = "angry";
|
|
|
|
|
} else {
|
|
|
|
|
animkey = "relieved";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( animkey == "" )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
this.bubble_immediate = true;
|
|
|
|
|
this.clearWordBubble();
|
|
|
|
|
this.awareness_effect = game.state.states.game.add.sprite(
|
|
|
|
|
this.x + 16,
|
|
|
|
|
this.y - 16,
|
|
|
|
|
'balloon');
|
|
|
|
|
addAnimation(this.awareness_effect, animkey);
|
|
|
|
|
this.awareness_effect.play(animkey, null, false, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.enableWordBubble = function() {
|
|
|
|
|
this.enable_word_bubble = true;
|
|
|
|
|
this.timer = game.time.create(false);
|
|
|
|
|
if ( this.bubble_immediate == true ) {
|
|
|
|
|
this.bubble_immediate = false;
|
|
|
|
|
this.setWordBubble();
|
|
|
|
|
} else {
|
|
|
|
|
var timerdelta = 10000 + (game.rnd.integerInRange(0, 20) * 1000);
|
|
|
|
|
timerev = this.timer.add(timerdelta, this.setWordBubble, this);
|
|
|
|
|
this.timer.start()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.clearWordBubble = function() {
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.bubble_text) )
|
2014-06-22 09:58:25 -07:00
|
|
|
this.clear_bubble = true;
|
|
|
|
|
this.enable_word_bubble = false;
|
|
|
|
|
this.timer = game.time.create(false);
|
|
|
|
|
timerev = this.timer.add(1000, this.enableWordBubble, this);
|
|
|
|
|
this.timer.start()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.setWordBubble = function()
|
|
|
|
|
{
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.bubble_text) ||
|
2014-06-22 09:58:25 -07:00
|
|
|
this.sprite_group == undefined ||
|
|
|
|
|
this.enable_world_bubble == false) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
aistate = this.state & ( STATE_UNAWARE | STATE_CONCERNED | STATE_ALERTED | STATE_LOSTHIM );
|
|
|
|
|
switch ( aistate ) {
|
|
|
|
|
case STATE_UNAWARE: {
|
|
|
|
|
aistate = "unaware";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case STATE_CONCERNED: {
|
|
|
|
|
aistate = "concerned";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case STATE_ALERTED: {
|
|
|
|
|
aistate = "alerted";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case STATE_LOSTHIM: {
|
|
|
|
|
aistate = "losthim";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var mylines = moonlightDialog['status'][this.sprite_group][aistate];
|
|
|
|
|
bubbleimg = game.cache.getImage('wordbubble');
|
|
|
|
|
text = mylines[game.rnd.integerInRange(0, mylines.length-1)];
|
|
|
|
|
style = {font: '14px Arial Bold', fill: '#ffffff'}
|
|
|
|
|
this.text_size = stringSize(text, style['font']);
|
|
|
|
|
this.bubble_sprite = game.add.sprite(this.x, this.y, 'wordbubble');
|
|
|
|
|
this.bubble_sprite.anchor.setTo(0.5, 1.0);
|
|
|
|
|
this.bubble_sprite.scale.x = Number((this.text_size[0] + 16) / bubbleimg.width);
|
|
|
|
|
this.bubble_sprite.scale.y = Number((this.text_size[1] + 16) / bubbleimg.height);
|
|
|
|
|
this.bubble_text = game.add.text(this.x, this.y, text, style);
|
|
|
|
|
this.snap_bubble_position();
|
|
|
|
|
|
|
|
|
|
this.timer = game.time.create(false);
|
|
|
|
|
timerev = this.timer.add(5000, this.clearWordBubble, this);
|
|
|
|
|
this.timer.start()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.snap_bubble_position = function()
|
|
|
|
|
{
|
|
|
|
|
this.bubble_sprite.x = this.x + 16;
|
|
|
|
|
this.bubble_sprite.y = this.y;
|
|
|
|
|
var tx = this.bubble_sprite.x - (this.text_size[0]/2);
|
|
|
|
|
var ty = this.bubble_sprite.y - (this.bubble_sprite.height) + 8;
|
|
|
|
|
this.bubble_text.position.x = tx;
|
|
|
|
|
this.bubble_text.position.y = ty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.blocked = function() {
|
|
|
|
|
function f() {
|
|
|
|
|
if ( hasState(this, STATE_FACE_LEFT) &&
|
|
|
|
|
this.body.blocked.left == true )
|
|
|
|
|
return true;
|
|
|
|
|
if ( hasState(this, STATE_FACE_RIGHT) &&
|
|
|
|
|
this.body.blocked.right == true )
|
|
|
|
|
return true;
|
|
|
|
|
if ( hasState(this, STATE_FACE_DOWN) &&
|
|
|
|
|
this.body.blocked.down == true )
|
|
|
|
|
return true;
|
|
|
|
|
if ( hasState(this, STATE_FACE_UP) &&
|
|
|
|
|
this.body.blocked.up == true )
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return f();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.path_purge = function() {
|
|
|
|
|
this.path = [];
|
|
|
|
|
this.path_index = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 10:48:00 -07:00
|
|
|
this.path_set = function(target, force, maxsteps, useNearestWalkable) {
|
|
|
|
|
useNearestWalkable = (typeof useNearestWalkable == 'undefined' ? true : useNearestWalkable);
|
2014-06-22 11:57:58 -07:00
|
|
|
maxsteps = (typeof maxsteps == 'undefined' ? this.path_maximum_steps : maxsteps);
|
|
|
|
|
force = ( typeof force == 'undefined' ? false : force );
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( force == false &&
|
|
|
|
|
this.path.length > 0 &&
|
|
|
|
|
this.path_index < this.path.length ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
this.path_purge();
|
2014-06-22 10:48:00 -07:00
|
|
|
if ( useNearestWalkable == true ) {
|
|
|
|
|
var pos = nearestWalkableTile(target);
|
|
|
|
|
} else {
|
|
|
|
|
var pos = [parseInt(target.x/32), parseInt(target.y/32)];
|
|
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
tpath = pathfinder.findPath(
|
|
|
|
|
parseInt(this.x/32),
|
|
|
|
|
parseInt(this.y/32),
|
|
|
|
|
pos[0],
|
|
|
|
|
pos[1],
|
2014-06-22 13:26:29 -07:00
|
|
|
gridWithAISprites()
|
2014-06-22 09:58:25 -07:00
|
|
|
);
|
|
|
|
|
prevpoint = [this.x, this.y];
|
|
|
|
|
for ( var i = 0 ; i < Math.min(maxsteps, tpath.length) ; i++ ) {
|
|
|
|
|
if ( (prevpoint[0]+prevpoint[1]) == ((tpath[i][0]*32)+(tpath[i][1]*32)) )
|
|
|
|
|
continue;
|
|
|
|
|
this.path.push(new Phaser.Line(prevpoint[0], prevpoint[1],
|
|
|
|
|
tpath[i][0]*32, tpath[i][1]*32));
|
|
|
|
|
prevpoint = [tpath[i][0]*32, tpath[i][1]*32];
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.path_tween_start = function(movingstate)
|
|
|
|
|
{
|
2014-06-26 07:39:52 -07:00
|
|
|
var movingstate = (typeof movingstate == 'undefined' ? (STATE_MOVING | STATE_RUNNING) : movingstate);
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_tweens = [];
|
|
|
|
|
prevpos = [this.x, this.y]
|
|
|
|
|
for ( var i = 0;
|
|
|
|
|
i < this.path.length ;
|
|
|
|
|
i++ ) {
|
|
|
|
|
pl = this.path[i];
|
2014-06-26 07:39:52 -07:00
|
|
|
var stepstate = movingstate;
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( pl.end.x < prevpos[0]) {
|
2014-06-26 07:39:52 -07:00
|
|
|
stepstate = stepstate | STATE_FACE_LEFT;
|
2014-06-22 09:58:25 -07:00
|
|
|
} else if ( pl.end.x > prevpos[0] ) {
|
2014-06-26 07:39:52 -07:00
|
|
|
stepstate = stepstate | STATE_FACE_RIGHT;
|
2014-06-22 09:58:25 -07:00
|
|
|
}
|
|
|
|
|
if ( pl.end.y < prevpos[1] ) {
|
2014-06-26 07:39:52 -07:00
|
|
|
stepstate = stepstate | STATE_FACE_UP;
|
2014-06-22 09:58:25 -07:00
|
|
|
} else if ( pl.end.y > prevpos[1] ) {
|
2014-06-26 07:39:52 -07:00
|
|
|
stepstate = stepstate | STATE_FACE_DOWN;
|
2014-06-22 09:58:25 -07:00
|
|
|
}
|
|
|
|
|
prevpos = [pl.end.x, pl.end.y];
|
|
|
|
|
tween = game.add.tween(this);
|
2014-06-26 07:39:52 -07:00
|
|
|
tween.stepstate = stepstate;
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_tweens.push(tween);
|
2014-06-26 07:39:52 -07:00
|
|
|
var tweenspeed = TWEEN_DURATION_PERPIXEL_WALKING;
|
|
|
|
|
if ( (stepstate & STATE_RUNNING) == STATE_RUNNING )
|
|
|
|
|
tweenspeed = TWEEN_DURATION_PERPIXEL_RUNNING;
|
2014-06-22 09:58:25 -07:00
|
|
|
tween.to(
|
|
|
|
|
{x: (pl.end.x), y: (pl.end.y)},
|
2014-06-26 07:39:52 -07:00
|
|
|
(tweenspeed * pl.length),
|
2014-06-22 09:58:25 -07:00
|
|
|
null);
|
|
|
|
|
tween.onStart.add(function() {
|
2014-06-26 07:39:52 -07:00
|
|
|
setMovingState(this._object, this.stepstate);
|
2014-06-26 07:05:10 -07:00
|
|
|
this._object.animations.play(getMovingAnimationName(this._object));
|
2014-06-22 09:58:25 -07:00
|
|
|
}, tween);
|
|
|
|
|
tween.onComplete.add(function() {
|
|
|
|
|
this._object.path_index += 1;
|
|
|
|
|
setMovingState(this._object, getFaceState(this._object));
|
2014-06-26 07:05:10 -07:00
|
|
|
this._object.animations.play(getMovingAnimationName(this._object));
|
2014-06-22 09:58:25 -07:00
|
|
|
this._object.animations.stop();
|
|
|
|
|
}, tween);
|
|
|
|
|
if ( i > 0 ) {
|
2014-06-26 07:39:52 -07:00
|
|
|
this.path_tweens[i-1].onComplete.add(tween.start,
|
2014-06-22 09:58:25 -07:00
|
|
|
tween);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ( this.path_tweens.length > 0 )
|
|
|
|
|
this.path_tweens[0].start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.path_tween_stop = function()
|
|
|
|
|
{
|
|
|
|
|
this.path_tweens.forEach(function(x) {
|
|
|
|
|
x.stop();
|
|
|
|
|
game.tweens.remove(x);
|
|
|
|
|
}, this);
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 13:50:50 -07:00
|
|
|
this.turnRandomDirection = function() {
|
|
|
|
|
var directions = [STATE_FACE_DOWN, STATE_FACE_LEFT,
|
|
|
|
|
STATE_FACE_RIGHT, STATE_FACE_UP];
|
2014-06-22 13:54:53 -07:00
|
|
|
setMovingState(this, directions[game.rnd.integerInRange(0, 3)]);
|
2014-06-22 13:50:50 -07:00
|
|
|
this.animations.stop();
|
2014-06-26 07:05:10 -07:00
|
|
|
this.animations.play(getMovingAnimationName(this));
|
2014-06-22 13:50:50 -07:00
|
|
|
this.animations.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 09:58:25 -07:00
|
|
|
this.turnUnseenDirection = function() {
|
|
|
|
|
if ( this.seen_directions.length >= 4 )
|
|
|
|
|
this.seen_directions = [];
|
|
|
|
|
var directions = [STATE_FACE_DOWN, STATE_FACE_LEFT,
|
|
|
|
|
STATE_FACE_RIGHT, STATE_FACE_UP];
|
|
|
|
|
var newdirection = directions[game.rnd.integerInRange(0, 3)];
|
|
|
|
|
while ( this.seen_directions.indexOf(newdirection) !== -1 ) {
|
|
|
|
|
newdirection = directions[game.rnd.integerInRange(0, 3)];
|
|
|
|
|
}
|
2014-06-26 23:39:32 -07:00
|
|
|
this.seen_directions.push(newdirection);
|
2014-06-22 09:58:25 -07:00
|
|
|
setMovingState(this, newdirection);
|
|
|
|
|
this.animations.stop();
|
2014-06-26 07:05:10 -07:00
|
|
|
this.animations.play(getMovingAnimationName(this));
|
2014-06-22 09:58:25 -07:00
|
|
|
this.animations.stop();
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.rotation_timer) ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
this.rotation_timer.stop();
|
|
|
|
|
this.rotation_timer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 10:52:48 -07:00
|
|
|
this.chasetarget = function(target, alertedState, movingstate, visual, maxsteps, useNearestWalkable)
|
2014-06-22 09:58:25 -07:00
|
|
|
{
|
2014-06-22 11:57:58 -07:00
|
|
|
alertedState = (typeof alertedState == 'undefined' ? STATE_ALERTED : alertedState);
|
|
|
|
|
visual = (typeof visual == 'undefined' ? false : visual);
|
|
|
|
|
movingstate = (typeof alertedState == 'undefined' ? STATE_NONE : movingstate);
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( game.physics.arcade.collide(this, target) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if ( this.path_index >= this.path.length ) {
|
|
|
|
|
this.path_tween_stop();
|
2014-06-22 16:45:27 -07:00
|
|
|
if ( ((visual == true) && (this.canSeeSprite(target, false) == true )) ||
|
|
|
|
|
(visual == false)) {
|
2014-06-22 09:58:25 -07:00
|
|
|
this.setAwarenessEffect(alertedState);
|
2014-06-22 10:52:48 -07:00
|
|
|
this.path_set(target, true, maxsteps, useNearestWalkable);
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_tween_start(movingstate);
|
|
|
|
|
} else {
|
2014-06-26 23:39:32 -07:00
|
|
|
this.startTimedRotation();
|
2014-06-22 09:58:25 -07:00
|
|
|
}
|
|
|
|
|
} else {
|
2014-06-22 10:52:48 -07:00
|
|
|
if ( this.path_set(target, this.blocked(true), maxsteps, useNearestWalkable) == true ) {
|
2014-06-22 12:21:52 -07:00
|
|
|
if ( (visual == true) && (this.canSeeSprite(target, false) == false )) {
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_purge();
|
|
|
|
|
this.path_tween_stop();
|
|
|
|
|
} else {
|
|
|
|
|
this.setAwarenessEffect(alertedState);
|
|
|
|
|
this.path_tween_start(movingstate);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.action_chaseplayer = function()
|
|
|
|
|
{
|
2014-06-22 16:52:12 -07:00
|
|
|
if ( this.path.length > 0 &&
|
2014-06-22 14:03:43 -07:00
|
|
|
this.path_index >= this.path.length &&
|
|
|
|
|
hasState(this, STATE_RUNNINGTOREPORT) ) {
|
|
|
|
|
delState(this, STATE_RUNNINGTOREPORT);
|
|
|
|
|
this.target = player;
|
|
|
|
|
}
|
|
|
|
|
if ( hasState(this, STATE_RUNNINGTOREPORT) ) {
|
|
|
|
|
this.chasetarget(this.target,
|
|
|
|
|
STATE_ALERTED,
|
|
|
|
|
STATE_MOVING | STATE_RUNNING,
|
2014-06-22 14:05:55 -07:00
|
|
|
false,
|
2014-06-22 14:03:43 -07:00
|
|
|
1000,
|
|
|
|
|
false);
|
|
|
|
|
} else {
|
|
|
|
|
this.chasetarget(player,
|
|
|
|
|
STATE_ALERTED,
|
|
|
|
|
STATE_MOVING | STATE_RUNNING,
|
|
|
|
|
true,
|
|
|
|
|
undefined,
|
|
|
|
|
false);
|
|
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.action_reportplayer = function()
|
|
|
|
|
{
|
|
|
|
|
if ( (this.path.length < 1) || this.path_index >= this.path.length) {
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.target) == false &&
|
2014-06-22 11:51:21 -07:00
|
|
|
hasState(this, STATE_RUNNINGTOLIGHT) == false ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
var aiSprites = game.state.states.game.aiSprites;
|
|
|
|
|
this.target = nearestInGroup(this, aiSprites, "townsfolk-guard");
|
2014-06-22 11:51:21 -07:00
|
|
|
} else if ( hasState(this, STATE_RUNNINGTOLIGHT) == false ) {
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.target) ) {
|
|
|
|
|
if ( isSet(this.target.rotation_timer) ) {
|
|
|
|
|
this.target.rotation_timer.stop();
|
|
|
|
|
this.target.rotation_timer = null;
|
|
|
|
|
}
|
|
|
|
|
if ( isSet(this.target.sprite_group) ) {
|
|
|
|
|
this.target.path_purge();
|
|
|
|
|
this.target.setAwarenessEffect(STATE_ALERTED);
|
|
|
|
|
this.target.target = this.lastSawPlayerAt;
|
2014-06-26 23:39:32 -07:00
|
|
|
this.target.lastSawPlayerAt = this.lastSawPlayerAt;
|
2014-06-26 07:15:38 -07:00
|
|
|
addState(this.target, STATE_RUNNINGTOREPORT);
|
|
|
|
|
}
|
2014-06-22 16:52:12 -07:00
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_tween_stop();
|
|
|
|
|
this.path_purge();
|
|
|
|
|
var staticLights = game.state.states.game.staticLights;
|
|
|
|
|
this.target = nearestInGroup(this, staticLights);
|
2014-06-22 11:51:21 -07:00
|
|
|
addState(this, STATE_RUNNINGTOLIGHT);
|
|
|
|
|
} else {
|
2014-06-22 11:53:01 -07:00
|
|
|
this.awareness_timer.stop();
|
|
|
|
|
this.awareness_change_enabled = true;
|
|
|
|
|
this.setAwarenessEffect(STATE_LOSTHIM);
|
2014-06-26 23:39:32 -07:00
|
|
|
setMovingState(this, STATE_NONE);
|
2014-06-22 13:50:50 -07:00
|
|
|
this.turnRandomDirection();
|
2014-06-22 13:29:45 -07:00
|
|
|
this.target = null;
|
2014-06-26 23:39:32 -07:00
|
|
|
this.path_purge();
|
2014-06-22 13:32:23 -07:00
|
|
|
delState(this, STATE_RUNNINGTOLIGHT);
|
2014-06-22 11:51:21 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.target) ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
this.chasetarget(this.target,
|
|
|
|
|
STATE_ALERTED,
|
|
|
|
|
STATE_MOVING | STATE_RUNNING,
|
|
|
|
|
false,
|
|
|
|
|
1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-26 23:39:32 -07:00
|
|
|
this.random_huntable_target = function(hunt_radius) {
|
|
|
|
|
hunt_radius = (typeof hunt_radius == 'undefined' ? this.hunt_radius : hunt_radius);
|
|
|
|
|
var curmap = game.state.states.game.map;
|
|
|
|
|
var intgridx = parseInt(this.state_changed_at.x/32);
|
|
|
|
|
var intgridy = parseInt(this.state_changed_at.y/32);
|
|
|
|
|
var boundleft = Math.max(0, (intgridx - hunt_radius));
|
|
|
|
|
var boundtop = Math.max(0, (intgridy - hunt_radius));
|
|
|
|
|
var boundright = Math.min(curmap.width, (intgridx + hunt_radius));
|
|
|
|
|
var boundbottom = Math.min(curmap.height, (intgridy + hunt_radius));
|
|
|
|
|
var destx = game.rnd.integerInRange(boundleft, boundright);
|
|
|
|
|
var desty = game.rnd.integerInRange(boundtop, boundbottom);
|
|
|
|
|
return new Phaser.Sprite(game, destx*32, desty*32, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.startTimedRotation = function() {
|
|
|
|
|
var rotation_times = {};
|
|
|
|
|
rotation_times["" + STATE_UNAWARE] = 5000;
|
|
|
|
|
rotation_times["" + STATE_CONCERNED] = 1000;
|
|
|
|
|
rotation_times["" + STATE_ALERTED] = 250;
|
|
|
|
|
rotation_times["" + STATE_LOSTHIM] = 1000;
|
|
|
|
|
if ( isSet(this.rotation_timer) == false ) {
|
|
|
|
|
this.rotation_timer = game.time.create(false);
|
|
|
|
|
timerev = this.rotation_timer.add(
|
|
|
|
|
rotation_times["" + getAwarenessState(this)],
|
|
|
|
|
this.turnUnseenDirection,
|
|
|
|
|
this);
|
|
|
|
|
this.rotation_timer.start()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-22 09:58:25 -07:00
|
|
|
this.action_huntplayer = function()
|
|
|
|
|
{
|
2014-06-26 23:39:32 -07:00
|
|
|
if ( hasState(this, STATE_LOOKINGFORTARGET) == false &&
|
|
|
|
|
this.path.length < 1 ) {
|
|
|
|
|
this.target = this.random_huntable_target()
|
|
|
|
|
} else if ( hasState(this, STATE_LOOKINGFORTARGET) ) {
|
|
|
|
|
if ( this.seen_directions.length < 4 ) {
|
|
|
|
|
this.startTimedRotation();
|
|
|
|
|
} else {
|
|
|
|
|
this.seen_directions = [];
|
|
|
|
|
delState(this, STATE_LOOKINGFORTARGET);
|
|
|
|
|
this.target = this.random_huntable_target()
|
|
|
|
|
}
|
|
|
|
|
} else if ( this.path.length > 0 &&
|
|
|
|
|
this.path_index >= this.path.length ) {
|
|
|
|
|
this.path_tween_stop();
|
|
|
|
|
setMovingState(this, getFaceState(this));
|
|
|
|
|
setSpriteMovement(this);
|
|
|
|
|
this.target = null;
|
|
|
|
|
addState(this, STATE_LOOKINGFORTARGET);
|
|
|
|
|
}
|
2014-06-26 07:54:27 -07:00
|
|
|
if ( isSet(this.target) ) {
|
|
|
|
|
this.chasetarget(this.target,
|
|
|
|
|
STATE_NONE,
|
|
|
|
|
STATE_MOVING,
|
|
|
|
|
false
|
|
|
|
|
);
|
|
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.action_wander = function()
|
|
|
|
|
{
|
|
|
|
|
if ( this.sprite_canmove == false) {
|
2014-06-26 23:39:32 -07:00
|
|
|
if ( this.x !== this.origin.x ||
|
|
|
|
|
this.y !== this.origin.y ) {
|
|
|
|
|
this.chasetarget(this.origin,
|
|
|
|
|
STATE_NONE,
|
|
|
|
|
STATE_MOVING,
|
2014-06-27 18:04:34 -07:00
|
|
|
false);
|
|
|
|
|
} else {
|
|
|
|
|
setMovingState(this, faceStateFromString(this.sprite_facing));
|
|
|
|
|
this.animations.stop();
|
|
|
|
|
this.animations.play(getMovingAnimationName(this));
|
|
|
|
|
this.animations.stop();
|
2014-06-26 23:39:32 -07:00
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ( game.rnd.integerInRange(0, 100) < 95 )
|
|
|
|
|
return;
|
|
|
|
|
this.turnUnseenDirection();
|
|
|
|
|
addState(this, STATE_MOVING);
|
|
|
|
|
setSpriteMovement(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.update = function()
|
|
|
|
|
{
|
|
|
|
|
if ( this.ready_to_update == false )
|
|
|
|
|
return;
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.awareness_effect) ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( this.awareness_effect.alive == false ) {
|
|
|
|
|
this.awareness_effect.destroy();
|
|
|
|
|
this.awareness_effect = null;
|
|
|
|
|
} else {
|
|
|
|
|
this.awareness_effect.x = this.x + 16;
|
|
|
|
|
this.awareness_effect.y = this.y - 16;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-06-28 17:38:50 -07:00
|
|
|
if ( isSet(this.glint_effect) ) {
|
|
|
|
|
if ( this.glint_effect.alive == true ) {
|
|
|
|
|
this.glint_effect.x = this.x + 16;
|
|
|
|
|
this.glint_effect.y = this.y + 24;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.bubble_text) ) {
|
2014-06-22 09:58:25 -07:00
|
|
|
if ( this.clear_bubble == true ) {
|
|
|
|
|
this.bubble_text.destroy();
|
|
|
|
|
this.bubble_sprite.destroy();
|
|
|
|
|
this.bubble_text = null;
|
|
|
|
|
this.bubble_sprite = null;
|
|
|
|
|
this.clear_bubble = false;
|
|
|
|
|
} else {
|
|
|
|
|
this.snap_bubble_position();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( hasState(this, STATE_ALERTED) ) {
|
|
|
|
|
if ( this.sprite_group == "townsfolk-guard" ) {
|
|
|
|
|
this.action_chaseplayer();
|
|
|
|
|
} else {
|
|
|
|
|
this.action_reportplayer();
|
|
|
|
|
}
|
|
|
|
|
} else if ( hasAnyState(this, [STATE_CONCERNED, STATE_LOSTHIM]) ) {
|
|
|
|
|
this.action_huntplayer();
|
|
|
|
|
} else {
|
|
|
|
|
this.action_wander();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.update_new_values = function() {
|
2014-06-26 07:15:38 -07:00
|
|
|
if ( isSet(this.timer) )
|
2014-06-22 09:58:25 -07:00
|
|
|
this.timer.stop();
|
|
|
|
|
this.animations.destroy();
|
|
|
|
|
this.clearWordBubble();
|
|
|
|
|
this.state = STATE_UNAWARE;
|
2014-06-26 07:05:10 -07:00
|
|
|
this.state_changed_at = new Phaser.Point(this.x, this.y);
|
2014-06-26 07:54:27 -07:00
|
|
|
this.hunt_radius = parseInt(this.hunt_radius);
|
2014-06-22 09:58:25 -07:00
|
|
|
this.sprite_can_see_lightmeter = Number(this.sprite_can_see_lightmeter);
|
|
|
|
|
this.sprite_canmove = parseBoolean(this.sprite_canmove);
|
|
|
|
|
this.sprite_awareness_duration = parseInt(this.sprite_awareness_duration);
|
|
|
|
|
this.collide_with_player = parseBoolean(this.collide_with_player);
|
|
|
|
|
this.collide_with_map = parseBoolean(this.collide_with_map);
|
|
|
|
|
this.carries_light = parseBoolean(this.carries_light);
|
2014-06-28 17:38:50 -07:00
|
|
|
this.sprite_has_treasure = parseBoolean(this.sprite_has_treasure);
|
|
|
|
|
if ( this.sprite_has_treasure ) {
|
|
|
|
|
this.treasure = getRandomTreasure();
|
|
|
|
|
}
|
2014-06-22 09:58:25 -07:00
|
|
|
|
|
|
|
|
this.path_maximum_steps = parseInt(this.path_maximum_steps);
|
|
|
|
|
this.loadTexture(this.sprite_name, 0);
|
|
|
|
|
addAnimation(this, 'bipedwalkleft');
|
|
|
|
|
addAnimation(this, 'bipedwalkright');
|
|
|
|
|
addAnimation(this, 'bipedwalkup');
|
|
|
|
|
addAnimation(this, 'bipedwalkdown');
|
|
|
|
|
addAnimation(this, 'bipedrunleft');
|
|
|
|
|
addAnimation(this, 'bipedrunright');
|
|
|
|
|
addAnimation(this, 'bipedrunup');
|
|
|
|
|
addAnimation(this, 'bipedrundown');
|
2014-06-27 18:04:34 -07:00
|
|
|
setMovingState(this, faceStateFromString(this.sprite_facing));
|
2014-06-22 09:58:25 -07:00
|
|
|
setSpriteMovement(this);
|
|
|
|
|
this.ready_to_update = true;
|
2014-06-28 17:38:50 -07:00
|
|
|
this.runGlintEffect();
|
2014-06-22 09:58:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var spritenames_by_type = [
|
|
|
|
|
'townsfolk-male-1',
|
|
|
|
|
'townsfolk-male-2',
|
|
|
|
|
'townsfolk-male-3',
|
|
|
|
|
'townsfolk-male-4',
|
|
|
|
|
'townsfolk-female-1',
|
|
|
|
|
'townsfolk-female-2',
|
|
|
|
|
'townsfolk-female-3',
|
|
|
|
|
'townsfolk-female-4',
|
|
|
|
|
'townsfolk-guard-1',
|
|
|
|
|
'townsfolk-guard-2'
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
this.ready_to_update = false;
|
|
|
|
|
Phaser.Sprite.call(this, game, x, y, null);
|
|
|
|
|
game.physics.arcade.enable(this);
|
|
|
|
|
this.body.immovable = true;
|
|
|
|
|
pathfinder_grid = [];
|
2014-06-27 18:04:34 -07:00
|
|
|
this.sprite_facing = "down";
|
2014-06-22 09:58:25 -07:00
|
|
|
this.walkables = [];
|
|
|
|
|
this.path = [];
|
2014-06-26 07:05:10 -07:00
|
|
|
this.state_changed_at = new Phaser.Point(this.x, this.y);
|
2014-06-22 09:58:25 -07:00
|
|
|
this.target = null;
|
2014-06-26 07:54:27 -07:00
|
|
|
this.hunt_radius = 5;
|
2014-06-22 09:58:25 -07:00
|
|
|
this.path_tweens = [];
|
|
|
|
|
this.path_maximum_steps = 4;
|
|
|
|
|
this.awareness_change_enabled = true;
|
|
|
|
|
this.lightmeter = 1.0;
|
|
|
|
|
this.sprite_can_see_lightmeter = 0.3;
|
|
|
|
|
this.awareness_effect = null;
|
|
|
|
|
this.awareness_timer = null;
|
2014-06-28 17:38:50 -07:00
|
|
|
this.glint_effect = null;
|
|
|
|
|
this.glint_timer = null;
|
2014-06-22 09:58:25 -07:00
|
|
|
this.lastSawPlayerAt = null;
|
|
|
|
|
this.seen_directions = [];
|
2014-06-26 23:39:32 -07:00
|
|
|
this.sprite_awareness_duration = 30000;
|
2014-06-22 09:58:25 -07:00
|
|
|
this.sprite_canmove = 'true';
|
|
|
|
|
this.collide_with_player = 'true';
|
|
|
|
|
this.collide_with_map = 'true';
|
|
|
|
|
this.carries_light = 'false';
|
|
|
|
|
this.view_distance = 32 * 5;
|
|
|
|
|
this.timer = null;
|
|
|
|
|
this.rotation_timer = null;
|
2014-06-27 18:04:34 -07:00
|
|
|
this.origin = new Phaser.Point(x, y);
|
2014-06-28 17:38:50 -07:00
|
|
|
this.sprite_has_treasure = [true, false][game.rnd.integerInRange(0, 1)];
|
2014-06-22 09:58:25 -07:00
|
|
|
this.bubble_immediate = false;
|
|
|
|
|
this.bubble_text = null;
|
|
|
|
|
this.enable_word_bubble = false;
|
|
|
|
|
this.body.collideWorldBounds = true;
|
|
|
|
|
this.sprite_name = "townsfolk-male-1";
|
|
|
|
|
this.sprite_group = "townsfolk-male";
|
|
|
|
|
this.update_new_values();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AISprite.prototype = Object.create(Phaser.Sprite.prototype);
|
|
|
|
|
AISprite.prototype.constructor = AISprite;
|