123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 |
- /*
- * ===========================================================================
- *
- * Wolf3D Browser Version GPL Source Code
- * Copyright (C) 2012 id Software LLC, a ZeniMax Media company.
- *
- * This file is part of the Wolf3D Browser Version GPL Source Code ("Wolf3D Browser Source Code").
- *
- * Wolf3D Browser Source Code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * Wolf3D Browser Source Code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License version 2
- * along with Wolf3D Browser Source Code. If not, see <http://www.gnu.org/licenses/>.
- *
- * If you have questions concerning this license, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- *
- * ===========================================================================
- */
- /**
- * @namespace
- * @description Artificial intelligence
- */
- Wolf.ActorAI = (function() {
- var dsounds = [
- "sfx/025.wav",
- "sfx/026.wav",
- "sfx/086.wav",
- "sfx/088.wav",
- "sfx/105.wav",
- "sfx/107.wav",
- "sfx/109.wav"
- ];
- /**
- * @description Initiate death scream sound effect.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- */
- function deathScream(self, game) {
- var pos = game.player.position;
-
- switch (self.type) {
- case Wolf.en_mutant:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/037.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_guard:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, dsounds[Wolf.Random.rnd() % 6], 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_officer:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/074.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_ss:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/046.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_dog:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/035.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_boss:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/019.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_schabbs:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/061.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_fake:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/069.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_mecha:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/084.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_hitler:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/044.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_gretel:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/115.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_gift:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/091.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- case Wolf.en_fat:
- Wolf.Sound.startSound(pos, self, 1, Wolf.CHAN_VOICE, "sfx/119.wav", 1, Wolf.ATTN_NORM, 0);
- break;
- }
- }
- /* Hitler */
-
- /**
- * @description Play Mecha sound.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- */
- function mechaSound(self, game) {
- if (game.level.state.areabyplayer[self.areanumber]) {
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/080.wav", 1, Wolf.ATTN_NORM, 0);
- }
- }
-
- /**
- * @description Play Slurpie sound.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- */
- function slurpie(self, game) {
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "lsfx/061.wav", 1, Wolf.ATTN_NORM, 0);
- }
- /**
- * @description Spawn new actor, when Mecha Hitler is dead.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- */
- function hitlerMorph(self, game) {
- var hitpoints = [500, 700, 800, 900],
- level = game.level,
- hitler;
- hitler = Wolf.Actors.getNewActor(level);
- if(!hitler) {
- return;
- }
- hitler.x = self.x;
- hitler.y = self.y;
- hitler.distance = self.distance;
- hitler.tile.x = self.tile.x;
- hitler.tile.y = self.tile.y;
- hitler.angle = self.angle;
- hitler.dir = self.dir;
- hitler.health = hitpoints[game.skill];
- hitler.areanumber = self.areanumber;
- hitler.state = Wolf.st_chase1;
- hitler.type = Wolf.en_hitler;
- hitler.speed = Wolf.SPDPATROL * 5;
- hitler.ticcount = 0;
- hitler.flags = self.flags | Wolf.FL_SHOOTABLE;
- hitler.sprite = Wolf.Sprites.getNewSprite(level);
- }
-
- /* Angel of Death */
-
- var angel_temp = 0;
- /**
- * @description Play Angel of Death Breathing sound.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- */
- function breathing(self) {
- Wolf.Sound.startSound(null, null, 1, Wolf.CHAN_VOICE, "lsfx/080.wav", 1, Wolf.ATTN_NORM, 0);
- }
-
- /**
- * @description Reset Angel of Death attack counter
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- */
- function startAttack(self) {
- angel_temp = 0;
- }
-
- /**
- * @description Angel of Death AI.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- */
- function relaunch(self) {
- if (++angel_temp == 3) {
- Wolf.Actors.stateChange(self, Wolf.st_pain);
- return;
- }
- if (Wolf.Random.rnd() & 1) {
- Wolf.Actors.stateChange(self, Wolf.st_chase1);
- return;
- }
- }
- /**
- * @description Victory - start intermission.
- * @memberOf Wolf.ActorAI
- */
- function victory(game) {
- Wolf.Game.startIntermission(game);
- }
-
- /**
- * @description Entity is dormant state.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- */
- function dormant(self, game) {
- var level = game.level,
- player = game.player,
- deltax,
- deltay,
- xl, xh, yl, yh,
- x, y, n,
- moveok = false;
- deltax = self.x - player.position.x;
- deltay = self.y - player.position.y;
-
- if (deltax < -Wolf.MINACTORDIST || deltax > Wolf.MINACTORDIST) {
- moveok = true;
- } else if(deltay < -Wolf.MINACTORDIST || deltay > Wolf.MINACTORDIST) {
- moveok = true;
- }
-
- if (!moveok) {
- return;
- }
- // moveok:
- xl = (self.x - Wolf.MINDIST) >> Wolf.TILESHIFT;
- xh = (self.x + Wolf.MINDIST) >> Wolf.TILESHIFT;
- yl = (self.y - Wolf.MINDIST) >> Wolf.TILESHIFT;
- yh = (self.y + Wolf.MINDIST) >> Wolf.TILESHIFT;
- for(y = yl; y <= yh ; ++y ) {
- for(x = xl;x <= xh;++x) {
- if (level.tileMap[x][y] & Wolf.SOLID_TILE) {
- return;
- }
- for (n=0;n<level.state.numGuards;++n) {
- if (level.state.guards[n].state >= Wolf.st_die1) {
- continue;
- }
- if (level.state.guards[n].tile.x == x && level.state.guards[n].tile.y == y) {
- return; // another guard in path
- }
- }
- }
- }
- self.flags |= Wolf.FL_AMBUSH | Wolf.FL_SHOOTABLE;
- self.flags &= ~Wolf.FL_ATTACKMODE;
- self.dir = Wolf.Math.dir8_nodir;
- Wolf.Actors.stateChange(self, Wolf.st_path1);
- }
- /**
- * @description Death cam animation.
- * Tthe DeathCam feature isn't implimented, but we want to
- * give the animation time to play before declaring victory.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- */
- function startDeathCam(game, self) {
- self.playstate = Wolf.ex_complete;
- setTimeout(function() {
- Wolf.Game.startIntermission(game);
- }, 5000);
- }
-
- /**
- * @description Rockets emmit smoke.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} level The level object.
- */
- function smoke(self, game) {
- var level = game.level,
- smokeEnt = Wolf.Actors.getNewActor(level);
-
- if (!smokeEnt) {
- return;
- }
- smokeEnt.x = self.x;
- smokeEnt.y = self.y;
- smokeEnt.tile.x = self.tile.x;
- smokeEnt.tile.y = self.tile.y;
- smokeEnt.state = Wolf.st_die1;
- smokeEnt.type = (self.type == Wolf.en_hrocket) ? Wolf.en_hsmoke : Wolf.en_smoke;
- smokeEnt.ticcount = 6;
- smokeEnt.flags = Wolf.FL_NEVERMARK;
- smokeEnt.sprite = Wolf.Sprites.getNewSprite(level);
- }
-
- /**
- * @description Puts an actor into attack mode and possibly reverses the direction if the player is behind it.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- */
- function firstSighting(self, game) {
- switch (self.type) {
- case Wolf.en_guard:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/001.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_officer:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/071.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 5; // go faster when chasing player
- break;
- case Wolf.en_mutant:
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_ss:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/015.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 4; // go faster when chasing player
- break;
- case Wolf.en_dog:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/002.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 2; // go faster when chasing player
- break;
- case Wolf.en_boss:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/017.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed = Wolf.SPDPATROL * 3; // go faster when chasing player
- break;
- case Wolf.en_gretel:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/112.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_gift:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/096.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_fat:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/102.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_schabbs:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/065.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_fake:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/054.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_mecha:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/040.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 3; // go faster when chasing player
- break;
- case Wolf.en_hitler:
- Wolf.Sound.startSound(game.player.position, self, 1, Wolf.CHAN_VOICE, "sfx/040.wav", 1, Wolf.ATTN_NORM, 0);
- self.speed *= 5; // go faster when chasing player
- break;
- case Wolf.en_blinky:
- case Wolf.en_clyde:
- case Wolf.en_pinky:
- case Wolf.en_inky:
- self.speed *= 2; // go faster when chasing player
- break;
- default:
- return;
- }
- Wolf.Actors.stateChange(self, Wolf.st_chase1);
-
- if (self.waitfordoorx) {
- self.waitfordoorx = self.waitfordoory = 0; // ignore the door opening command
- }
- self.dir = Wolf.Math.dir8_nodir;
- self.flags |= Wolf.FL_ATTACKMODE | Wolf.FL_FIRSTATTACK;
- }
- /**
- * @description Called when the player succesfully hits an enemy.
- * Does damage points to enemy ob, either putting it into a stun frame or killing it.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- * @param {object} player The player object.
- * @param {number} damage The number of damage points.
- */
- function damageActor(self, game, player, damage) {
- player.madenoise = 1;
- // do double damage if shooting a non attack mode actor
- if (!(self.flags & Wolf.FL_ATTACKMODE)) {
- damage <<= 1;
- }
- self.health -= damage;
- if (self.health <= 0) {
- killActor(self, game, player);
- } else {
- if (!(self.flags & Wolf.FL_ATTACKMODE) ) {
- firstSighting(self, game); // put into combat mode
- }
- switch (self.type) { // dogs only have one hit point
- case Wolf.en_guard:
- case Wolf.en_officer:
- case Wolf.en_mutant:
- case Wolf.en_ss:
- if (self.health & 1) {
- Wolf.Actors.stateChange(self, Wolf.st_pain);
- } else {
- Wolf.Actors.stateChange(self, Wolf.st_pain1);
- }
- break;
- }
- }
- }
-
-
- /**
- * @description Actor has been killed, so give points and spawn powerups.
- * @memberOf Wolf.ActorAI
- * @param {object} self The enemy actor object.
- * @param {object} game The game object.
- * @param {object} player The player object.
- */
- function killActor(self, game, player) {
- var level = game.level,
- tilex = self.tile.x = self.x >> Wolf.TILESHIFT; // drop item on center,
- tiley = self.tile.y = self.y >> Wolf.TILESHIFT;
- switch (self.type) {
- case Wolf.en_guard:
- Wolf.Player.givePoints(player, 100);
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_clip2);
- break;
- case Wolf.en_officer:
- Wolf.Player.givePoints(player, 400);
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_clip2);
- break;
- case Wolf.en_mutant:
- Wolf.Player.givePoints(player, 700);
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_clip2);
- break;
- case Wolf.en_ss:
- Wolf.Player.givePoints(player, 500);
- if (player.items & Wolf.ITEM_WEAPON_3) { // have a schmeiser?
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_clip2);
- } else {
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_machinegun);
- }
- break;
- case Wolf.en_dog:
- Wolf.Player.givePoints(player, 200);
- break;
- case Wolf.en_boss:
- Wolf.Player.givePoints(player, 5000);
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_key1);
- break;
- case Wolf.en_gretel:
- Wolf.Player.givePoints(player, 5000);
- Wolf.Powerups.spawn(level, tilex, tiley, Wolf.pow_key1);
- break;
- case Wolf.en_gift:
- Wolf.Player.givePoints(player, 5000);
- startDeathCam(game, self);
- break;
- case Wolf.en_fat:
- Wolf.Player.givePoints(player, 5000);
- startDeathCam(game, self);
- break;
- case Wolf.en_schabbs:
- Wolf.Player.givePoints(player, 5000);
- deathScream(self, game);
- startDeathCam(game, self);
- break;
- case Wolf.en_fake:
- Wolf.Player.givePoints(player, 2000);
- break;
- case Wolf.en_mecha:
- Wolf.Player.givePoints(player, 5000);
- break;
- case Wolf.en_hitler:
- Wolf.Player.givePoints(player, 5000);
- deathScream(self, game);
- startDeathCam(game, self);
- break;
- }
- Wolf.Actors.stateChange(self, Wolf.st_die1);
-
- if (++level.state.killedMonsters == level.state.totalMonsters) {
- Wolf.Game.notify("You killed the last enemy!");
- }
-
- self.flags &= ~Wolf.FL_SHOOTABLE;
- self.flags |= Wolf.FL_NONMARK;
- }
-
- return {
- firstSighting : firstSighting,
- damageActor : damageActor,
- killActor : killActor,
- deathScream : deathScream,
- mechaSound : mechaSound,
- slurpie : slurpie,
- hitlerMorph : hitlerMorph,
- breathing : breathing,
- startAttack : startAttack,
- relaunch : relaunch,
- victory : victory,
- dormant : dormant,
- startDeathCam : startDeathCam,
- smoke : smoke
- };
- })();
|