123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519 |
- /*
- * ===========================================================================
- *
- * 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 Actors
- */
- Wolf.Actors = (function() {
- Wolf.setConsts({
- SPDPATROL : 512,
- SPDDOG : 1500,
- FL_SHOOTABLE : 1,
- FL_BONUS : 2,
- FL_NEVERMARK : 4,
- FL_VISABLE : 8,
- FL_ATTACKMODE : 16,
- FL_FIRSTATTACK : 32,
- FL_AMBUSH : 64,
- FL_NONMARK : 128,
- MAX_GUARDS : 255,
- NUMENEMIES : 31,
- NUMSTATES : 34,
- MINACTORDIST : 0x10000
- });
-
- Wolf.setConsts({
- en_guard : 0,
- en_officer : 1,
- en_ss : 2,
- en_dog : 3,
- en_boss : 4,
- en_schabbs : 5,
- en_fake : 6,
- en_mecha : 7,
- en_hitler : 8,
- en_mutant : 9,
- en_blinky : 10,
- en_clyde : 11,
- en_pinky : 12,
- en_inky : 13,
- en_gretel : 14,
- en_gift : 15,
- en_fat : 16,
- // --- Projectiles
- en_needle : 17,
- en_fire : 18,
- en_rocket : 19,
- en_smoke : 20,
- en_bj : 21,
- // --- Spear of destiny!
- en_spark : 22,
- en_hrocket : 23,
- en_hsmoke : 24,
- en_spectre : 25,
- en_angel : 26,
- en_trans : 27,
- en_uber : 28,
- en_will : 29,
- en_death : 30
- });
-
- Wolf.setConsts({
- st_stand : 0,
- st_path1 : 1,
- st_path1s : 2,
- st_path2 : 3,
- st_path3 : 4,
- st_path3s : 5,
- st_path4 : 6,
- st_pain : 7,
- st_pain1 : 8,
- st_shoot1 : 9,
- st_shoot2 : 10,
- st_shoot3 : 11,
- st_shoot4 : 12,
- st_shoot5 : 13,
- st_shoot6 : 14,
- st_shoot7 : 15,
- st_shoot8 : 16,
- st_shoot9 : 17,
- st_chase1 : 18,
- st_chase1s : 19,
- st_chase2 : 20,
- st_chase3 : 21,
- st_chase3s : 22,
- st_chase4 : 23,
- st_die1 : 24,
- st_die2 : 25,
- st_die3 : 26,
- st_die4 : 27,
- st_die5 : 28,
- st_die6 : 29,
- st_die7 : 30,
- st_die8 : 31,
- st_die9 : 32,
- st_dead : 33,
- st_remove : 34
- });
-
- var add8dir = [4, 5, 6, 7, 0, 1, 2, 3, 0],
- r_add8dir = [4, 7, 6, 5, 0, 1, 2, 3, 0];
- /**
- * @description Create new actor.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @returns {object} The new actor object.
- */
- function getNewActor(level) {
- if (level.state.numGuards > Wolf.MAX_GUARDS) {
- return null;
- }
- var actor = {
- x : 0,
- y : 0,
- angle : 0,
- type : 0,
- health : 0,
- max_health : 0,
- speed : 0,
- ticcount : 0,
- temp2 : 0,
- distance : 0,
- tile : {
- x : 0,
- y : 0
- },
- areanumber : 0,
- waitfordoorx : 0,
- waitfordoory : 0, // waiting on this door if non 0
- flags : 0, // FL_SHOOTABLE, etc
- state : 0,
- dir : 0,
- sprite : 0
- };
- level.state.guards[level.state.numGuards++] = actor;
-
- return actor;
- }
-
- /**
- * @description Process a single actor.
- * @private
- * @param {object} ent The actor object.
- * @param {object} level The level object.
- * @param {object} player The player object.
- * @param {number} tics The number of tics.
- * @returns {boolean} False if actor should be removed, otherwise true.
- */
- function doGuard(ent, game, tics) { // FIXME: revise!
- var think;
- //assert( ent->tilex >= 0 && ent->tilex < 64 );
- //assert( ent->tiley >= 0 && ent->tiley < 64 );
- //assert( ent->dir >= 0 && ent->dir <= 8 );
-
-
- // ticcounts fire discrete actions separate from think functions
- if (ent.ticcount) {
- ent.ticcount -= tics;
- while (ent.ticcount <= 0) {
- //assert( ent->type >= 0 && ent->type < NUMENEMIES );
- //assert( ent->state >= 0 && ent->state < NUMSTATES );
- think = Wolf.objstate[ent.type][ent.state].action; // end of state action
- if (think) {
- think(ent, game, tics);
- if (ent.state == Wolf.st_remove) {
- return false;
- }
- }
- ent.state = Wolf.objstate[ent.type][ent.state].next_state;
- if (ent.state == Wolf.st_remove) {
- return false;
- }
-
- if (!Wolf.objstate[ent.type][ent.state].timeout) {
- ent.ticcount = 0;
- break;
- }
-
- ent.ticcount += Wolf.objstate[ent.type][ent.state].timeout;
- }
- }
- //
- // think
- //
- //assert( ent->type >= 0 && ent->type < NUMENEMIES );
- //assert( ent->state >= 0 && ent->state < NUMSTATES );
- think = Wolf.objstate[ent.type][ent.state].think;
- if (think) {
- think(ent, game, tics);
- if (ent.state == Wolf.st_remove) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * @description Changes guard's state to that defined in newState.
- * @memberOf Wolf.Actors
- * @param {object} ent The actor object.
- * @param {number} newState The new state.
- */
- function stateChange(ent, newState) {
- ent.state = newState;
- // assert( ent->type >= 0 && ent->type < NUMENEMIES );
- if (newState == Wolf.st_remove) {
- ent.ticcount = 0;
- } else {
- // assert( ent->state >= 0 && ent->state < NUMSTATES );
- ent.ticcount = Wolf.objstate[ent.type][ent.state].timeout; //0;
- }
- }
-
- /**
- * @description Process all the enemy actors.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @param {object} player The player object.
- * @param {number} tics The number of tics.
- */
- function process(game, tics) {
- var level = game.level,
- player = game.player,
- n, tex, guard,
- liveGuards = [];
-
- for (n = 0 ; n < level.state.numGuards ; ++n ) {
- guard = level.state.guards[n];
- if (!doGuard(guard, game, tics)) {
- // remove guard from the game forever!
- // remove(game, guards[n--]);
- Wolf.Sprites.remove(level, guard.sprite);
- level.state.guards[n] = null;
- continue;
- }
- Wolf.Sprites.setPos(level, guard.sprite, guard.x, guard.y, guard.angle);
-
- tex = Wolf.objstate[guard.type][guard.state].texture;
-
- if (Wolf.objstate[guard.type][guard.state].rotate) {
- if (guard.type == Wolf.en_rocket || guard.type == Wolf.en_hrocket) {
- tex += r_add8dir[Wolf.Math.get8dir( Wolf.Angle.distCW(Wolf.FINE2RAD(player.angle), Wolf.FINE2RAD(guard.angle)))];
- } else {
- tex += add8dir[Wolf.Math.get8dir( Wolf.Angle.distCW(Wolf.FINE2RAD(player.angle), Wolf.FINE2RAD(guard.angle)))];
- }
- }
- Wolf.Sprites.setTex(level, guard.sprite, 0, tex);
- }
- for (n = 0 ; n < level.state.numGuards ; ++n ) {
- if (level.state.guards[n]) {
- liveGuards.push(level.state.guards[n]);
- }
- }
- level.state.guards = liveGuards;
- level.state.numGuards = liveGuards.length;
- }
-
- /**
- * @description Reset and clear the enemy actors in the level.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- */
- function resetGuards(level) {
- level.state.guards = [];
- level.state.numGuards = 0;
- //New = NULL;
- }
- /**
- * @description Spawn a new enemy actor at the given position.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @param {number} skill The difficulty level.
- * @param {number} which The actor type.
- * @param {number} x The x position.
- * @param {number} y The y position.
- * @param {number} dir The direction.
- * @returns {object} The new actor object or null if actor creation failed.
- */
- function spawn(level, skill, which, x, y, dir) {
- var ent = getNewActor(level);
-
- if (!ent) {
- return null;
- }
- ent.x = Wolf.TILE2POS(x);
- ent.y = Wolf.TILE2POS(y);
- ent.tile.x = x;
- ent.tile.y = y;
- // assert( dir >= 0 && dir <= 4 );
- ent.angle = Wolf.Math.dir4angle[dir];
- ent.dir = Wolf.Math.dir4to8[dir];
- ent.areanumber = level.areas[x][y];
- if (ent.areanumber < 0) {
- // ambush marker tiles are listed as -3 area
- ent.areanumber = 0;
- }
-
- // assert( ent->areanumber >= 0 && ent->areanumber < NUMAREAS );
- ent.type = which;
- ent.health = Wolf.starthitpoints[skill][which];
- ent.sprite = Wolf.Sprites.getNewSprite(level);
- return ent;
- }
-
- /**
- * @description Spawn a dead guard.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @param {number} skill The difficulty level.
- * @param {number} which The actor type.
- * @param {number} x The x position.
- * @param {number} y The y position.
- */
- function spawnDeadGuard(level, skill, which, x, y) {
- var self = spawn(level, skill, which, x, y, Wolf.Math.dir4_nodir);
- if (!self) {
- return;
- }
- self.state = Wolf.st_dead;
- self.speed = 0;
- self.health = 0;
- self.ticcount = Wolf.objstate[which][Wolf.st_dead].timeout ? Wolf.Random.rnd() % Wolf.objstate[which][Wolf.st_dead].timeout + 1 : 0;
- }
-
- /**
- * @description Spawn a patrolling guard.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @param {number} skill The difficulty level.
- * @param {number} which The actor type.
- * @param {number} x The x position.
- * @param {number} y The y position.
- */
- function spawnPatrol(level, skill, which, x, y, dir) {
- var self = spawn(level, skill, which, x, y, dir);
- if (!self) {
- return;
- }
-
- self.state = Wolf.st_path1;
- self.speed = (which == Wolf.en_dog) ? Wolf.SPDDOG : Wolf.SPDPATROL;
- self.distance = Wolf.TILEGLOBAL;
- self.ticcount = Wolf.objstate[which][Wolf.st_path1].timeout ? Wolf.Random.rnd() % Wolf.objstate[which][Wolf.st_path1].timeout + 1 : 0;
- self.flags |= Wolf.FL_SHOOTABLE;
- level.state.totalMonsters++;
- }
- /**
- * @description Spawn a standing guard.
- * @memberOf Wolf.Actors
- * @param {object} level The level object.
- * @param {number} skill The difficulty level.
- * @param {number} which The actor type.
- * @param {number} x The x position.
- * @param {number} y The y position.
- */
- function spawnStand(level, skill, which, x, y, dir) {
- var self = spawn(level, skill, which, x, y, dir);
- if (!self) {
- return;
- }
- self.state = Wolf.st_stand;
- self.speed = Wolf.SPDPATROL;
- self.ticcount = Wolf.objstate[which][Wolf.st_stand].timeout ? Wolf.Random.rnd() % Wolf.objstate[which][Wolf.st_stand].timeout + 1 : 0;
- self.flags |= Wolf.FL_SHOOTABLE;
-
- if (level.tileMap[x][y] & Wolf.AMBUSH_TILE) {
- self.flags |= Wolf.FL_AMBUSH;
- }
- level.state.totalMonsters++;
- }
-
- function spawnBoss(level, skill, which, x, y) {
- var self,
- face;
- switch (which) {
- case Wolf.en_boss:
- case Wolf.en_schabbs:
- case Wolf.en_fat:
- case Wolf.en_hitler:
- face = Wolf.Math.dir4_south;
- break;
- case Wolf.en_fake:
- case Wolf.en_gretel:
- case Wolf.en_gift:
- face = Wolf.Math.dir4_north;
- break;
- case Wolf.en_trans:
- case Wolf.en_uber:
- case Wolf.en_will:
- case Wolf.en_death:
- case Wolf.en_angel:
- case Wolf.en_spectre:
- face = Wolf.Math.dir4_nodir;
- break;
- default:
- face = Wolf.Math.dir4_nodir;
- break;
- }
- self = spawn(level, skill, which, x, y, face);
- if (!self) {
- return;
- }
-
- self.state = which == Wolf.en_spectre ? Wolf.st_path1 : Wolf.st_stand;
- self.speed = Wolf.SPDPATROL;
- self.health = Wolf.starthitpoints[skill][which];
- self.ticcount = Wolf.objstate[which][Wolf.st_stand].timeout ? Wolf.Random.rnd() % Wolf.objstate[which][Wolf.st_stand].timeout + 1 : 0;
- self.flags |= Wolf.FL_SHOOTABLE | Wolf.FL_AMBUSH;
- level.state.totalMonsters++;
- }
-
-
- function spawnGhosts(level, skill, which, x, y) {
- var self = spawn(level, skill, which, x, y, Wolf.Math.dir4_nodir);
- if (!self) {
- return;
- }
-
- self.state = Wolf.st_chase1;
- self.speed = Wolf.SPDPATROL * 3;
- self.health = Wolf.starthitpoints[skill][which];
- self.ticcount = Wolf.objstate[which][Wolf.st_chase1].timeout ? Wolf.Random.rnd() % Wolf.objstate[which][Wolf.st_chase1].timeout + 1: 0;
- self.flags |= Wolf.FL_AMBUSH;
- level.state.totalMonsters++;
- }
-
- function spawnBJVictory(player, level, skill) {
- var x = Wolf.POS2TILE(player.position.x),
- y = Wolf.POS2TILE(player.position.y),
- bj = spawn(level, skill, Wolf.en_bj, x, y + 1, Wolf.Math.dir4_north);
-
- if (!bj) {
- return;
- }
- bj.x = player.position.x;
- bj.y = player.position.y;
- bj.state = Wolf.st_path1;
- bj.speed = Wolf.BJRUNSPEED;
- bj.flags = Wolf.FL_NONMARK; // FL_NEVERMARK;
- bj.temp2 = 6;
- bj.ticcount = 1;
- }
-
- return {
- process : process,
- resetGuards : resetGuards,
- getNewActor : getNewActor,
- spawn : spawn,
- spawnDeadGuard : spawnDeadGuard,
- spawnPatrol : spawnPatrol,
- spawnStand : spawnStand,
- spawnBoss : spawnBoss,
- spawnGhosts : spawnGhosts,
- spawnBJVictory : spawnBJVictory,
- stateChange : stateChange
- };
- })();
|