mirror of
https://github.com/id-Software/Wolf3D-iOS.git
synced 2026-03-19 16:39:49 +01:00
Source release of Wolfenstein 3D Classic Platinum for iOS, 1.1
This commit is contained in:
1619
wolf3d/code/wolf/wolf_act_stat.h
Normal file
1619
wolf3d/code/wolf/wolf_act_stat.h
Normal file
File diff suppressed because it is too large
Load Diff
968
wolf3d/code/wolf/wolf_actor_ai.c
Normal file
968
wolf3d/code/wolf/wolf_actor_ai.c
Normal file
@@ -0,0 +1,968 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2001 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_actor_ai.c: Wolfenstein3-D artificial intelligence.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
const char dsounds[ 7 ][ 32 ] =
|
||||
{
|
||||
"sfx/025.wav",
|
||||
"sfx/026.wav",
|
||||
"sfx/086.wav",
|
||||
"sfx/088.wav",
|
||||
"sfx/105.wav",
|
||||
"sfx/107.wav",
|
||||
"sfx/109.wav"
|
||||
};
|
||||
|
||||
const char dsodsounds[ 7 ][ 32 ] =
|
||||
{
|
||||
"sfx/021.wav",
|
||||
"sfx/022.wav",
|
||||
"sfx/052.wav",
|
||||
"sfx/054.wav",
|
||||
"sfx/057.wav",
|
||||
"sfx/059.wav",
|
||||
"sfx/061.wav"
|
||||
};
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_DeathScream() -Do a death scream sound depending on actor type.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_DeathScream( entity_t *self )
|
||||
{
|
||||
switch( self->type )
|
||||
{
|
||||
case en_mutant:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/033.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/037.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_guard:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( dsodsounds[ US_RndT() % 6 ] ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( dsounds[ US_RndT() % 6 ] ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_officer:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/046.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/074.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_ss:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/035.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/046.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_dog:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/031.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/035.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_boss:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/019.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_schabbs:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/061.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_fake:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/069.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_mecha:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/084.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_hitler:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/044.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_gretel:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/115.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_gift:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/091.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_fat:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/119.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_spectre:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/062.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_angel:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/098.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_trans:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/070.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_uber:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_will:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/072.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case en_death:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/090.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_FirstSighting() -Puts an actor into attack mode and possibly
|
||||
reverses the direction if the player is
|
||||
behind it.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_FirstSighting( entity_t *self )
|
||||
{
|
||||
switch( self->type )
|
||||
{
|
||||
case en_guard:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/001.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_officer:
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/043.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/071.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
self->speed *= 5; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_mutant:
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_ss:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/015.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 4; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_dog:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/002.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 2; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_boss:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/017.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = SPDPATROL * 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_gretel:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/112.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_gift:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/096.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_fat:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/102.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_schabbs:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/065.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_fake:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/054.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_mecha:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/040.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 3; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_hitler:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/040.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed *= 5; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_blinky:
|
||||
case en_clyde:
|
||||
case en_pinky:
|
||||
case en_inky:
|
||||
self->speed *= 2; // go faster when chasing player
|
||||
break;
|
||||
|
||||
//
|
||||
// Spear of Destiny
|
||||
//
|
||||
case en_spectre:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/003.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = 800; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_angel:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/095.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = 1536; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_trans:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/066.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = 1536; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_uber:
|
||||
self->speed = 3000; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_will:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/073.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = 2048; // go faster when chasing player
|
||||
break;
|
||||
|
||||
case en_death:
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/085.wav" ), 1, ATTN_NORM, 0 );
|
||||
self->speed = 2048; // go faster when chasing player
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
A_StateChange( self, st_chase1 );
|
||||
if( self->waitfordoorx )
|
||||
{
|
||||
self->waitfordoorx = self->waitfordoory = 0; // ignore the door opening command
|
||||
}
|
||||
|
||||
self->dir = dir8_nodir;
|
||||
self->flags |= FL_ATTACKMODE | FL_FIRSTATTACK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_KillActor() -Actor has been killed, so give points and spawn
|
||||
powerups.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void A_KillActor( entity_t *self )
|
||||
{
|
||||
int tilex, tiley;
|
||||
|
||||
tilex = self->tilex = self->x >> TILESHIFT; // drop item on center
|
||||
tiley = self->tiley = self->y >> TILESHIFT;
|
||||
|
||||
switch( self->type )
|
||||
{
|
||||
case en_guard:
|
||||
PL_GivePoints( &Player, 100 );
|
||||
Powerup_Spawn( tilex, tiley, pow_clip2 );
|
||||
break;
|
||||
|
||||
case en_officer:
|
||||
PL_GivePoints( &Player, 400 );
|
||||
Powerup_Spawn( tilex, tiley, pow_clip2 );
|
||||
break;
|
||||
|
||||
case en_mutant:
|
||||
PL_GivePoints( &Player, 700 );
|
||||
Powerup_Spawn( tilex, tiley, pow_clip2 );
|
||||
break;
|
||||
|
||||
case en_ss:
|
||||
PL_GivePoints( &Player, 500 );
|
||||
if( Player.items & ITEM_WEAPON_3 ) // have a schmeiser?
|
||||
{
|
||||
Powerup_Spawn( tilex, tiley, pow_clip2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Powerup_Spawn( tilex, tiley, pow_machinegun );
|
||||
}
|
||||
break;
|
||||
|
||||
case en_dog:
|
||||
PL_GivePoints( &Player, 200 );
|
||||
break;
|
||||
|
||||
case en_boss:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
|
||||
case en_gretel:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
|
||||
case en_gift:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
A_StartDeathCam( self );
|
||||
break;
|
||||
|
||||
case en_fat:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
A_StartDeathCam( self );
|
||||
break;
|
||||
|
||||
case en_schabbs:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
A_DeathScream( self );
|
||||
A_StartDeathCam( self );
|
||||
break;
|
||||
|
||||
case en_fake:
|
||||
PL_GivePoints( &Player, 2000 );
|
||||
break;
|
||||
|
||||
case en_mecha:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
break;
|
||||
|
||||
case en_hitler:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
A_DeathScream( self );
|
||||
A_StartDeathCam( self );
|
||||
break;
|
||||
|
||||
case en_spectre:
|
||||
PL_GivePoints( &Player, 200 );
|
||||
break;
|
||||
|
||||
case en_angel:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
break;
|
||||
|
||||
case en_trans:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
|
||||
case en_uber:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
|
||||
case en_will:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
|
||||
case en_death:
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Powerup_Spawn( tilex, tiley, pow_key1 );
|
||||
break;
|
||||
}
|
||||
|
||||
A_StateChange( self, st_die1 );
|
||||
|
||||
if ( ++levelstate.killed_monsters == levelstate.total_monsters ) {
|
||||
iphoneSetNotifyText( "You killed the last enemy!" );
|
||||
}
|
||||
|
||||
self->flags &= ~FL_SHOOTABLE;
|
||||
self->flags |= FL_NONMARK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_DamageActor() -Called when the player succesfully hits an enemy.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
Does damage points to enemy ob, either putting it into a stun frame or
|
||||
killing it.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_DamageActor( entity_t *self, int damage )
|
||||
{
|
||||
Player.madenoise = 1;
|
||||
|
||||
// do double damage if shooting a non attack mode actor
|
||||
if( ! (self->flags & FL_ATTACKMODE) )
|
||||
{
|
||||
damage <<= 1;
|
||||
}
|
||||
|
||||
self->health -= damage;
|
||||
|
||||
if( self->health <= 0 )
|
||||
{
|
||||
A_KillActor( self );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ! (self->flags & FL_ATTACKMODE) )
|
||||
{
|
||||
A_FirstSighting( self ); // put into combat mode
|
||||
}
|
||||
|
||||
switch( self->type ) // dogs only have one hit point
|
||||
{
|
||||
case en_guard:
|
||||
case en_officer:
|
||||
case en_mutant:
|
||||
case en_ss:
|
||||
if( self->health & 1 )
|
||||
{
|
||||
A_StateChange( self, st_pain );
|
||||
}
|
||||
else
|
||||
{
|
||||
A_StateChange( self, st_pain1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Hitler
|
||||
//
|
||||
///////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_MechaSound -Play Mecha sound.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_MechaSound( entity_t *self )
|
||||
{
|
||||
if( areabyplayer[ self->areanumber ] )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/080.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_Slurpie -Play Slurpie sound.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Slurpie( entity_t *self )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_HitlerMorph() -Spawn new actor, when Mecha Hitler is dead.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_HitlerMorph( entity_t *self )
|
||||
{
|
||||
int hitpoints[ 4 ] = { 500, 700, 800, 900 };
|
||||
entity_t *hitler;
|
||||
|
||||
hitler = GetNewActor();
|
||||
if( ! hitler )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hitler->x = self->x;//
|
||||
hitler->y = self->y;//
|
||||
hitler->distance = self->distance;
|
||||
hitler->tilex = self->tilex;//
|
||||
hitler->tiley = self->tiley;//
|
||||
hitler->angle = self->angle;//
|
||||
hitler->dir = self->dir;//
|
||||
hitler->health = hitpoints[ (int)skill->value ];
|
||||
hitler->areanumber = self->areanumber;
|
||||
hitler->state = st_chase1;//
|
||||
hitler->type = en_hitler; //
|
||||
hitler->speed = SPDPATROL * 5;//
|
||||
hitler->ticcount = 0;//
|
||||
hitler->flags=self->flags | FL_SHOOTABLE; //
|
||||
hitler->sprite = Sprite_GetNewSprite();
|
||||
|
||||
if ( ++levelstate.killed_monsters == levelstate.total_monsters ) {
|
||||
iphoneSetNotifyText( "You killed the last enemy!" );
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Angel of Death
|
||||
//
|
||||
///////////////////////////
|
||||
|
||||
/*
|
||||
Angel can't shoot more then 3 sparks in a row.
|
||||
It will get tired!
|
||||
*/
|
||||
|
||||
PRIVATE int angel_temp = 0;
|
||||
|
||||
//
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_Breathing -Play Angel of Death Breathing sound.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Breathing( entity_t *self )
|
||||
{
|
||||
Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "lsfx/080.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_StartAttack( entity_t *self )
|
||||
{
|
||||
angel_temp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Relaunch( entity_t *self )
|
||||
{
|
||||
if( ++angel_temp == 3 )
|
||||
{
|
||||
A_StateChange( self, st_pain );
|
||||
return;
|
||||
}
|
||||
|
||||
if( US_RndT() & 1 )
|
||||
{
|
||||
A_StateChange( self, st_chase1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Victory( entity_t *self )
|
||||
{
|
||||
iphoneStartIntermission( 0 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_Dormant() -Entity is dormant state.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Dormant( entity_t *self )
|
||||
{
|
||||
int deltax, deltay;
|
||||
int xl, xh, yl, yh, x, y, n;
|
||||
|
||||
deltax = self->x - Player.position.origin[ 0 ];
|
||||
|
||||
if( deltax < -MINACTORDIST || deltax > MINACTORDIST )
|
||||
{
|
||||
goto moveok;
|
||||
}
|
||||
|
||||
deltay = self->y - Player.position.origin[ 1 ];
|
||||
if( deltay < -MINACTORDIST || deltay > MINACTORDIST )
|
||||
{
|
||||
goto moveok;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
moveok:
|
||||
xl = (self->x - MINDIST) >> TILESHIFT;
|
||||
xh = (self->x + MINDIST) >> TILESHIFT;
|
||||
yl = (self->y - MINDIST) >> TILESHIFT;
|
||||
yh = (self->y + MINDIST) >> TILESHIFT;
|
||||
|
||||
for( y = yl ; y <= yh ; ++y )
|
||||
for( x = xl ; x <= xh ; ++x )
|
||||
{
|
||||
if( r_world->tilemap[ x ][ y ] & SOLID_TILE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( Guards[ n ].state >= st_die1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
|
||||
{
|
||||
return; // another guard in path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->flags |= FL_AMBUSH | FL_SHOOTABLE;
|
||||
self->flags &= ~FL_ATTACKMODE;
|
||||
self->dir = dir8_nodir;
|
||||
A_StateChange( self, st_path1 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_StartDeathCam( entity_t *self )
|
||||
{
|
||||
// the DeathCam feature isn't implimented, but we want to give the animation time
|
||||
// to play before declaring victory.
|
||||
iphoneStartIntermission( 50 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_Smoke() -Rockets emmit smoke.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_Smoke( entity_t *self )
|
||||
{
|
||||
entity_t *smoke;
|
||||
|
||||
smoke = GetNewActor();
|
||||
if( ! smoke )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
smoke->x = self->x;
|
||||
smoke->y = self->y;
|
||||
smoke->tilex = self->tilex;
|
||||
smoke->tiley = self->tiley;
|
||||
smoke->state = st_die1;
|
||||
smoke->type = (self->type==en_hrocket) ? en_hsmoke : en_smoke;
|
||||
smoke->ticcount = 6;
|
||||
smoke->flags = FL_NEVERMARK;
|
||||
smoke->sprite = Sprite_GetNewSprite();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: ProjectileTryMove() -Called when projectile is airborne.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
lvl -[in] Valid Pointer to LevelData_t structure.
|
||||
|
||||
Returns: true if move ok, otherwise false.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE _boolean ProjectileTryMove( entity_t *self, LevelData_t *lvl )
|
||||
{
|
||||
#define PROJSIZE 0x2000
|
||||
|
||||
|
||||
int xl, yl, xh, yh, x, y;
|
||||
|
||||
xl = (self->x - PROJSIZE) >> TILESHIFT;
|
||||
yl = (self->y - PROJSIZE) >> TILESHIFT;
|
||||
|
||||
xh = (self->x + PROJSIZE) >> TILESHIFT;
|
||||
yh = (self->y + PROJSIZE) >> TILESHIFT;
|
||||
|
||||
// Checking for solid walls:
|
||||
for( y = yl ; y <= yh ; ++y )
|
||||
{
|
||||
for( x = xl ; x <= xh ; ++x )
|
||||
{
|
||||
// FIXME: decide what to do with statics & Doors!
|
||||
if( lvl->tilemap[ x ][ y ] & (WALL_TILE | BLOCK_TILE) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
|
||||
{
|
||||
if( Door_Opened( &lvl->Doors, x, y ) != DOOR_FULLOPEN )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// FIXME: Projectile will fly through objects (even guards & columns) - must fix to create rocket launcher!
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: T_Projectile() -Called when projectile is airborne.
|
||||
|
||||
Parameters: self -[in] Valid Pointer to an entity_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void T_Projectile( entity_t *self )
|
||||
{
|
||||
#define PROJECTILESIZE 0xC000
|
||||
|
||||
|
||||
int deltax, deltay, speed, damage;
|
||||
|
||||
speed = self->speed * tics;
|
||||
|
||||
deltax = (int)(speed * CosTable[ self->angle ]);
|
||||
deltay = (int)(speed * SinTable[ self->angle ]);
|
||||
|
||||
if( deltax > TILEGLOBAL )
|
||||
{
|
||||
deltax = TILEGLOBAL;
|
||||
}
|
||||
|
||||
if( deltax < -TILEGLOBAL )
|
||||
{
|
||||
deltax = -TILEGLOBAL; // my
|
||||
}
|
||||
|
||||
if( deltay > TILEGLOBAL)
|
||||
{
|
||||
deltay = TILEGLOBAL;
|
||||
}
|
||||
|
||||
if( deltay < -TILEGLOBAL)
|
||||
{
|
||||
deltay = -TILEGLOBAL; // my
|
||||
}
|
||||
|
||||
self->x += deltax;
|
||||
self->y += deltay;
|
||||
|
||||
deltax = ABS( self->x-Player.position.origin[ 0 ] );
|
||||
deltay = ABS( self->y-Player.position.origin[ 1 ] );
|
||||
|
||||
if( ! ProjectileTryMove( self, r_world ) )
|
||||
{
|
||||
if( self->type == en_rocket || self->type == en_hrocket )
|
||||
{ // rocket ran into obstacle, draw explosion!
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_WEAPON, Sound_RegisterSound( "lsfx/001.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_WEAPON, Sound_RegisterSound( "lsfx/086.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
A_StateChange( self, st_die1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
A_StateChange( self, st_remove ); // mark for removal
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( deltax < PROJECTILESIZE && deltay < PROJECTILESIZE )
|
||||
{ // hit the player
|
||||
switch( self->type )
|
||||
{
|
||||
case en_needle:
|
||||
damage = (US_RndT() >> 3) + 20;
|
||||
break;
|
||||
|
||||
case en_rocket:
|
||||
case en_hrocket:
|
||||
case en_spark:
|
||||
damage = (US_RndT()>>3) + 30;
|
||||
break;
|
||||
|
||||
case en_fire:
|
||||
damage = (US_RndT() >> 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
damage = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
PL_Damage( &Player, self, damage );
|
||||
A_StateChange( self, st_remove ); // mark for removal
|
||||
return;
|
||||
}
|
||||
|
||||
self->tilex = self->x >> TILESHIFT;
|
||||
self->tiley = self->y >> TILESHIFT;
|
||||
}
|
||||
73
wolf3d/code/wolf/wolf_actor_ai.h
Normal file
73
wolf3d/code/wolf/wolf_actor_ai.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_actor_ai.h: Wolfenstein3-D entity management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_actor_ai.c.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_ACTOR_AI_H__
|
||||
#define __WOLF_ACTOR_AI_H__
|
||||
|
||||
#include "wolf_actors.h"
|
||||
|
||||
extern void A_DeathScream( entity_t *self );
|
||||
extern void A_FirstSighting( entity_t *self );
|
||||
extern void A_DamageActor( entity_t *self, int damage );
|
||||
|
||||
// hitler
|
||||
extern void A_MechaSound( entity_t *self );
|
||||
extern void A_Slurpie( entity_t *self );
|
||||
extern void A_HitlerMorph( entity_t *self );
|
||||
|
||||
// angel
|
||||
extern void A_Breathing( entity_t *self );
|
||||
extern void A_StartAttack( entity_t *self );
|
||||
extern void A_Relaunch( entity_t *self );
|
||||
extern void A_Victory( entity_t *self );
|
||||
|
||||
// ghost
|
||||
extern void A_Dormant( entity_t *self );
|
||||
|
||||
extern void A_StartDeathCam( entity_t *self );
|
||||
|
||||
// missiles
|
||||
extern void T_Projectile( entity_t *self );
|
||||
extern void A_Smoke( entity_t *self );
|
||||
|
||||
|
||||
#endif /* __WOLF_ACTOR_AI_H__ */
|
||||
471
wolf3d/code/wolf/wolf_actors.c
Normal file
471
wolf3d/code/wolf/wolf_actors.c
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2001 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_actors.c: Wolfenstein3-D actor manager.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
#include "wolf_act_stat.h"
|
||||
|
||||
entity_t Guards[ MAX_GUARDS + 1 ], *New;
|
||||
W16 NumGuards = 0;
|
||||
W8 add8dir[ 9 ] = { 4, 5, 6, 7, 0, 1, 2, 3, 0 };
|
||||
W8 r_add8dir[ 9 ]= { 4, 7, 6, 5, 0, 1, 2, 3, 0 };
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: A_StateChange -Changes guard's state to that defined in NewState.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void A_StateChange( entity_t *ent, en_state NewState )
|
||||
{
|
||||
ent->state = NewState;
|
||||
assert( ent->type >= 0 && ent->type < NUMENEMIES );
|
||||
if ( NewState == st_remove ) {
|
||||
ent->ticcount = 0;
|
||||
} else {
|
||||
assert( ent->state >= 0 && ent->state < NUMSTATES );
|
||||
ent->ticcount = objstate[ ent->type ][ ent->state ].timeout; //0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE int DoGuard( entity_t *ent ) // FIXME: revise!
|
||||
{ // returns 0 if we must remove this Guard from Guards list, otherwise 1;
|
||||
think_t 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 = objstate[ ent->type ][ ent->state ].action; // end of state action
|
||||
if( think )
|
||||
{
|
||||
think( ent );
|
||||
if( ent->state == st_remove )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ent->state = objstate[ ent->type ][ ent->state ].next_state;
|
||||
if( ent->state == st_remove )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ! objstate[ ent->type ][ ent->state ].timeout )
|
||||
{
|
||||
ent->ticcount = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ent->ticcount += objstate[ ent->type ][ ent->state ].timeout;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// think
|
||||
//
|
||||
assert( ent->type >= 0 && ent->type < NUMENEMIES );
|
||||
assert( ent->state >= 0 && ent->state < NUMSTATES );
|
||||
think = objstate[ ent->type ][ ent->state ].think;
|
||||
if( think )
|
||||
{
|
||||
think( ent );
|
||||
if( ent->state == st_remove )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void RemoveActor( entity_t *actor )
|
||||
{
|
||||
Sprite_RemoveSprite( actor->sprite );
|
||||
memmove( actor, actor+1, (int)(&Guards[ NumGuards ]) - (int)(actor+1) );
|
||||
NumGuards--;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void ProcessGuards( void )
|
||||
{
|
||||
int n, tex;
|
||||
assert( NumGuards < MAX_GUARDS );
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( ! DoGuard( &Guards[ n ] ) )
|
||||
{ // remove guard from the game forever!
|
||||
RemoveActor( &Guards[ n-- ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
Sprite_SetPos( Guards[ n ].sprite, Guards[ n ].x, Guards[ n ].y, Guards[ n ].angle );
|
||||
tex = objstate[ Guards[ n ].type ][ Guards[ n ].state ].texture;
|
||||
|
||||
if( objstate[ Guards[ n ].type ][ Guards[ n ].state ].rotate )
|
||||
{
|
||||
if( Guards[ n ].type == en_rocket || Guards[ n ].type == en_hrocket )
|
||||
{
|
||||
tex += r_add8dir[ Get8dir( angle_wise( FINE2RAD(Player.position.angle), FINE2RAD(Guards[ n ].angle) ) ) ];
|
||||
}
|
||||
else
|
||||
{
|
||||
tex += add8dir[ Get8dir( angle_wise( FINE2RAD(Player.position.angle), FINE2RAD(Guards[ n ].angle) ) ) ];
|
||||
}
|
||||
}
|
||||
|
||||
Sprite_SetTex( Guards[ n ].sprite, 0, tex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: ResetGuards -Reset actors status
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void ResetGuards( void )
|
||||
{
|
||||
memset( Guards, 0, sizeof( Guards ) );
|
||||
NumGuards = 0;
|
||||
New = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC entity_t *GetNewActor( void )
|
||||
{
|
||||
if( NumGuards > MAX_GUARDS )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( &Guards[ NumGuards ], 0, sizeof( Guards[ 0 ] ) );
|
||||
|
||||
return &Guards[ NumGuards++ ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC entity_t *SpawnActor( enemy_t which, int x, int y, dir4type dir, LevelData_t *lvl )
|
||||
{
|
||||
entity_t *new_actor;
|
||||
|
||||
new_actor = GetNewActor();
|
||||
if( ! new_actor )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_actor->x = TILE2POS( x );
|
||||
new_actor->y = TILE2POS( y );
|
||||
|
||||
new_actor->tilex = x;
|
||||
new_actor->tiley = y;
|
||||
|
||||
assert( dir >= 0 && dir <= 4 );
|
||||
new_actor->angle = dir4angle[ dir ];
|
||||
new_actor->dir = dir4to8[ dir ];
|
||||
|
||||
new_actor->areanumber = lvl->areas[ x ][ y ];
|
||||
// Com_Printf( "Actor at %i,%i had areaNum: %i\n", x, y, new_actor->areanumber );
|
||||
if ( new_actor->areanumber < 0 ) {
|
||||
// ambush marker tiles are listed as -3 area
|
||||
new_actor->areanumber = 0;
|
||||
}
|
||||
|
||||
assert( new_actor->areanumber >= 0 && new_actor->areanumber < NUMAREAS );
|
||||
new_actor->type = which;
|
||||
|
||||
new_actor->health = starthitpoints[ (int)skill->value ][ which ];
|
||||
new_actor->sprite = Sprite_GetNewSprite();
|
||||
|
||||
return new_actor;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void SpawnStand( enemy_t which, int x, int y, int dir, LevelData_t *lvl )
|
||||
{
|
||||
entity_t *self;
|
||||
|
||||
self = SpawnActor( which, x, y, dir, r_world );
|
||||
if( ! self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->state = st_stand;
|
||||
self->speed = SPDPATROL;
|
||||
self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0;
|
||||
self->flags |= FL_SHOOTABLE;
|
||||
if( lvl->tilemap[ x ][ y ] & AMBUSH_TILE )
|
||||
{
|
||||
self->flags |= FL_AMBUSH;
|
||||
}
|
||||
|
||||
levelstate.total_monsters++;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void SpawnPatrol( enemy_t which, int x, int y, int dir )
|
||||
{
|
||||
entity_t *self;
|
||||
|
||||
self = SpawnActor( which, x, y, dir, r_world );
|
||||
if( ! self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->state = st_path1;
|
||||
self->speed = (which == en_dog) ? SPDDOG : SPDPATROL;
|
||||
self->distance = TILEGLOBAL;
|
||||
self->ticcount = objstate[ which ][ st_path1 ].timeout ? US_RndT() % objstate[ which ][ st_path1 ].timeout + 1 : 0;
|
||||
self->flags |= FL_SHOOTABLE;
|
||||
|
||||
levelstate.total_monsters++;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void SpawnDeadGuard( enemy_t which, int x, int y )
|
||||
{
|
||||
entity_t *self;
|
||||
|
||||
self = SpawnActor( which, x, y, dir4_nodir, r_world );
|
||||
if( ! self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->state = st_dead;
|
||||
self->speed = 0;
|
||||
self->health = 0;
|
||||
self->ticcount = objstate[ which ][ st_dead ].timeout ? US_RndT() % objstate[ which ][ st_dead ].timeout + 1 : 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void SpawnBoss( enemy_t which, int x, int y )
|
||||
{
|
||||
entity_t *self;
|
||||
dir4type face;
|
||||
|
||||
switch( which )
|
||||
{
|
||||
case en_boss:
|
||||
case en_schabbs:
|
||||
case en_fat:
|
||||
case en_hitler:
|
||||
face = dir4_south;
|
||||
break;
|
||||
|
||||
case en_fake:
|
||||
case en_gretel:
|
||||
case en_gift:
|
||||
face = dir4_north;
|
||||
break;
|
||||
|
||||
case en_trans:
|
||||
case en_uber:
|
||||
case en_will:
|
||||
case en_death:
|
||||
case en_angel:
|
||||
case en_spectre:
|
||||
face = dir4_nodir;
|
||||
break;
|
||||
|
||||
default:
|
||||
face = dir4_nodir;
|
||||
break;
|
||||
}
|
||||
|
||||
self = SpawnActor( which, x, y, face, r_world );
|
||||
if( ! self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->state = which == en_spectre ? st_path1 : st_stand;
|
||||
self->speed = SPDPATROL;
|
||||
self->health = starthitpoints[ (int)skill->value ][ which ];
|
||||
self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0;
|
||||
self->flags |= FL_SHOOTABLE | FL_AMBUSH;
|
||||
|
||||
levelstate.total_monsters++;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void SpawnGhosts( enemy_t which, int x, int y )
|
||||
{
|
||||
entity_t *self;
|
||||
|
||||
self = SpawnActor( which, x, y, dir4_nodir, r_world );
|
||||
if( ! self )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->state = st_chase1;
|
||||
self->speed = SPDPATROL * 3;
|
||||
self->health = starthitpoints[ (int)skill->value ][ which ];
|
||||
self->ticcount = objstate[ which ][ st_chase1 ].timeout ? US_RndT() % objstate[ which ][ st_chase1 ].timeout + 1: 0;
|
||||
self->flags |= FL_AMBUSH;
|
||||
|
||||
levelstate.total_monsters++;
|
||||
}
|
||||
172
wolf3d/code/wolf/wolf_actors.h
Normal file
172
wolf3d/code/wolf/wolf_actors.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_actors.h: Wolfenstein3-D entity management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_actors.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_ACTORS_H__
|
||||
#define __WOLF_ACTORS_H__
|
||||
|
||||
#define SPDPATROL 512
|
||||
#define SPDDOG 1500
|
||||
|
||||
#define FL_SHOOTABLE 1
|
||||
#define FL_BONUS 2
|
||||
#define FL_NEVERMARK 4
|
||||
#define FL_VISABLE 8
|
||||
#define FL_ATTACKMODE 16
|
||||
#define FL_FIRSTATTACK 32
|
||||
#define FL_AMBUSH 64
|
||||
#define FL_NONMARK 128
|
||||
|
||||
#define MAX_GUARDS 255
|
||||
#define NUMENEMIES 31
|
||||
#define NUMSTATES 34
|
||||
|
||||
#define MINACTORDIST 0x10000 // minimum dist from player center to any actor center
|
||||
|
||||
typedef enum
|
||||
{
|
||||
en_guard,
|
||||
en_officer,
|
||||
en_ss,
|
||||
en_dog,
|
||||
en_boss,
|
||||
en_schabbs,
|
||||
en_fake,
|
||||
en_mecha,
|
||||
en_hitler,
|
||||
en_mutant,
|
||||
en_blinky,
|
||||
en_clyde,
|
||||
en_pinky,
|
||||
en_inky,
|
||||
en_gretel,
|
||||
en_gift,
|
||||
en_fat,
|
||||
// --- Projectiles
|
||||
en_needle,
|
||||
en_fire,
|
||||
en_rocket,
|
||||
en_smoke,
|
||||
en_bj,
|
||||
// --- Spear of destiny!
|
||||
en_spark,
|
||||
en_hrocket,
|
||||
en_hsmoke,
|
||||
|
||||
en_spectre,
|
||||
en_angel,
|
||||
en_trans,
|
||||
en_uber,
|
||||
en_will,
|
||||
en_death
|
||||
|
||||
} enemy_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
st_stand,
|
||||
st_path1, st_path1s, st_path2, st_path3, st_path3s, st_path4,
|
||||
st_pain, st_pain1,
|
||||
st_shoot1, st_shoot2, st_shoot3, st_shoot4, st_shoot5, st_shoot6, st_shoot7, st_shoot8, st_shoot9,
|
||||
st_chase1, st_chase1s, st_chase2, st_chase3, st_chase3s, st_chase4,
|
||||
st_die1, st_die2, st_die3, st_die4, st_die5, st_die6, st_die7, st_die8, st_die9,
|
||||
st_dead,
|
||||
st_remove
|
||||
|
||||
} en_state;
|
||||
|
||||
typedef struct entity_s
|
||||
{
|
||||
int x, y, angle;
|
||||
int type;
|
||||
int health;
|
||||
int max_health;
|
||||
int speed;
|
||||
int ticcount;
|
||||
int temp2;
|
||||
int distance;
|
||||
char tilex, tiley;
|
||||
char areanumber;
|
||||
int waitfordoorx, waitfordoory; // waiting on this door if non 0
|
||||
W8 flags; // FL_SHOOTABLE, etc
|
||||
en_state state;
|
||||
dir8type dir;
|
||||
int sprite;
|
||||
|
||||
} entity_t;
|
||||
|
||||
typedef void (*think_t)( entity_t *self );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char rotate; // 1-if object can be rotated, 0 if one sprite for every direction
|
||||
int texture; // base object's state texture if rotation is on facing player
|
||||
int timeout; // after how man ticks change state to .next_state
|
||||
think_t think; // what to do every frame
|
||||
think_t action; // what to do once per state
|
||||
en_state next_state; // next state
|
||||
|
||||
} stateinfo;
|
||||
|
||||
|
||||
|
||||
extern entity_t Guards[ MAX_GUARDS + 1 ];
|
||||
extern entity_t *New;
|
||||
extern W16 NumGuards;
|
||||
extern stateinfo objstate[ NUMENEMIES ][ NUMSTATES ];
|
||||
|
||||
extern void ResetGuards(void);
|
||||
|
||||
|
||||
extern entity_t *GetNewActor( void );
|
||||
extern entity_t *SpawnActor( enemy_t which, int x, int y, dir4type dir, LevelData_t *lvl );
|
||||
extern void A_StateChange( entity_t *Guard, en_state NewState );
|
||||
|
||||
|
||||
extern void SpawnStand( enemy_t which, int tilex, int tiley, int dir, LevelData_t *lvl );
|
||||
extern void SpawnPatrol( enemy_t which, int tilex, int tiley, int dir );
|
||||
extern void SpawnDeadGuard( enemy_t which, int x, int y );
|
||||
extern void SpawnBoss( enemy_t which, int x, int y );
|
||||
extern void SpawnGhosts( enemy_t which, int x, int y );
|
||||
|
||||
|
||||
#endif /* __WOLF_ACTORS_H__ */
|
||||
|
||||
1315
wolf3d/code/wolf/wolf_ai_com.c
Normal file
1315
wolf3d/code/wolf/wolf_ai_com.c
Normal file
File diff suppressed because it is too large
Load Diff
65
wolf3d/code/wolf/wolf_ai_com.h
Normal file
65
wolf3d/code/wolf/wolf_ai_com.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_ai_com.h: Wolfenstein3-D entity management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_ai_com.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_AI_COM_H__
|
||||
#define __WOLF_AI_COM_H__
|
||||
|
||||
#include "wolf_actors.h"
|
||||
|
||||
// common AI functions
|
||||
|
||||
extern void T_Stand( entity_t *self );
|
||||
extern void T_Path( entity_t *self );
|
||||
extern void T_Ghosts( entity_t *self );
|
||||
extern void T_Chase( entity_t *self );
|
||||
extern void T_Bite( entity_t *self );
|
||||
extern void T_DogChase( entity_t *self );
|
||||
extern void T_BossChase( entity_t *self );
|
||||
extern void T_Fake( entity_t *self );
|
||||
|
||||
extern void T_Shoot( entity_t *self );
|
||||
extern void T_UShoot( entity_t *self );
|
||||
extern void T_Launch( entity_t *self );
|
||||
|
||||
|
||||
#endif /* __WOLF_AI_COM_H__ */
|
||||
|
||||
170
wolf3d/code/wolf/wolf_areas.c
Normal file
170
wolf3d/code/wolf/wolf_areas.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_areas.c: Wolfenstein3-D area management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Notes:
|
||||
|
||||
Open doors connect two areas, so sounds will travel between them and sight
|
||||
will be checked when the player is in a connected area.
|
||||
|
||||
Areaconnect is incremented/decremented by each door. If >0 they connect.
|
||||
|
||||
Every time a door opens or closes the areabyplayer matrix gets recalculated.
|
||||
An area is true if it connects with the player's current spor.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
|
||||
|
||||
|
||||
W8 areaconnect[ NUMAREAS ][ NUMAREAS ];
|
||||
_boolean areabyplayer[ NUMAREAS ];
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Areas_RecursiveConnect() -Scans outward from playerarea,
|
||||
marking all connected areas.
|
||||
|
||||
Parameters: areanumber -[in] area.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void Areas_RecursiveConnect( int areanumber )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0 ; i < NUMAREAS ; ++i )
|
||||
{
|
||||
if( areaconnect[ areanumber ][ i ] && ! areabyplayer[ i ] )
|
||||
{
|
||||
areabyplayer[ i ] = true;
|
||||
Areas_RecursiveConnect( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Areas_ConnectAreas() -Connect area.
|
||||
|
||||
Parameters: areanumber -[in] area.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Areas_ConnectAreas( int areanumber )
|
||||
{
|
||||
int c = 0;
|
||||
int i;
|
||||
|
||||
assert( areanumber < NUMAREAS );
|
||||
memset( areabyplayer, 0, sizeof( areabyplayer ) );
|
||||
areabyplayer[ areanumber ] = true;
|
||||
Areas_RecursiveConnect( areanumber );
|
||||
for ( i = 0 ; i < NUMAREAS ; i++ ) {
|
||||
if ( areabyplayer[i] ) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Areas_InitAreas( int areanumber )
|
||||
{
|
||||
memset( areaconnect, 0, sizeof( areaconnect ) );
|
||||
memset( areabyplayer, 0, sizeof( areabyplayer ) );
|
||||
areabyplayer[ areanumber ] = true;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Areas_JoinAreas( int area1, int area2 )
|
||||
{// FIXME: check for overflow!
|
||||
areaconnect[ area1 ][ area2 ]++;
|
||||
areaconnect[ area2 ][ area1 ]++;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Areas_DisconnectAreas( int area1, int area2 )
|
||||
{// FIXME: check for underflow!
|
||||
areaconnect[ area1 ][ area2 ]--;
|
||||
areaconnect[ area2 ][ area1 ]--;
|
||||
}
|
||||
136
wolf3d/code/wolf/wolf_bj.c
Normal file
136
wolf3d/code/wolf/wolf_bj.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
|
||||
|
||||
#define BJRUNSPEED 2048
|
||||
#define BJJUMPSPEED 680
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void SpawnBJVictory( void )
|
||||
{
|
||||
entity_t *bj;
|
||||
|
||||
bj = SpawnActor( en_bj, POS2TILE(Player.position.origin[0]), POS2TILE(Player.position.origin[1]), dir4_north, r_world );
|
||||
if( ! bj )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bj->x = Player.position.origin[ 0 ];
|
||||
bj->y = Player.position.origin[ 1 ];
|
||||
bj->state = st_path1;
|
||||
bj->speed = BJRUNSPEED;
|
||||
bj->flags = FL_NONMARK; // FL_NEVERMARK;
|
||||
bj->temp2 = 6;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void T_BJRun( entity_t *Guard )
|
||||
{
|
||||
// MoveObj(Guard, Guard->speed);
|
||||
|
||||
if( ! Guard->distance )
|
||||
{
|
||||
Guard->distance = TILEGLOBAL;
|
||||
if ( !(--Guard->temp2) )
|
||||
{
|
||||
A_StateChange( Guard, st_shoot1 );
|
||||
Guard->speed = BJJUMPSPEED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void T_BJJump( entity_t *Guard )
|
||||
{
|
||||
// MoveObj(Guard, Guard->speed);
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void T_BJYell( entity_t *Guard )
|
||||
{
|
||||
Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void T_BJDone( entity_t *Guard )
|
||||
{
|
||||
Player.playstate = ex_victory; // exit castle tile
|
||||
}
|
||||
59
wolf3d/code/wolf/wolf_bj.h
Normal file
59
wolf3d/code/wolf/wolf_bj.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_bj.h: Wolfenstein3-D bj code .
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_bj.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_BJ_H__
|
||||
#define __WOLF_BJ_H__
|
||||
|
||||
|
||||
|
||||
extern void SpawnBJVictory( void );
|
||||
extern void T_BJRun( entity_t *Guard );
|
||||
extern void T_BJJump( entity_t *Guard );
|
||||
extern void T_BJYell( entity_t *Guard );
|
||||
extern void T_BJDone( entity_t *Guard );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __WOLF_BJ_H__ */
|
||||
|
||||
91
wolf3d/code/wolf/wolf_client_main.c
Normal file
91
wolf3d/code/wolf/wolf_client_main.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Client_PrepRefresh( const char *r_mapname )
|
||||
{
|
||||
char mapname[ 32 ];
|
||||
|
||||
if( ! r_mapname || ! *r_mapname )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
spritelocation = SODSPRITESDIRNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
spritelocation = WL6SPRITESDIRNAME;
|
||||
}
|
||||
|
||||
my_strlcpy( mapname, r_mapname, sizeof( mapname ) ); // skip "maps/"
|
||||
|
||||
// !@# fix crash bug if you type something short...
|
||||
if ( strlen( mapname ) > 4 && !strcmp( mapname + strlen( mapname ) - 4, ".map" ) ) {
|
||||
mapname[ strlen( mapname ) - 4 ] = '\0'; // cut off ".map"
|
||||
}
|
||||
|
||||
// register models, pics, and skins
|
||||
R_BeginRegistration( mapname );
|
||||
|
||||
if( r_world == NULL )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Com_Printf( "Map: %s\n", r_world->mapName );
|
||||
|
||||
Level_ScanInfoPlane( r_world ); // Spawn items/guards
|
||||
|
||||
Com_Printf( "Spawning Entities\n" );
|
||||
PL_Spawn( r_world->pSpawn, r_world ); // Spawn Player
|
||||
|
||||
Com_Printf( "Caching Textures and Sounds\n" );
|
||||
Level_PrecacheTextures_Sound( r_world );
|
||||
|
||||
// clear any lines of console text
|
||||
Con_ClearNotify();
|
||||
|
||||
Sound_StartBGTrack( levelData.musicName, levelData.musicName );
|
||||
|
||||
Player.playstate = ex_playing;
|
||||
}
|
||||
|
||||
int tics;
|
||||
|
||||
|
||||
|
||||
|
||||
506
wolf3d/code/wolf/wolf_doors.c
Normal file
506
wolf3d/code/wolf/wolf_doors.c
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_doors.c: Wolfenstein 3-D door management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Wolfenstein 3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
#define CLOSEWALL MINDIST // Space between wall & player
|
||||
#define MAXDOORS 64 // max number of sliding doors
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Door_ResetDoors -Resets doors status
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Door_ResetDoors( LevelDoors_t *lvldoors )
|
||||
{
|
||||
lvldoors->doornum = 0;
|
||||
|
||||
memset( lvldoors->Doors, 0, sizeof( lvldoors->Doors ) );
|
||||
memset( lvldoors->DoorMap, 0, sizeof( lvldoors->DoorMap ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Door_SpawnDoor -Spawns door at x, y, position.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int Door_SpawnDoor( LevelDoors_t *lvldoors, int x, int y, int type )
|
||||
{
|
||||
if( lvldoors->doornum >= MAXDOORS )
|
||||
{
|
||||
Com_DPrintf( "[%s]: Too many Doors on level! (%d)\n", "wolf_doors.c", lvldoors->doornum );
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case 0x5A:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_VERT;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical= true;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DDOOR + 1;
|
||||
break;
|
||||
|
||||
case 0x5B:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_HORIZ;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = false;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DDOOR;
|
||||
break;
|
||||
|
||||
case 0x5C:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_G_VERT;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = true;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK;
|
||||
break;
|
||||
|
||||
case 0x5D:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_G_HORIZ;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = false;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK;
|
||||
break;
|
||||
|
||||
case 0x5E:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_S_VERT;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = true;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK + 1;
|
||||
break;
|
||||
|
||||
case 0x5F:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_S_HORIZ;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = false;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK + 1;
|
||||
break;
|
||||
|
||||
case 0x64:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_E_VERT;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = true;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DELEV + 1;
|
||||
break;
|
||||
|
||||
case 0x65:
|
||||
lvldoors->DoorMap[ x ][ y ].type = DOOR_E_HORIZ;
|
||||
lvldoors->DoorMap[ x ][ y ].vertical = false;
|
||||
lvldoors->DoorMap[ x ][ y ].texture = TEX_DELEV;
|
||||
break;
|
||||
|
||||
default:
|
||||
Com_DPrintf( "Door_SpawnDoor: Unknown door type: %d\n", type );
|
||||
return 0;
|
||||
}
|
||||
|
||||
lvldoors->DoorMap[ x ][ y ].tilex = x;
|
||||
lvldoors->DoorMap[ x ][ y ].tiley = y;
|
||||
lvldoors->DoorMap[ x ][ y ].action = dr_closed;
|
||||
|
||||
lvldoors->Doors[ lvldoors->doornum ] = &lvldoors->DoorMap[ x ][ y ];
|
||||
lvldoors->doornum++;
|
||||
|
||||
return lvldoors->doornum - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Door_SetAreas( LevelDoors_t *lvldoors, int (*areas)[64] )
|
||||
{
|
||||
int n, x, y;
|
||||
|
||||
for( n = 0 ; n < lvldoors->doornum ; ++n )
|
||||
{
|
||||
x = lvldoors->Doors[ n ]->tilex;
|
||||
y = lvldoors->Doors[ n ]->tiley;
|
||||
|
||||
if( lvldoors->Doors[ n ]->vertical )
|
||||
{
|
||||
lvldoors->Doors[ n ]->area1 = areas[ x + 1 ][ y ] >= 0 ? areas[ x + 1 ][ y ] : 0;
|
||||
lvldoors->Doors[ n ]->area2 = areas[ x - 1 ][ y ] >= 0 ? areas[ x - 1 ][ y ] : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lvldoors->Doors[ n ]->area1 = areas[ x ][ y + 1 ] >= 0 ? areas[ x ][ y + 1 ] : 0;
|
||||
lvldoors->Doors[ n ]->area2 = areas[ x ][ y - 1 ] >= 0 ? areas[ x ][ y - 1 ] : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE W8 CanCloseDoor( int x, int y, char vert )
|
||||
{
|
||||
int n;
|
||||
|
||||
if( POS2TILE( Player.position.origin[ 0 ] ) == x &&
|
||||
POS2TILE( Player.position.origin[ 1 ] ) == y )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( vert )
|
||||
{
|
||||
if( POS2TILE( Player.position.origin[ 1 ] ) == y )
|
||||
{
|
||||
if( POS2TILE( Player.position.origin[ 0 ] + CLOSEWALL ) == x )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( POS2TILE( Player.position.origin[ 0 ] - CLOSEWALL ) == x )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
|
||||
if( Guards[ n ].tilex == x - 1 &&
|
||||
Guards[ n ].tiley == y &&
|
||||
POS2TILE( Guards[ n ].x + CLOSEWALL ) == x )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
|
||||
if( Guards[ n ].tilex == x + 1 &&
|
||||
Guards[ n ].tiley == y &&
|
||||
POS2TILE( Guards[ n ].x - CLOSEWALL ) == x )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( POS2TILE( Player.position.origin[ 0 ] ) == x )
|
||||
{
|
||||
if( POS2TILE( Player.position.origin[ 1 ] + CLOSEWALL ) == y )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( POS2TILE( Player.position.origin[ 1 ] - CLOSEWALL ) == y )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
|
||||
if( Guards[ n ].tilex == x &&
|
||||
Guards[ n ].tiley == y - 1 &&
|
||||
POS2TILE( Guards[ n ].y + CLOSEWALL ) == y )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
|
||||
if( Guards[ n ].tilex == x &&
|
||||
Guards[ n ].tiley == y + 1 &&
|
||||
POS2TILE( Guards[ n ].y - CLOSEWALL ) == y )
|
||||
{
|
||||
return 0; // guard in door
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Door_OpenDoor( doors_t *Door )
|
||||
{
|
||||
if( Door->action == dr_open )
|
||||
{
|
||||
Door->ticcount = 0; // reset opened time
|
||||
}
|
||||
else
|
||||
{
|
||||
Door->action = dr_opening; // start opening it
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void Door_ChangeDoorState( doors_t *Door )
|
||||
{
|
||||
if( Door->action < dr_opening )
|
||||
{
|
||||
Door_OpenDoor( Door );
|
||||
}
|
||||
else if( Door->action == dr_open && CanCloseDoor( Door->tilex, Door->tiley, Door->vertical ) )
|
||||
{
|
||||
// !@# for the iphone with automatic using, don't allow any door close actions
|
||||
// Door->action = dr_closing;
|
||||
// Door->ticcount = DOOR_FULLOPEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Door_ProcessDoors_e( LevelDoors_t *lvldoors, int t_tk )
|
||||
{
|
||||
int n;
|
||||
|
||||
for( n = 0 ; n < lvldoors->doornum ; ++n )
|
||||
{
|
||||
switch( lvldoors->Doors[ n ]->action )
|
||||
{
|
||||
case dr_closed: // this door is closed!
|
||||
continue;
|
||||
|
||||
case dr_opening:
|
||||
if( lvldoors->Doors[ n ]->ticcount >= DOOR_FULLOPEN ) // door fully opened!
|
||||
{
|
||||
lvldoors->Doors[ n ]->action = dr_open;
|
||||
lvldoors->Doors[ n ]->ticcount = 0;
|
||||
}
|
||||
else // opening!
|
||||
{
|
||||
if( lvldoors->Doors[ n ]->ticcount == 0 )
|
||||
{ // door is just starting to open, so connect the areas
|
||||
Areas_JoinAreas( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
|
||||
Areas_ConnectAreas( Player.areanumber );
|
||||
if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Opening sound!
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/010.wav" ), 1, ATTN_STATIC, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
lvldoors->Doors[n]->ticcount += t_tk;
|
||||
|
||||
if( lvldoors->Doors[ n ]->ticcount > DOOR_FULLOPEN )
|
||||
{
|
||||
lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case dr_closing:
|
||||
if( lvldoors->Doors[ n ]->ticcount <= 0 ) // door fully closed! disconnect areas!
|
||||
{
|
||||
Areas_DisconnectAreas( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
|
||||
Areas_ConnectAreas( Player.areanumber );
|
||||
lvldoors->Doors[ n ]->ticcount = 0;
|
||||
lvldoors->Doors[ n ]->action = dr_closed;
|
||||
}
|
||||
else // closing!
|
||||
{
|
||||
if( lvldoors->Doors[ n ]->ticcount == DOOR_FULLOPEN )
|
||||
{
|
||||
if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Closing sound!
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/007.wav" ), 1, ATTN_STATIC, 0 );
|
||||
}
|
||||
}
|
||||
lvldoors->Doors[ n ]->ticcount -= t_tk;
|
||||
if( lvldoors->Doors[ n ]->ticcount < 0 )
|
||||
{
|
||||
lvldoors->Doors[ n ]->ticcount = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case dr_open:
|
||||
if( lvldoors->Doors[ n ]->ticcount > DOOR_MINOPEN )
|
||||
{ // If player or something is in door do not close it!
|
||||
if( ! CanCloseDoor( lvldoors->Doors[ n ]->tilex, lvldoors->Doors[ n ]->tiley, lvldoors->Doors[ n ]->vertical ) )
|
||||
{
|
||||
lvldoors->Doors[ n ]->ticcount = DOOR_MINOPEN; // do not close door immediately!
|
||||
}
|
||||
}
|
||||
if( lvldoors->Doors[ n ]->ticcount >= DOOR_TIMEOUT )
|
||||
{ // Door timeout, time to close it!
|
||||
lvldoors->Doors[ n ]->action = dr_closing;
|
||||
lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
|
||||
}
|
||||
else
|
||||
{ // Increase timeout!
|
||||
lvldoors->Doors[ n ]->ticcount += t_tk;
|
||||
}
|
||||
break;
|
||||
|
||||
} // End switch lvldoors->Doors[ n ].action
|
||||
|
||||
} // End for n = 0 ; n < lvldoors->doornum ; ++n
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Door_Opened -Check to see if a door is open.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: DOOR_FULLOPEN Door is opened
|
||||
0 Door is closed
|
||||
>0 <DOOR_FULLOPEN Door is partially opened.
|
||||
|
||||
Notes:
|
||||
If there are no doors in tile assume a closed door!
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int Door_Opened( LevelDoors_t *lvldoors, int x, int y )
|
||||
{
|
||||
return lvldoors->DoorMap[ x ][ y ].action == dr_open ? DOOR_FULLOPEN : lvldoors->DoorMap[ x ][ y ].ticcount;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Door_TryUse -Try to use a door with keys that the player has.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC _boolean Door_TryUse( doors_t *Door, int keys )
|
||||
{
|
||||
switch( Door->type )
|
||||
{
|
||||
case DOOR_VERT:
|
||||
case DOOR_HORIZ:
|
||||
case DOOR_E_VERT:
|
||||
case DOOR_E_HORIZ:
|
||||
Door_ChangeDoorState( Door ); // does not require key!
|
||||
break;
|
||||
|
||||
case DOOR_G_VERT:
|
||||
case DOOR_G_HORIZ:
|
||||
if( keys & ITEM_KEY_1 )
|
||||
{
|
||||
Door_ChangeDoorState( Door );
|
||||
}
|
||||
else
|
||||
{
|
||||
iphoneSetNotifyText( "You need a gold key" );
|
||||
}
|
||||
break;
|
||||
|
||||
case DOOR_S_VERT:
|
||||
case DOOR_S_HORIZ:
|
||||
if( keys & ITEM_KEY_2 )
|
||||
{
|
||||
Door_ChangeDoorState( Door );
|
||||
}
|
||||
else
|
||||
{
|
||||
iphoneSetNotifyText( "You need a silver key" );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true; // FIXME
|
||||
|
||||
}
|
||||
1376
wolf3d/code/wolf/wolf_level.c
Normal file
1376
wolf3d/code/wolf/wolf_level.c
Normal file
File diff suppressed because it is too large
Load Diff
292
wolf3d/code/wolf/wolf_level.h
Normal file
292
wolf3d/code/wolf/wolf_level.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_level.h: Wolfenstein3-D level management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_areas.c, wolf_doors.c, wolf_level.c and
|
||||
wolf_pushwalls.c
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_LEVEL_H__
|
||||
#define __WOLF_LEVEL_H__
|
||||
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Areas
|
||||
//
|
||||
///////////////////
|
||||
|
||||
#define NUMAREAS 37 // number of areas
|
||||
#define FIRSTAREA 0x6B // first area in map data (it is by the way a way to the secret floor!)
|
||||
#define AMBUSHTILE 0x6A // def guard
|
||||
#define AMBUSH -2
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Doors
|
||||
//
|
||||
///////////////////
|
||||
#define MAX_DOORS 256
|
||||
#define DOOR_TIMEOUT 300
|
||||
#define DOOR_MINOPEN 50
|
||||
|
||||
#define DOOR_FULLOPEN 63
|
||||
|
||||
|
||||
#define DOOR_VERT 255
|
||||
#define DOOR_HORIZ 254
|
||||
#define DOOR_E_VERT 253
|
||||
#define DOOR_E_HORIZ 252
|
||||
|
||||
#define DOOR_G_VERT 251
|
||||
#define DOOR_G_HORIZ 250
|
||||
#define DOOR_S_VERT 249
|
||||
#define DOOR_S_HORIZ 248
|
||||
|
||||
#define FIRST_DOOR 248
|
||||
#define LAST_LOCK 251
|
||||
|
||||
|
||||
|
||||
|
||||
#define TEX_DOOR 126
|
||||
|
||||
// texture IDs used by cache routines
|
||||
#define TEX_DDOOR (0 + TEX_DOOR) // Simple Door
|
||||
#define TEX_PLATE (2 + TEX_DOOR) // Door Plate
|
||||
#define TEX_DELEV (4 + TEX_DOOR) // Elevator Door
|
||||
#define TEX_DLOCK (6 + TEX_DOOR) // Locked Door
|
||||
|
||||
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Level
|
||||
//
|
||||
///////////////////
|
||||
#define WALL_TILE 1
|
||||
#define PUSHWALL_TILE (1 << 20)
|
||||
#define DOOR_TILE 2
|
||||
#define SECRET_TILE 4
|
||||
#define DRESS_TILE 8
|
||||
#define BLOCK_TILE 16
|
||||
#define ACTOR_TILE 32
|
||||
#define DEADACTOR_TILE 64
|
||||
#define POWERUP_TILE 128
|
||||
#define AMBUSH_TILE 256
|
||||
#define EXIT_TILE 512
|
||||
#define SECRETLEVEL_TILE 1024
|
||||
#define ELEVATOR_TILE (1 << 11)
|
||||
#define TILE_IS_E_TURN (1 << 12)
|
||||
#define TILE_IS_NE_TURN (1 << 13)
|
||||
#define TILE_IS_N_TURN (1 << 14)
|
||||
#define TILE_IS_NW_TURN (1 << 15)
|
||||
#define TILE_IS_W_TURN (1 << 16)
|
||||
#define TILE_IS_SW_TURN (1 << 17)
|
||||
#define TILE_IS_S_TURN (1 << 18)
|
||||
#define TILE_IS_SE_TURN (1 << 19)
|
||||
|
||||
#define SOLID_TILE (WALL_TILE | BLOCK_TILE | PUSHWALL_TILE)
|
||||
#define BLOCKS_MOVE_TILE (WALL_TILE | BLOCK_TILE | PUSHWALL_TILE | ACTOR_TILE)
|
||||
#define WAYPOINT_TILE (TILE_IS_E_TURN | TILE_IS_NE_TURN | TILE_IS_N_TURN | TILE_IS_NW_TURN | TILE_IS_W_TURN | TILE_IS_SW_TURN | TILE_IS_S_TURN | TILE_IS_SE_TURN )
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Doors
|
||||
//
|
||||
///////////////////
|
||||
typedef enum
|
||||
{
|
||||
dr_closing = -1,
|
||||
dr_closed,
|
||||
dr_opening,
|
||||
dr_open
|
||||
|
||||
} dr_state;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int tilex, tiley;
|
||||
_boolean vertical;
|
||||
int ticcount;
|
||||
|
||||
dr_state action;
|
||||
|
||||
int area1, area2;
|
||||
/*DOOR_VERT 255
|
||||
DOOR_HORIZ 254
|
||||
DOOR_E_VERT 253
|
||||
DOOR_E_HORIZ 252
|
||||
DOOR_G_VERT 251
|
||||
DOOR_G_HORIZ 250
|
||||
DOOR_S_VERT 249
|
||||
DOOR_S_HORIZ 248*/
|
||||
int type;
|
||||
|
||||
int texture;
|
||||
|
||||
} doors_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int doornum;
|
||||
doors_t *Doors[ 256 ];
|
||||
doors_t DoorMap[ 64 ][ 64 ];
|
||||
|
||||
} LevelDoors_t;
|
||||
|
||||
#define MAX_POWERUPS 1000
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Level
|
||||
//
|
||||
///////////////////
|
||||
typedef struct
|
||||
{
|
||||
char fname[ 32 ]; /* Map filename */
|
||||
|
||||
W16 Plane1[ 64 * 64 ]; /* walls */
|
||||
W16 Plane2[ 64 * 64 ]; /* objects */
|
||||
W16 Plane3[ 64 * 64 ]; /* other */
|
||||
|
||||
|
||||
long tilemap[ 64 ][ 64 ]; // wall values only
|
||||
W8 spotvis[ 64 ][ 64 ];
|
||||
// objtype *actorat[ 64 ][ 64 ];
|
||||
|
||||
// this is an array of references to texture descriptions
|
||||
// the renderer must know what to draw by this number
|
||||
int wall_tex_x[ 64 ][ 64 ]; // x_wall
|
||||
int wall_tex_y[ 64 ][ 64 ]; // y_wall
|
||||
|
||||
// this is a (0-based) array of area numbers!
|
||||
// must be all filled by level loading sub
|
||||
// if -1 it is a wall, if -2 it is a door, if -3 it is unknown
|
||||
int areas[ 64 ][ 64 ];
|
||||
|
||||
LevelDoors_t Doors;
|
||||
|
||||
placeonplane_t pSpawn; // player spawn place
|
||||
|
||||
powerup_t powerups[MAX_POWERUPS];
|
||||
int numPowerups;
|
||||
|
||||
sprite_t sprites[ MAX_SPRITES ];
|
||||
int numSprites;
|
||||
|
||||
char mapName[128]; /* Map name */
|
||||
char musicName[128]; /* Music file name */
|
||||
|
||||
colour3_t ceilingColour, floorColour;
|
||||
|
||||
W8 tileEverVisible[ 64 ][ 64 ]; // for automap
|
||||
} LevelData_t;
|
||||
|
||||
|
||||
typedef struct statinfo_t
|
||||
{
|
||||
_boolean block;
|
||||
int powerup;
|
||||
|
||||
} statinfo_t;
|
||||
|
||||
|
||||
extern LevelData_t *r_world;
|
||||
extern LevelData_t levelData;
|
||||
|
||||
extern LevelData_t *Level_LoadMap( const char *levelname );
|
||||
extern void Level_PrecacheTextures_Sound( LevelData_t *lvl );
|
||||
extern _boolean Level_CheckLine( SW32 x1, SW32 y1, SW32 x2, SW32 y2, LevelData_t *lvl );
|
||||
extern void Level_ScanInfoPlane( LevelData_t *lvl );
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Doors
|
||||
//
|
||||
///////////////////
|
||||
extern void Door_ResetDoors( LevelDoors_t *lvl );
|
||||
extern int Door_SpawnDoor( LevelDoors_t *lvl, int x, int y, int type );
|
||||
extern void Door_SetAreas( LevelDoors_t *lvl, int (*areas)[64] );
|
||||
extern void Door_OpenDoor( doors_t *Door );
|
||||
extern void Door_ProcessDoors_e( LevelDoors_t *lvl, int t_tk );
|
||||
extern int Door_Opened( LevelDoors_t *lvl, int x, int y );
|
||||
extern _boolean Door_TryUse( doors_t *Door, int keys );
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Areas
|
||||
//
|
||||
///////////////////
|
||||
extern _boolean areabyplayer[ NUMAREAS ];
|
||||
|
||||
extern void Areas_ConnectAreas( int areanumber );
|
||||
extern void Areas_InitAreas( int areanumber );
|
||||
extern void Areas_JoinAreas( int area1, int area2 );
|
||||
extern void Areas_DisconnectAreas( int area1, int area2 );
|
||||
|
||||
|
||||
///////////////////
|
||||
//
|
||||
// Push Walls
|
||||
//
|
||||
///////////////////
|
||||
typedef struct
|
||||
{
|
||||
_boolean active;
|
||||
int PWtilesmoved;
|
||||
int PWpointsmoved;
|
||||
dir4type dir;
|
||||
int x, y;
|
||||
int dx, dy;
|
||||
int tex_x, tex_y;
|
||||
|
||||
} Pwall_t;
|
||||
|
||||
|
||||
extern Pwall_t PWall;
|
||||
|
||||
|
||||
extern void PushWall_Reset( void );
|
||||
extern _boolean PushWall_Push( int x, int y, dir4type dir );
|
||||
extern void PushWall_Process( void );
|
||||
|
||||
|
||||
#endif /* __WOLF_LEVEL_H__ */
|
||||
150
wolf3d/code/wolf/wolf_local.h
Normal file
150
wolf3d/code/wolf/wolf_local.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_local.h: Wolfenstein3-D init.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_main.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_LOCAL_H__
|
||||
#define __WOLF_LOCAL_H__
|
||||
|
||||
|
||||
// Game Version
|
||||
#define WOLFENSTEINWL6 0x00
|
||||
#define SPEAROFDESTINY 0x01
|
||||
|
||||
|
||||
|
||||
#define TILEGLOBAL 0x10000
|
||||
#define HALFTILE 0x8000
|
||||
#define TILESHIFT 16
|
||||
|
||||
#define MINDIST (0x5800)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum difficulty_e
|
||||
{
|
||||
gd_baby,
|
||||
gd_easy,
|
||||
gd_medium,
|
||||
gd_hard
|
||||
|
||||
} difficulty_t;
|
||||
|
||||
//
|
||||
// this structure is cleared as each map is entered
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int framenum;
|
||||
float time;
|
||||
|
||||
char level_name[ MAX_OSPATH ]; // the descriptive name (Outer Base, etc)
|
||||
char mapname[ MAX_OSPATH ]; // the server name (base1, etc)
|
||||
char nextmap[ MAX_OSPATH ]; // go here when fraglimit is hit
|
||||
|
||||
// intermission state
|
||||
W32 levelCompleted; // in case the game was saved at the intermission
|
||||
|
||||
W32 floornum;
|
||||
float fpartime;
|
||||
char spartime[6];
|
||||
|
||||
W32 total_secrets;
|
||||
W32 found_secrets;
|
||||
|
||||
W32 total_treasure;
|
||||
W32 found_treasure;
|
||||
|
||||
W32 total_monsters;
|
||||
W32 killed_monsters;
|
||||
|
||||
|
||||
} level_locals_t;
|
||||
|
||||
|
||||
|
||||
extern level_locals_t levelstate;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
W32 total_secrets;
|
||||
W32 found_secrets;
|
||||
|
||||
W32 total_treasure;
|
||||
W32 found_treasure;
|
||||
|
||||
W32 total_monsters;
|
||||
W32 killed_monsters;
|
||||
W32 time;
|
||||
|
||||
} LRstruct;
|
||||
|
||||
|
||||
extern LRstruct LevelRatios;
|
||||
|
||||
|
||||
|
||||
extern cvar_t *g_version;
|
||||
extern cvar_t *episode;
|
||||
extern cvar_t *skill;
|
||||
|
||||
extern int tics;
|
||||
|
||||
|
||||
W32 floornumber;
|
||||
|
||||
|
||||
extern void Game_Init( void );
|
||||
extern void Game_Reset( void );
|
||||
|
||||
|
||||
|
||||
extern void ProcessGuards( void );
|
||||
|
||||
|
||||
#define WL6SPRITESDIRNAME "sprites"
|
||||
#define SODSPRITESDIRNAME "sodsprites"
|
||||
|
||||
|
||||
extern char *spritelocation;
|
||||
|
||||
|
||||
|
||||
#endif /* __WOLF_LOCAL_H__ */
|
||||
87
wolf3d/code/wolf/wolf_main.c
Normal file
87
wolf3d/code/wolf/wolf_main.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004-2005 Michael Liebscher
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
level_locals_t levelstate;
|
||||
|
||||
LRstruct LevelRatios;
|
||||
|
||||
cvar_t *g_version; // Wolfenstein or Spear of Destiny
|
||||
cvar_t *episode;
|
||||
cvar_t *skill;
|
||||
|
||||
|
||||
char *spritelocation = WL6SPRITESDIRNAME;
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Game_Reset( void )
|
||||
{
|
||||
memset( &levelstate, 0, sizeof( levelstate ) );
|
||||
}
|
||||
|
||||
extern void Map_f( void );
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Game_Init( void )
|
||||
{
|
||||
Com_Printf( "\n------ Game Init ------\n" );
|
||||
|
||||
episode = Cvar_Get( "episode", "0", CVAR_ARCHIVE );
|
||||
skill = Cvar_Get( "skill", "1", CVAR_ARCHIVE );
|
||||
g_version = Cvar_Get( "g_version", "0", CVAR_ARCHIVE );
|
||||
|
||||
#ifndef LITE
|
||||
Cmd_AddCommand( "map", Map_f );
|
||||
#endif
|
||||
|
||||
G_Build_Tables();
|
||||
Powerup_Reset();
|
||||
Sprite_Reset();
|
||||
Game_Reset();
|
||||
PL_Init();
|
||||
|
||||
Com_Printf( "\n-----------------------\n" );
|
||||
|
||||
}
|
||||
341
wolf3d/code/wolf/wolf_math.c
Normal file
341
wolf3d/code/wolf/wolf_math.c
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_math.c: Wolfenstein 3-D math routines.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
#define XRES 640
|
||||
#define YRES 480
|
||||
|
||||
// ------------------------- * LUTs * -------------------------
|
||||
double SinTable[ ANG_360 + ANG_90 + 1 ],
|
||||
*CosTable = SinTable + ANG_90,
|
||||
TanTable[ ANG_360 + 1 ];
|
||||
|
||||
int XnextTable[ ANG_360 + 1 ],
|
||||
YnextTable[ ANG_360 + 1 ];
|
||||
|
||||
int ColumnAngle[ 640 ]; // ViewAngle=PlayerAngle+ColumnAngle[curcolumn]; /in fines/
|
||||
|
||||
char dx4dir[5]={1, 0, -1, 0, 0}; // dx & dy based on direction
|
||||
char dy4dir[5]={0, 1, 0, -1, 0};
|
||||
char dx8dir[9]={1, 1, 0, -1, -1, -1, 0, 1, 0}; // dx & dy based on direction
|
||||
char dy8dir[9]={0, 1, 1, 1, 0, -1, -1, -1, 0};
|
||||
dir4type opposite4[5]={2, 3, 0, 1, 4};
|
||||
dir8type opposite8[9]={4, 5, 6, 7, 0, 1, 2, 3, 8};
|
||||
dir8type dir4to8[5]={0, 2, 4, 6, 8};
|
||||
dir8type diagonal[9][9]=
|
||||
{
|
||||
/* east */ {dir8_nodir, dir8_nodir, dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southeast, dir8_nodir, dir8_nodir},
|
||||
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
/* north */ {dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
/* west */ {dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir},
|
||||
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
/* south */ {dir8_southeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
|
||||
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir}
|
||||
};
|
||||
// dir of delta tooks dx{-1|0|1}+1 & dy{-1|0|1}+1 and give direction
|
||||
dir4type dir4d[3][3]={{dir4_nodir, dir4_west , dir4_nodir},
|
||||
{dir4_south, dir4_nodir, dir4_north},
|
||||
{dir4_nodir, dir4_east , dir4_nodir}};
|
||||
int dir8angle[9]={ANG_0, ANG_45, ANG_90, ANG_135, ANG_180, ANG_225, ANG_270, ANG_315, ANG_0};
|
||||
int dir4angle[5]={ANG_0, ANG_90, ANG_180, ANG_270, ANG_0};
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int G_Build_Tables( void )
|
||||
{
|
||||
double angle, tanfov2, tanval, value;
|
||||
int n;
|
||||
|
||||
for( n = 0 ; n <= ANG_90 ; ++n )
|
||||
{
|
||||
angle = FINE2RAD( n );
|
||||
|
||||
value = sin( angle );
|
||||
SinTable[ n ] = SinTable[ ANG_180 - n ] = SinTable[ n + ANG_360 ] = value;
|
||||
SinTable[ ANG_180 + n ] = SinTable[ ANG_360 - n ] = -value;
|
||||
}
|
||||
|
||||
for( n = 0 ; n <= ANG_360 ; ++n )
|
||||
{
|
||||
angle = FINE2RAD( n ); //angle is in radians, n is in FINEs
|
||||
|
||||
if( n == ANG_90 || n == ANG_270 )
|
||||
{
|
||||
TanTable[ n ] = tan( FINE2RAD( n - 0.5 ) ); // infinity
|
||||
YnextTable[ n ] = (int)(FLOATTILE * tan( FINE2RAD( n - 0.5 ) )); // infinity
|
||||
}
|
||||
else
|
||||
{
|
||||
TanTable[ n ] = tan( angle );
|
||||
YnextTable[ n ] = (int)(FLOATTILE * tan( angle ));
|
||||
}
|
||||
|
||||
if( n == ANG_0 || n == ANG_360 )
|
||||
XnextTable[ n ] = (int)(FLOATTILE / tan( FINE2RAD( n + 0.5 ) )); // infinity
|
||||
else if( n == ANG_180 )
|
||||
XnextTable[ n ] = (int)(FLOATTILE / tan(FINE2RAD( n - 0.5 ) )); // -infinity
|
||||
else if( n == ANG_90 || n == ANG_270 )
|
||||
XnextTable[ n ] = 0;
|
||||
else
|
||||
XnextTable[ n ] = (int)(FLOATTILE / tan( angle ));
|
||||
}
|
||||
|
||||
tanfov2 = TanDgr( CalcFov( 75, XRES, YRES) / 2.0 ) * ((float)XRES / (float)YRES );
|
||||
for( n = 0 ; n < XRES ; ++n )
|
||||
{
|
||||
tanval = tanfov2 * (-1.0 + 2.0 * (double)n / (double)(XRES-1) );
|
||||
ColumnAngle[ n ] = (int)RAD2FINE( atan( tanval ) );
|
||||
}
|
||||
|
||||
US_InitRndT( 1 ); // random number generators
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: NormalizeAngle -clips angle to [0..360] bounds.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int NormalizeAngle( int alpha )
|
||||
{
|
||||
if( alpha > ANG_360 )
|
||||
alpha %= ANG_360;
|
||||
|
||||
if(alpha<ANG_0)
|
||||
alpha = ANG_360 - (-alpha) % ANG_360;
|
||||
|
||||
return alpha;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC quadrant GetQuadrant( float angle )
|
||||
{
|
||||
angle = normalize_angle( angle );
|
||||
|
||||
if( angle < M_PI / 2 )
|
||||
{
|
||||
return q_first;
|
||||
}
|
||||
else if( angle < M_PI )
|
||||
{
|
||||
return q_second;
|
||||
}
|
||||
else if( angle < 3 * M_PI / 2 )
|
||||
{
|
||||
return q_third;
|
||||
}
|
||||
else
|
||||
{
|
||||
return q_fourth;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC dir4type Get4dir( float angle )
|
||||
{
|
||||
angle = normalize_angle( angle + M_PI / 4 );
|
||||
|
||||
if( angle < M_PI / 2 )
|
||||
{
|
||||
return dir4_east;
|
||||
}
|
||||
else if( angle < M_PI )
|
||||
{
|
||||
return dir4_north;
|
||||
}
|
||||
else if( angle < 3 * M_PI / 2 )
|
||||
{
|
||||
return dir4_west;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dir4_south;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Get8dir -Get 8 point direction.
|
||||
|
||||
Parameters: angle -[in] Radian angle.
|
||||
|
||||
Returns: Directional point.
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC dir8type Get8dir( float angle )
|
||||
{
|
||||
angle = normalize_angle( angle + M_PI / 12 );
|
||||
|
||||
if( angle <= (M_PI / 4) )
|
||||
{
|
||||
return dir8_east;
|
||||
}
|
||||
else if( angle < (M_PI / 2) )
|
||||
{
|
||||
return dir8_northeast;
|
||||
}
|
||||
else if( angle <= (3 * M_PI / 4) )
|
||||
{
|
||||
return dir8_north;
|
||||
}
|
||||
else if( angle < M_PI )
|
||||
{
|
||||
return dir8_northwest;
|
||||
}
|
||||
else if( angle <= (5 * M_PI / 4) )
|
||||
{
|
||||
return dir8_west;
|
||||
}
|
||||
else if( angle < (3 * M_PI / 2) )
|
||||
{
|
||||
return dir8_southwest;
|
||||
}
|
||||
else if( angle <= (7 * M_PI / 4) )
|
||||
{
|
||||
return dir8_south;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dir8_southeast;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Point2LineDist -calculates distance between a point (x, y) and
|
||||
a line.
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int Point2LineDist( int x, int y, int a )
|
||||
{
|
||||
return ABS( (int)(x * SinTable[ a ] - y * CosTable[ a ]) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: LineLen2Point -Calculates line length to the point nearest to (poin)
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int LineLen2Point( int x, int y, int a )
|
||||
{
|
||||
return (int)(x * CosTable[ a ] + y * SinTable[ a ] );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
Function returns angle in radians
|
||||
point2 = {x,y}
|
||||
/ |
|
||||
/ |
|
||||
/ |
|
||||
/a______|----------> x
|
||||
point1 = {x, y}
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y )
|
||||
{
|
||||
float angle;
|
||||
|
||||
angle = atan2( Point1Y - Point2Y, Point1X - Point2X );
|
||||
|
||||
return normalize_angle( angle );
|
||||
}
|
||||
|
||||
147
wolf3d/code/wolf/wolf_math.h
Normal file
147
wolf3d/code/wolf/wolf_math.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_math.h: Wolfenstein 3-D math routines.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_math.c
|
||||
|
||||
*/
|
||||
#ifndef __WOLF_MATH_H__
|
||||
#define __WOLF_MATH_H__
|
||||
|
||||
|
||||
#define FLOATTILE 65536.0f
|
||||
|
||||
|
||||
// Angle Direction Types & LUTs (Hard Coded! Please do not mess them)
|
||||
typedef enum {q_first, q_second, q_third, q_fourth} quadrant;
|
||||
typedef enum {dir4_east, dir4_north, dir4_west, dir4_south, dir4_nodir} dir4type;
|
||||
typedef enum { dir8_east, dir8_northeast, dir8_north, dir8_northwest, dir8_west,
|
||||
dir8_southwest, dir8_south, dir8_southeast, dir8_nodir} dir8type;
|
||||
|
||||
extern char dx4dir[5], dy4dir[5], dx8dir[9], dy8dir[9];
|
||||
extern dir4type opposite4[5], dir4d[3][3];
|
||||
extern dir8type opposite8[9], dir4to8[5], diagonal[9][9];
|
||||
extern int dir8angle[9], dir4angle[5];
|
||||
// ------------------------- * Vectors * -------------------------
|
||||
// Vectors & angles for 3D-Space
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long origin[2];
|
||||
long angle;
|
||||
|
||||
} placeonplane_t;
|
||||
|
||||
|
||||
// ------------------------- * Some Macroses * -------------------------
|
||||
|
||||
|
||||
#define max_of_2(a, b) ((a)>(b)?(a):(b))
|
||||
|
||||
|
||||
|
||||
#define LABS(x) ((long)(x)>0?(x):-(x))
|
||||
|
||||
|
||||
#define TILE2POS(a) (((a)<<TILESHIFT)+HALFTILE)
|
||||
#define POS2TILE(a) ((a)>>TILESHIFT)
|
||||
#define POS2TILEf(a) ((a)/FLOATTILE)
|
||||
// ------------------------- * vvv FINE angles vvv * -------------------------
|
||||
#define ASTEP 0.0078125f // 1 FINE=x DEGREES
|
||||
#define ASTEPRAD 0.000136354f // 1 FINE=x RADIANS
|
||||
#define ANG_1RAD 7333.8598 // 1 RADIAN=x FINES
|
||||
#define ANG_0 0 //(int)((float)0/ASTEP)
|
||||
#define ANG_1 128 //(int)((float)1/ASTEP)
|
||||
#define ANG_6 768 //(int)((float)6/ASTEP)
|
||||
#define ANG_15 1920 //(int)((float)15/ASTEP)
|
||||
#define ANG_22_5 2880 //(int)((float)22.5/ASTEP)
|
||||
#define ANG_30 3840 //(int)((float)30/ASTEP)
|
||||
#define ANG_45 5760 //(int)((float)45/ASTEP)
|
||||
#define ANG_67_5 8640 //(int)((float)67.5/ASTEP)
|
||||
#define ANG_90 11520 //(int)((float)90/ASTEP)
|
||||
#define ANG_112_5 14400 //(int)((float)112.5/ASTEP)
|
||||
#define ANG_135 17280 //(int)((float)135/ASTEP)
|
||||
#define ANG_157_5 20160 //(int)((float)157.5/ASTEP)
|
||||
#define ANG_180 23040 //(int)((float)180/ASTEP)
|
||||
#define ANG_202_5 25920 //(int)((float)202.5/ASTEP)
|
||||
#define ANG_225 28800 //(int)((float)225/ASTEP)
|
||||
#define ANG_247_5 31680 //(int)((float)247.5/ASTEP)
|
||||
#define ANG_270 34560 //(int)((float)270/ASTEP)
|
||||
#define ANG_292_5 37440 //(int)((float)292.5/ASTEP)
|
||||
#define ANG_315 40320 //(int)((float)225/ASTEP)
|
||||
#define ANG_337_5 43200 //(int)((float)337.5/ASTEP)
|
||||
#define ANG_360 46080 //(int)((float)360/ASTEP)
|
||||
// ------------------------- * ^^^ FINE angles ^^^ * -------------------------
|
||||
|
||||
|
||||
|
||||
#define FINE2RAD( a ) (((a) * M_PI ) / ANG_180)
|
||||
#define RAD2FINE( a ) (((a) * ANG_180) / M_PI)
|
||||
#define FINE2DEG( a ) ((float)(a) / ANG_1) // !@# don't lose precision bits
|
||||
#define FINE2DEGf( a ) ((a) / (float)ANG_1)
|
||||
#define DEG2FINE( a ) ((a) * ANG_1)
|
||||
|
||||
extern double SinTable[], *CosTable, TanTable[ ANG_360 + 1 ];
|
||||
extern int XnextTable[ ANG_360 + 1], YnextTable[ ANG_360 + 1 ];
|
||||
extern int ColumnAngle[640]; //
|
||||
|
||||
extern int G_Build_Tables(void);
|
||||
|
||||
#define TanDgr( x ) (tan( DEG2RAD( x ) ))
|
||||
#define SinDgr( x ) (sin( DEG2RAD( x ) ))
|
||||
#define CosDgr( x ) (cos( DEG2RAD( x ) ))
|
||||
|
||||
#define ArcTanDgr( x ) (RAD2DEG( atan( x ) ))
|
||||
#define ArcSinDgr( x ) (RAD2DEG( asin( x ) ))
|
||||
#define ArcCosDgr( x ) (RAD2DEG( acos( x ) ))
|
||||
|
||||
|
||||
|
||||
extern int NormalizeAngle( int angle );
|
||||
extern int Point2LineDist( int x, int y, int a );
|
||||
extern int LineLen2Point( int x, int y, int a );
|
||||
|
||||
extern quadrant GetQuadrant( float angle );
|
||||
extern dir4type Get4dir( float angle );
|
||||
extern dir8type Get8dir( float angle );
|
||||
|
||||
extern float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __WOLF_MATH_H__ */
|
||||
518
wolf3d/code/wolf/wolf_opengl.c
Normal file
518
wolf3d/code/wolf/wolf_opengl.c
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_opengl.c: Wolfenstein3-D OpenGL renderer.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Quake II, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
// width and height in 2D
|
||||
#define WIDTH_2D 640
|
||||
#define HEIGHT_2D 480
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void GL_SetDefaultState( void )
|
||||
{
|
||||
pfglClearColor( 1,0, 0.5 , 0.5 );
|
||||
pfglCullFace( GL_FRONT );
|
||||
pfglEnable( GL_TEXTURE_2D );
|
||||
pfglDisable( GL_DEPTH_TEST );
|
||||
pfglDisable( GL_CULL_FACE );
|
||||
pfglDisable( GL_BLEND );
|
||||
pfglColor4f( 1, 1, 1, 1 );
|
||||
pfglShadeModel( GL_FLAT );
|
||||
pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_DrawBox( int x, int y, int w, int h, W32 color )
|
||||
{
|
||||
pfglDisable( GL_TEXTURE_2D );
|
||||
|
||||
// pfglEnable( GL_BLEND );
|
||||
// pfglBlendFunc( GL_SRC_COLOR, GL_DST_COLOR );
|
||||
|
||||
pfglColor4ubv( (GLubyte *) & color );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
pfglVertex2i( x, y );
|
||||
pfglVertex2i( x, y + h);
|
||||
pfglVertex2i( x + w, y + h );
|
||||
pfglVertex2i( x + w, y );
|
||||
|
||||
pfglEnd();
|
||||
|
||||
pfglColor3f( 1, 1, 1 );
|
||||
// pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
// pfglDisable( GL_BLEND );
|
||||
pfglEnable( GL_TEXTURE_2D );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
LoadWallTexture
|
||||
|
||||
Returns with the texture bound and glColor set to the right intensity.
|
||||
Loads an image from the filesystem if necessary.
|
||||
Used both during gameplay and for preloading during level parse.
|
||||
|
||||
Wolfenstein was very wasteful with texture usage, making almost half of
|
||||
the textures just dim versions to provide "lighting" on the different
|
||||
wall sides. With only a few exceptions for things like the elevator tiles
|
||||
and outdoor tiles that could only be used in particular orientations
|
||||
====================
|
||||
*/
|
||||
float wallBrightness[1000];
|
||||
void LoadWallTexture( int wallPicNum ) {
|
||||
assert( wallPicNum >= 0 && wallPicNum < 1000 );
|
||||
texture_t *twall = wallTextures[wallPicNum];
|
||||
if ( !twall ) {
|
||||
if ( ( wallPicNum & 1 ) &&
|
||||
wallPicNum != 31 &&
|
||||
wallPicNum != 41 &&
|
||||
wallPicNum != 43 &&
|
||||
wallPicNum != 133 ) {
|
||||
// this wallPicNum is just a dim version of another image
|
||||
|
||||
// load the brighter version
|
||||
LoadWallTexture( wallPicNum - 1 );
|
||||
// use the same texture
|
||||
twall = wallTextures[wallPicNum] = wallTextures[wallPicNum - 1];
|
||||
// at a dimmer intensity
|
||||
wallBrightness[wallPicNum] = 0.7f;
|
||||
} else {
|
||||
// this wallPicNum has a real image associated with it
|
||||
char name[1024];
|
||||
my_snprintf( name, sizeof( name ), "walls/%.3d.tga", wallPicNum );
|
||||
twall = wallTextures[wallPicNum] = TM_FindTexture( name, TT_Wall );
|
||||
wallBrightness[wallPicNum] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
R_Bind( twall->texnum );
|
||||
|
||||
// almost half of the walls are just slightly dimmer versions of
|
||||
// the "bright side", and are not stored as separate textures
|
||||
float f = wallBrightness[wallPicNum];
|
||||
pfglColor3f( f, f, f );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
north (y)
|
||||
__________
|
||||
| |
|
||||
west (x) | | east (x)
|
||||
|________|
|
||||
south (y)
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_Draw_Wall( float x, float y, float z1, float z2, int type, int tex )
|
||||
{
|
||||
float x1, x2, y1, y2;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
// X wall
|
||||
case dir4_east:
|
||||
x1 = x2 = x + 1;
|
||||
y1 = -1 - y;
|
||||
y2 = -y;
|
||||
break;
|
||||
|
||||
case dir4_west:
|
||||
x1 = x2 = x;
|
||||
y1 = -y;
|
||||
y2 = -1 - y;
|
||||
break;
|
||||
|
||||
// Y wall
|
||||
case dir4_north:
|
||||
y1 = y2 = -y - 1;
|
||||
x1 = x;
|
||||
x2 = x + 1;
|
||||
break;
|
||||
|
||||
case dir4_south:
|
||||
y1 = y2 = -y;
|
||||
x1 = x + 1;
|
||||
x2 = x;
|
||||
break;
|
||||
}
|
||||
|
||||
LoadWallTexture( tex );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( x1, z2, y1 );
|
||||
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( x2, z2, y2 );
|
||||
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( x2, z1, y2 );
|
||||
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( x1, z1, y1 );
|
||||
|
||||
pfglEnd();
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_Draw_Door( int x, int y, float z1, float z2, _boolean vertical, _boolean backside, int tex, int amount )
|
||||
{
|
||||
float x1, x2, y1, y2, amt;
|
||||
|
||||
if( amount == DOOR_FULLOPEN )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
amt = (float)amount / DOOR_FULLOPEN;
|
||||
|
||||
|
||||
if( vertical )
|
||||
{
|
||||
x1 = x2 = (float)x + 0.5f;
|
||||
y1 = -((float)y - amt);
|
||||
y2 = -((float)y - amt); // -1
|
||||
if( backside )
|
||||
{
|
||||
y1 -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y2 -= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
y1 = y2 = -(float)y - 0.5f;
|
||||
x1 = (float)x + amt; // +1
|
||||
x2 = (float)x + amt;
|
||||
if( backside )
|
||||
{
|
||||
x2 += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 += 1;
|
||||
}
|
||||
}
|
||||
|
||||
LoadWallTexture( tex );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
pfglTexCoord2f( backside ? 0.0f : 1.0f, 0.0 ); pfglVertex3f( x1, z2, y1 );
|
||||
pfglTexCoord2f( backside ? 1.0f : 0.0f, 0.0 ); pfglVertex3f( x2, z2, y2 );
|
||||
pfglTexCoord2f( backside ? 1.0f : 0.0f, 1.0 ); pfglVertex3f( x2, z1, y2 );
|
||||
pfglTexCoord2f( backside ? 0.0f : 1.0f, 1.0 ); pfglVertex3f( x1, z1, y1 );
|
||||
|
||||
pfglEnd();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: R_DrawSprites -Draws all visible sprites.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_DrawSprites( void )
|
||||
{
|
||||
float sina, cosa;
|
||||
float Ex, Ey, Dx, Dy;
|
||||
int n_sprt, n, ang;
|
||||
texture_t *twall;
|
||||
extern cvar_t *cropSprites;
|
||||
|
||||
// build visible sprites list
|
||||
n_sprt = Sprite_CreateVisList();
|
||||
if( ! n_sprt )
|
||||
{
|
||||
return; // nothing to draw
|
||||
}
|
||||
|
||||
// prepare values for billboarding
|
||||
ang = NormalizeAngle( Player.position.angle + ANG_90 );
|
||||
sina = (float)(0.5 * SinTable[ ang ]);
|
||||
cosa = (float)(0.5 * CosTable[ ang ]);
|
||||
|
||||
pfglEnable( GL_BLEND );
|
||||
qglDepthMask( GL_FALSE );
|
||||
for( n = 0; n < n_sprt; ++n )
|
||||
{
|
||||
int texnum = vislist[ n ].tex;
|
||||
if( vislist[ n ].dist < MINDIST / 2 )
|
||||
{
|
||||
continue; // little hack to save speed & z-buffer
|
||||
}
|
||||
|
||||
|
||||
|
||||
assert( texnum >= 0 && texnum < 1000 );
|
||||
twall = spriteTextures[texnum];
|
||||
if ( !twall ) {
|
||||
char name[1024];
|
||||
my_snprintf( name, sizeof( name ), "%s/%.3d.tga", spritelocation, (vislist[ n ].tex) );
|
||||
twall = spriteTextures[texnum] = TM_FindTexture( name, TT_Wall );
|
||||
}
|
||||
R_Bind( twall->texnum );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
if ( cropSprites->value && twall->header.numBounds > 0 ) {
|
||||
// draw one or two subrects to avoid blending all the empty space
|
||||
int b;
|
||||
|
||||
for ( b = 0 ; b < twall->header.numBounds ; b++ ) {
|
||||
// include a bit extra for filtering
|
||||
float x1 = (float)(twall->header.bounds[b][0][0]-1) / (twall->header.uploadWidth-1);
|
||||
float y1 = (float)(twall->header.bounds[b][0][1]-1) / (twall->header.uploadHeight-1);
|
||||
float x2 = (float)(twall->header.bounds[b][1][0]+1) / (twall->header.uploadWidth-1);
|
||||
float y2 = (float)(twall->header.bounds[b][1][1]+1) / (twall->header.uploadHeight-1);
|
||||
if ( x1 < 0 ) {
|
||||
x1 = 0;
|
||||
} else if ( x2 > 1.0 ) {
|
||||
x2 = 1.0;
|
||||
}
|
||||
if ( y1 < 0 ) {
|
||||
y1 = 0;
|
||||
} else if ( y2 > 1.0 ) {
|
||||
y2 = 1.0;
|
||||
}
|
||||
Ex = vislist[ n ].x / FLOATTILE + cosa;
|
||||
Ey = vislist[ n ].y / FLOATTILE + sina;
|
||||
|
||||
pfglTexCoord2f( x1, y1 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x1 * 2*sina );
|
||||
pfglTexCoord2f( x1, y2 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x1 * 2*sina );
|
||||
pfglTexCoord2f( x2, y2 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x2 * 2*sina );
|
||||
pfglTexCoord2f( x2, y1 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x2 * 2*sina );
|
||||
}
|
||||
} else {
|
||||
Ex = Dx = vislist[ n ].x / FLOATTILE;
|
||||
Ey = Dy = vislist[ n ].y / FLOATTILE;
|
||||
Ex += cosa; Ey += sina;
|
||||
Dx -= cosa; Dy -= sina;
|
||||
|
||||
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( Ex, UPPERZCOORD, -Ey );
|
||||
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( Ex, LOWERZCOORD, -Ey );
|
||||
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( Dx, LOWERZCOORD, -Dy );
|
||||
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( Dx, UPPERZCOORD, -Dy );
|
||||
}
|
||||
|
||||
pfglEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_DrawNumber( int x, int y, int number )
|
||||
{
|
||||
texture_t *tex;
|
||||
int col;
|
||||
float fcol;
|
||||
static float w = 0.1f;
|
||||
int i;
|
||||
char string[ 20 ];
|
||||
W32 length;
|
||||
|
||||
|
||||
my_snprintf( string, sizeof( string ), "%d", number );
|
||||
length = strlen( string );
|
||||
|
||||
tex = TM_FindTexture( "pics/N_NUMPIC.tga", TT_Pic );
|
||||
|
||||
|
||||
pfglEnable( GL_TEXTURE_2D );
|
||||
|
||||
R_Bind( tex->texnum );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
for( i = length-1 ; i >= 0 ; --i )
|
||||
{
|
||||
col = string[ i ] - 48;
|
||||
|
||||
fcol = col * w;
|
||||
|
||||
pfglTexCoord2f( fcol, 0 ); pfglVertex2i( x, y );
|
||||
pfglTexCoord2f( fcol+w, 0 ); pfglVertex2i( x+18, y );
|
||||
pfglTexCoord2f( fcol+w, 1 ); pfglVertex2i( x+18, y+32 );
|
||||
pfglTexCoord2f( fcol, 1 ); pfglVertex2i( x, y+32 );
|
||||
|
||||
x -= 18;
|
||||
}
|
||||
|
||||
pfglEnd();
|
||||
|
||||
}
|
||||
|
||||
|
||||
W8 wfont[ ] = {
|
||||
32, 15, 32, 32, 32, 32, 32, 12, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 };
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_put_line( int x, int y, const char *string )
|
||||
{
|
||||
texture_t *tex;
|
||||
int mx = x;
|
||||
int num;
|
||||
float frow, fcol;
|
||||
static float h = 0.25f; // (32 / 128.0f);
|
||||
static float w = 0.0625f; // (32 / 512.0f);
|
||||
|
||||
|
||||
tex = TM_FindTexture( "pics/L_FONTPIC.tga", TT_Pic );
|
||||
|
||||
|
||||
R_Bind( tex->texnum );
|
||||
|
||||
pfglBegin( GL_QUADS );
|
||||
|
||||
while( *string )
|
||||
{
|
||||
if( *string == '\n' )
|
||||
{
|
||||
mx = x;
|
||||
y += 32;
|
||||
++string;
|
||||
continue;
|
||||
}
|
||||
|
||||
num = *string;
|
||||
|
||||
num &= 255;
|
||||
|
||||
if( (num & 127) == 32 )
|
||||
{
|
||||
mx += 32;
|
||||
++string;
|
||||
continue; // space
|
||||
}
|
||||
|
||||
|
||||
frow = ((num >> 4) - 2) * h;
|
||||
fcol = (num & 15) * w;
|
||||
|
||||
|
||||
pfglTexCoord2f( fcol, frow ); pfglVertex2i( mx, y );
|
||||
pfglTexCoord2f( fcol+w, frow ); pfglVertex2i( mx+32, y );
|
||||
pfglTexCoord2f( fcol+w, frow+h ); pfglVertex2i( mx+32, y+32 );
|
||||
pfglTexCoord2f( fcol, frow+h ); pfglVertex2i( mx, y+32 );
|
||||
|
||||
|
||||
|
||||
mx += wfont[ (num & 127) - 32 ];
|
||||
++string;
|
||||
}
|
||||
|
||||
pfglEnd();
|
||||
}
|
||||
|
||||
982
wolf3d/code/wolf/wolf_player.c
Normal file
982
wolf3d/code/wolf/wolf_player.c
Normal file
@@ -0,0 +1,982 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_player.c: Wolfenstein3-D player management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
player_t Player; // player struct (pos, health etc...)
|
||||
|
||||
|
||||
#define PLAYERSIZE MINDIST // player radius
|
||||
|
||||
|
||||
|
||||
struct atkinf
|
||||
{
|
||||
char tics, attack, frame; // attack is 1 for gun, 2 for knife
|
||||
|
||||
} attackinfo[ 4 ][ 14 ] = // 4 guns, 14 frames max for every gun!
|
||||
{
|
||||
{ {6,0,1},{6,2,2},{6,0,3},{6,-1,0} },
|
||||
{ {6,0,1},{6,1,2},{6,0,3},{6,-1,0} },
|
||||
{ {6,0,1},{6,1,2},{6,3,3},{6,-1,0} },
|
||||
{ {6,0,1},{6,1,2},{6,4,3},{6,-1,0} },
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: true if player can change weapons, otherwise false.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE _boolean PL_ChangeWeapon( player_t *self, int weapon )
|
||||
{
|
||||
unsigned itemflag;
|
||||
|
||||
itemflag = ITEM_WEAPON_1 << weapon;
|
||||
|
||||
if( self->ammo[ AMMO_BULLETS ] == 0 && weapon != WEAPON_KNIFE )
|
||||
{
|
||||
// Com_Printf("Not enough ammo.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if( ! (self->items & itemflag) )
|
||||
{
|
||||
// Com_Printf( "No weapon.\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
self->weapon =
|
||||
self->pendingweapon = weapon;
|
||||
|
||||
self->attackframe =
|
||||
self->attackcount =
|
||||
self->weaponframe = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Called if player pressed USE button
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: returns true if player used something
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE _boolean PL_Use( player_t *self, LevelData_t *lvl )
|
||||
{
|
||||
int x, y, dir;
|
||||
|
||||
dir = Get4dir( FINE2RAD( self->position.angle ) );
|
||||
x = self->tilex + dx4dir[ dir ];
|
||||
y = self->tiley + dy4dir[ dir ];
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
|
||||
{
|
||||
return Door_TryUse( &lvl->Doors.DoorMap[ x ][ y ], Player.items );
|
||||
}
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & SECRET_TILE )
|
||||
{
|
||||
return PushWall_Push( x, y, dir );
|
||||
}
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & ELEVATOR_TILE )
|
||||
{
|
||||
int newtex;
|
||||
|
||||
switch( dir )
|
||||
{
|
||||
case dir4_east:
|
||||
case dir4_west:
|
||||
newtex = lvl->wall_tex_x[ x ][ y ] += 2;
|
||||
break;
|
||||
|
||||
case dir4_north:
|
||||
case dir4_south:
|
||||
return false; // don't allow to press elevator rails
|
||||
}
|
||||
|
||||
if( lvl->tilemap[ self->tilex ][ self->tiley ] & SECRETLEVEL_TILE )
|
||||
{
|
||||
self->playstate = ex_secretlevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->playstate = ex_complete;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/040.wav" ), 1, ATTN_NORM, 0 );
|
||||
|
||||
iphoneStartIntermission( 0 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/020.wav" ), 1, ATTN_NORM, 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define STOPSPEED 0x0D00
|
||||
#define FRICTION 0.25f
|
||||
#define MAXMOVE (MINDIST*2-1)
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: returns true if move ok
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE _boolean PL_TryMove( player_t *self, LevelData_t *lvl )
|
||||
{
|
||||
int xl, yl, xh, yh, x, y;
|
||||
int d, n;
|
||||
|
||||
xl = POS2TILE( Player.position.origin[ 0 ] - PLAYERSIZE );
|
||||
yl = POS2TILE( Player.position.origin[ 1 ] - PLAYERSIZE );
|
||||
xh = POS2TILE( Player.position.origin[ 0 ] + PLAYERSIZE );
|
||||
yh = POS2TILE( Player.position.origin[ 1 ] + PLAYERSIZE );
|
||||
|
||||
// Cheching for solid walls:
|
||||
for( y = yl ; y <= yh ; ++y )
|
||||
for( x = xl ; x <= xh ; ++x )
|
||||
{
|
||||
if( lvl->tilemap[ x ][ y ] & SOLID_TILE )
|
||||
return 0;
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & DOOR_TILE &&
|
||||
Door_Opened( &lvl->Doors, x, y) != DOOR_FULLOPEN ) {
|
||||
// iphone hack to allow player to move halfway into door tiles
|
||||
// if the player bounds doesn't cross the middle of the tile, let the move continue
|
||||
if ( abs( Player.position.origin[0] - TILE2POS( x ) ) <= 0x9000
|
||||
&& abs( Player.position.origin[1] - TILE2POS( y ) ) <= 0x9000 ) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check for actors
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( Guards[ n ].state >= st_die1 )
|
||||
continue;
|
||||
|
||||
d = self->position.origin[ 0 ] - Guards[ n ].x;
|
||||
|
||||
if( d < -MINACTORDIST || d > MINACTORDIST )
|
||||
continue;
|
||||
|
||||
d = self->position.origin[ 1 ] - Guards[ n ].y;
|
||||
|
||||
if( d < -MINACTORDIST || d > MINACTORDIST)
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void PL_ClipMove( player_t *self, int xmove, int ymove )
|
||||
{
|
||||
int basex, basey;
|
||||
|
||||
basex = self->position.origin[ 0 ];
|
||||
basey = self->position.origin[ 1 ];
|
||||
|
||||
self->position.origin[ 0 ] += xmove;
|
||||
self->position.origin[ 1 ] += ymove;
|
||||
if( PL_TryMove( self, r_world ) )
|
||||
{
|
||||
return; // we moved as we wanted
|
||||
}
|
||||
|
||||
//Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/000.wav" ), 1, ATTN_NORM, 0 );
|
||||
|
||||
if( xmove ) // don't bother if we don't move x!
|
||||
{
|
||||
self->position.origin[ 0 ] = basex + xmove;
|
||||
self->position.origin[ 1 ] = basey;
|
||||
if( PL_TryMove( self, r_world ) )
|
||||
{
|
||||
return; // May be we'll move only X direction?
|
||||
}
|
||||
}
|
||||
if( ymove ) // don't bother if we don't move y!
|
||||
{
|
||||
self->position.origin[ 0 ] = basex;
|
||||
self->position.origin[ 1 ] = basey + ymove;
|
||||
if( PL_TryMove( self, r_world ) )
|
||||
{
|
||||
return; // May be we'll move only Y direction?
|
||||
}
|
||||
}
|
||||
|
||||
// movement blocked; we must stay on one place... :(
|
||||
self->position.origin[ 0 ] = basex;
|
||||
self->position.origin[ 1 ] = basey;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Changes player's angle and position
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void PL_ControlMovement( player_t *self, LevelData_t *lvl )
|
||||
{
|
||||
int angle, speed;
|
||||
|
||||
// rotation
|
||||
angle = self->position.angle;
|
||||
|
||||
// if(cmd->forwardmove || cmd->sidemove)
|
||||
self->movx = self->movy = 0; // clear accumulated movement
|
||||
|
||||
if( Player.cmd.forwardmove )
|
||||
{
|
||||
speed = tics * Player.cmd.forwardmove;
|
||||
self->movx+=(int)(speed * CosTable[ angle ] );
|
||||
self->movy+=(int)(speed * SinTable[ angle ] );
|
||||
}
|
||||
if( Player.cmd.sidemove )
|
||||
{
|
||||
speed = tics * Player.cmd.sidemove;
|
||||
self->movx += (int)( speed * SinTable[ angle ] );
|
||||
self->movy -= (int)( speed * CosTable[ angle ] );
|
||||
}
|
||||
|
||||
if( ! self->movx && ! self->movy )
|
||||
return;
|
||||
|
||||
#ifdef SPEAR
|
||||
|
||||
funnyticount = 0; // ZERO FUNNY COUNTER IF MOVED! // FIXME!
|
||||
|
||||
#endif
|
||||
self->speed = self->movx + self->movy;
|
||||
|
||||
// bound movement
|
||||
if( self->movx > MAXMOVE )
|
||||
self->movx = MAXMOVE;
|
||||
else if( self->movx < -MAXMOVE )
|
||||
self->movx = -MAXMOVE;
|
||||
|
||||
if( self->movy > MAXMOVE )
|
||||
self->movy = MAXMOVE;
|
||||
else if( self->movy < -MAXMOVE )
|
||||
self->movy = -MAXMOVE;
|
||||
|
||||
// move player and clip movement to walls (check for no-clip mode here)
|
||||
PL_ClipMove( self, self->movx, self->movy );
|
||||
self->tilex = POS2TILE( self->position.origin[ 0 ] );
|
||||
self->tiley = POS2TILE( self->position.origin[ 1 ] );
|
||||
|
||||
// pick up items easier -- any tile you touch, instead of
|
||||
// just the midpoint tile
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for ( x = -1 ; x <= 1 ; x+= 2 ) {
|
||||
int tilex = POS2TILE( self->position.origin[0] + x * PLAYERSIZE );
|
||||
for ( y = -1 ; y <= 1 ; y+= 2 ) {
|
||||
int tiley = POS2TILE( self->position.origin[1] + y * PLAYERSIZE );
|
||||
Powerup_PickUp( tilex, tiley );
|
||||
}
|
||||
}
|
||||
}
|
||||
// Powerup_PickUp( self->tilex, self->tiley );
|
||||
|
||||
// Checking for area change, ambush tiles and doors will have negative values
|
||||
if( lvl->areas[ self->tilex ][ self->tiley ] >= 0 &&
|
||||
lvl->areas[ self->tilex ][ self->tiley ] != Player.areanumber )
|
||||
{
|
||||
Player.areanumber = lvl->areas[ self->tilex ][ self->tiley ];
|
||||
assert( Player.areanumber >= 0 && Player.areanumber < NUMAREAS );
|
||||
Areas_ConnectAreas( Player.areanumber );
|
||||
}
|
||||
|
||||
if( lvl->tilemap[ self->tilex ][ self->tiley ] & EXIT_TILE )
|
||||
{
|
||||
iphoneStartIntermission( 0 );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void PL_PlayerAttack( player_t *self, _boolean re_attack )
|
||||
{
|
||||
struct atkinf *cur;
|
||||
|
||||
self->attackcount -= tics;
|
||||
while( self->attackcount <= 0 )
|
||||
{
|
||||
cur = &attackinfo[ self->weapon ][ self->attackframe ];
|
||||
switch( cur->attack )
|
||||
{
|
||||
case -1:
|
||||
self->flags &= ~PL_FLAG_ATTCK;
|
||||
if( ! self->ammo[ AMMO_BULLETS ] )
|
||||
{
|
||||
self->weapon = WEAPON_KNIFE;
|
||||
}
|
||||
else if( self->weapon != self->pendingweapon )
|
||||
{
|
||||
self->weapon = self->pendingweapon;
|
||||
}
|
||||
self->attackframe = self->weaponframe = 0;
|
||||
return;
|
||||
|
||||
case 4:
|
||||
if( ! self->ammo[ AMMO_BULLETS ] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( re_attack )
|
||||
{
|
||||
self->attackframe -= 2;
|
||||
}
|
||||
|
||||
case 1:
|
||||
if( ! self->ammo[ AMMO_BULLETS ] ) // can only happen with chain gun
|
||||
{
|
||||
self->attackframe++;
|
||||
break;
|
||||
}
|
||||
fire_lead( self );
|
||||
self->ammo[ AMMO_BULLETS ]--;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fire_hit( self );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(self->ammo[AMMO_BULLETS] && re_attack)
|
||||
self->attackframe-=2;
|
||||
break;
|
||||
}
|
||||
|
||||
self->attackcount += cur->tics;
|
||||
self->attackframe++;
|
||||
self->weaponframe = attackinfo[ self->weapon ][ self->attackframe ].frame;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_Process( player_t *self, LevelData_t *lvl )
|
||||
{
|
||||
int n;
|
||||
|
||||
self->madenoise = false;
|
||||
|
||||
PL_ControlMovement( self, lvl );
|
||||
|
||||
if( self->flags & PL_FLAG_ATTCK )
|
||||
{
|
||||
PL_PlayerAttack( self, Player.cmd.buttons & BUTTON_ATTACK );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( Player.cmd.buttons & BUTTON_USE )
|
||||
{
|
||||
if(!(self->flags & PL_FLAG_REUSE) && PL_Use( self, lvl ) )
|
||||
{
|
||||
self->flags|=PL_FLAG_REUSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self->flags &= ~PL_FLAG_REUSE;
|
||||
}
|
||||
|
||||
if( Player.cmd.buttons & BUTTON_ATTACK )
|
||||
{
|
||||
self->flags |= PL_FLAG_ATTCK;
|
||||
|
||||
self->attackframe = 0;
|
||||
self->attackcount = attackinfo[ self->weapon ][ 0 ].tics;
|
||||
self->weaponframe = attackinfo[ self->weapon ][ 0 ].frame;
|
||||
} else if ( Player.cmd.buttons & BUTTON_CHANGE_WEAPON ) {
|
||||
self->pendingweapon=self->weapon;
|
||||
for( n = 0 ; n < 4; ++n )
|
||||
{
|
||||
if( ++self->weapon > WEAPON_CHAIN )
|
||||
{
|
||||
self->weapon = WEAPON_KNIFE;
|
||||
}
|
||||
|
||||
if( PL_ChangeWeapon( self, self->weapon ) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
self->weapon = self->pendingweapon;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_Reset(void)
|
||||
{
|
||||
memset( &Player, 0, sizeof( Player ) );
|
||||
Player.playstate = ex_notingame;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_Spawn( placeonplane_t location, LevelData_t *lvl )
|
||||
{
|
||||
Player.position = location;
|
||||
Player.tilex = POS2TILE( location.origin[ 0 ] );
|
||||
Player.tiley = POS2TILE( location.origin[ 1 ] );
|
||||
Player.areanumber = lvl->areas[ Player.tilex ][ Player.tiley ];
|
||||
assert( Player.areanumber >= 0 && Player.areanumber < NUMAREAS );
|
||||
if( Player.areanumber < 0 )
|
||||
{
|
||||
Player.areanumber = 36;
|
||||
}
|
||||
|
||||
Areas_ConnectAreas( Player.areanumber );
|
||||
|
||||
char str[128];
|
||||
sprintf( str, "Entering level E%iM%i", currentMap.episode + 1, currentMap.map + 1 );
|
||||
iphoneSetNotifyText( str );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void Cmd_Give_f( void )
|
||||
{
|
||||
Com_Printf( "Giving stuff.\n" );
|
||||
PL_GiveHealth( &Player, 999, 0 );
|
||||
PL_GiveAmmo( &Player, AMMO_BULLETS, 99 );
|
||||
PL_GiveWeapon( &Player, WEAPON_AUTO );
|
||||
PL_GiveWeapon( &Player, WEAPON_CHAIN );
|
||||
PL_GiveKey( &Player, KEY_GOLD );
|
||||
PL_GiveKey( &Player, KEY_SILVER );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void Cmd_God_f( void )
|
||||
{
|
||||
Player.flags ^= FL_GODMODE;
|
||||
|
||||
Com_Printf( "God mode %s\n", Player.flags & FL_GODMODE ? "ON":"OFF" );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void PL_notarget_f( void )
|
||||
{
|
||||
Player.flags ^= FL_NOTARGET;
|
||||
Com_Printf( "Notarget mode %s\n", Player.flags & FL_NOTARGET ? "ON":"OFF" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_Init(void)
|
||||
{
|
||||
PL_Reset();
|
||||
PL_NewGame( &Player );
|
||||
|
||||
Cmd_AddCommand( "god", Cmd_God_f );
|
||||
Cmd_AddCommand( "notarget", PL_notarget_f );
|
||||
Cmd_AddCommand( "give", Cmd_Give_f );
|
||||
}
|
||||
|
||||
// ------------------------- * environment interraction * -------------------------
|
||||
#define EXTRAPOINTS 40000 // points for an extra life
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_Damage( player_t *self, entity_t *attacker, int points )
|
||||
{
|
||||
|
||||
if( self->playstate == ex_dead )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self->LastAttacker = attacker;
|
||||
|
||||
if( skill->value == gd_baby )
|
||||
{
|
||||
points >>= 2;
|
||||
}
|
||||
|
||||
// vibe the phone
|
||||
SysIPhoneVibrate();
|
||||
|
||||
// note the direction of the last hit for the directional blends
|
||||
{
|
||||
int dx = attacker->x - self->position.origin[0];
|
||||
int dy = attacker->y - self->position.origin[1];
|
||||
|
||||
// probably won't ever have damage from self, but check anyway
|
||||
if ( dx != 0 || dy != 0 ) {
|
||||
float angle = atan2f( dy, dx );
|
||||
float playerAngle = self->position.angle * 360.0f / (float)ANG_360;
|
||||
float deltaAngle;
|
||||
angle = angle * 180.0f / M_PI;
|
||||
if ( angle < 0 ) {
|
||||
angle = 360 + angle;
|
||||
}
|
||||
deltaAngle = angle - playerAngle;
|
||||
if ( deltaAngle > 180 ) {
|
||||
deltaAngle = deltaAngle - 360;
|
||||
}
|
||||
if ( deltaAngle < -180 ) {
|
||||
deltaAngle = 360 + deltaAngle;
|
||||
}
|
||||
// Com_Printf( "damage: player angle: %4.0f shotAngle: %4.0f deltaAngle:%4.0f\n", playerAngle, angle, deltaAngle );
|
||||
if ( deltaAngle > 40 ) {
|
||||
iphoneSetAttackDirection( 1 );
|
||||
} else if ( deltaAngle < -40 ) {
|
||||
iphoneSetAttackDirection( -1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do everything else but subtract health in god mode, to ease
|
||||
// testing of damage feedback
|
||||
if( !(self->flags & FL_GODMODE) )
|
||||
{
|
||||
self->health -= points;
|
||||
}
|
||||
|
||||
if( self->health <= 0 )
|
||||
{
|
||||
// dead
|
||||
self->health = 0;
|
||||
self->playstate = ex_dead;
|
||||
|
||||
Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/009.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
|
||||
// red screen flash
|
||||
iphoneStartDamageFlash( points );
|
||||
|
||||
// stop the happy grin face if shot before it times out
|
||||
Player.face_gotgun = false;
|
||||
|
||||
// make BJ's eyes bulge on huge hits
|
||||
if( points > 30 && Player.health != 0 )
|
||||
{
|
||||
Player.face_ouch = true;
|
||||
Player.facecount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: returns true if player needs this health.
|
||||
|
||||
Notes:
|
||||
gives player some HP
|
||||
max can be:
|
||||
0 - natural player's health limit (100 or 150 with augment)
|
||||
>0 - indicates the limit
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC _boolean PL_GiveHealth( player_t *self, int points, int max )
|
||||
{
|
||||
if( max == 0 )
|
||||
{
|
||||
max = (self->items & ITEM_AUGMENT) ? 150 : 100;
|
||||
}
|
||||
|
||||
if( self->health >= max )
|
||||
{
|
||||
return false; // doesn't need this health
|
||||
}
|
||||
|
||||
self->health += points;
|
||||
|
||||
if( self->health > max )
|
||||
{
|
||||
self->health = max;
|
||||
}
|
||||
|
||||
Player.face_gotgun = false;
|
||||
|
||||
return true; // took it
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: returns true if player needs this ammo
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC _boolean PL_GiveAmmo( player_t *self, int type, int ammo )
|
||||
{
|
||||
int max_ammo[ AMMO_TYPES ] = { 99 };
|
||||
int max;
|
||||
|
||||
max = max_ammo[ type ];
|
||||
if( self->items & ITEM_BACKPACK )
|
||||
{
|
||||
max *= 2;
|
||||
}
|
||||
|
||||
if( self->ammo[ type ] >= max )
|
||||
{
|
||||
return false; // don't need
|
||||
}
|
||||
|
||||
if( ! self->ammo[ type ] && ! self->attackframe ) // knife was out
|
||||
{
|
||||
self->weapon = self->pendingweapon;
|
||||
}
|
||||
|
||||
self->ammo[ type ] += ammo;
|
||||
if( self->ammo[ type ] > max )
|
||||
{
|
||||
self->ammo[ type ] = max;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_GiveWeapon( player_t *self, int weapon )
|
||||
{
|
||||
unsigned itemflag;
|
||||
|
||||
PL_GiveAmmo( self, AMMO_BULLETS, 6 ); // give some ammo with a weapon
|
||||
|
||||
itemflag = ITEM_WEAPON_1 << weapon;
|
||||
if( self->items & itemflag )
|
||||
{
|
||||
return; // player owns this weapon
|
||||
}
|
||||
else
|
||||
{
|
||||
self->items |= itemflag;
|
||||
if ( self->weapon < weapon ) { // don't switch if already using better weapon
|
||||
self->weapon = self->pendingweapon = weapon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_GivePoints( player_t *self, W32 points )
|
||||
{
|
||||
#if 0 // no score on iphone
|
||||
self->score += points;
|
||||
while( self->score >= self->next_extra )
|
||||
{
|
||||
self->next_extra += EXTRAPOINTS;
|
||||
PL_GiveLife( self );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_GiveKey( player_t *self, int key )
|
||||
{
|
||||
self->items |= ITEM_KEY_1 << key;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Set up player for the new game
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_NewGame( player_t *self )
|
||||
{
|
||||
memset( self, 0, sizeof( player_t ) );
|
||||
|
||||
self->health = 100;
|
||||
self->ammo[ AMMO_BULLETS ] = 16; // JDC: changed for iphone 8;
|
||||
self->lives = 3;
|
||||
|
||||
self->weapon = self->pendingweapon = WEAPON_PISTOL;
|
||||
self->items = ITEM_WEAPON_1 | ITEM_WEAPON_2;
|
||||
self->next_extra = EXTRAPOINTS;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Set up player for level transition
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PL_NextLevel( player_t *self )
|
||||
{
|
||||
self->old_score = self->score;
|
||||
self->attackcount = self->attackframe = self->weaponframe = 0;
|
||||
self->flags = 0;
|
||||
|
||||
self->items &= ~(ITEM_KEY_1 | ITEM_KEY_2 | ITEM_KEY_3 | ITEM_KEY_4);
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: self -[in] Player to respawn in game world.
|
||||
|
||||
Returns: returns false if no lives left
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC _boolean PL_Reborn( player_t *self )
|
||||
{
|
||||
#if 0 // removed game over from iphone version
|
||||
if( --self->lives < 1 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
self->health = 100;
|
||||
self->ammo[ AMMO_BULLETS ] = 16; // JDC: changed for iphone 8;
|
||||
self->score = self->old_score;
|
||||
self->attackcount = 0;
|
||||
self->attackframe = 0;
|
||||
self->weaponframe = 0;
|
||||
self->flags = 0;
|
||||
|
||||
self->weapon = self->pendingweapon = WEAPON_PISTOL;
|
||||
self->items = ITEM_WEAPON_1 | ITEM_WEAPON_2;
|
||||
|
||||
self->playstate = ex_playing;
|
||||
|
||||
return true;
|
||||
}
|
||||
179
wolf3d/code/wolf/wolf_player.h
Normal file
179
wolf3d/code/wolf/wolf_player.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_player.h: Wolfenstein3-D player management.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_player.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_PLAYER_H__
|
||||
#define __WOLF_PLAYER_H__
|
||||
|
||||
#define ITEM_KEY_1 1
|
||||
#define ITEM_KEY_2 2
|
||||
#define ITEM_KEY_3 4
|
||||
#define ITEM_KEY_4 8
|
||||
#define ITEM_WEAPON_1 16
|
||||
#define ITEM_WEAPON_2 32
|
||||
#define ITEM_WEAPON_3 64
|
||||
#define ITEM_WEAPON_4 128
|
||||
#define ITEM_WEAPON_5 256
|
||||
#define ITEM_WEAPON_6 512
|
||||
#define ITEM_WEAPON_7 1024
|
||||
#define ITEM_WEAPON_8 2048
|
||||
#define ITEM_BACKPACK (1<<12) // doubles carrying capacity
|
||||
#define ITEM_AUGMENT (1<<13) // adds 50 to maximum health
|
||||
#define ITEM_UNIFORM (1<<14) // allows you to pass guards
|
||||
#define ITEM_AUTOMAP (1<<15) // shows unknown map ares in other color (as in DooM)
|
||||
#define ITEM_FREE (1<<16) // - unused -
|
||||
|
||||
|
||||
enum weapon_e
|
||||
{
|
||||
WEAPON_KNIFE,
|
||||
WEAPON_PISTOL,
|
||||
WEAPON_AUTO,
|
||||
WEAPON_CHAIN,
|
||||
|
||||
WEAPON_TYPES
|
||||
};
|
||||
|
||||
enum key_e
|
||||
{
|
||||
KEY_GOLD,
|
||||
KEY_SILVER,
|
||||
KEY_FREE1,
|
||||
KEY_FREE2,
|
||||
|
||||
KEY_TYPES
|
||||
};
|
||||
|
||||
enum ammo_e
|
||||
{
|
||||
AMMO_BULLETS,
|
||||
|
||||
AMMO_TYPES
|
||||
};
|
||||
|
||||
|
||||
|
||||
// flags
|
||||
#define PL_FLAG_REUSE 1 // use button pressed
|
||||
#define PL_FLAG_ATTCK 2 // attacking
|
||||
// debug (cheat codes) flags
|
||||
#define FL_GODMODE (1<<4)
|
||||
#define FL_NOTARGET (1<<6)
|
||||
|
||||
|
||||
typedef enum state_e
|
||||
{
|
||||
ex_notingame,
|
||||
ex_playing,
|
||||
ex_dead,
|
||||
ex_secretlevel,
|
||||
ex_victory,
|
||||
ex_complete
|
||||
/*
|
||||
ex_stillplaying,
|
||||
ex_completed,
|
||||
ex_died,
|
||||
ex_warped,
|
||||
ex_resetgame,
|
||||
ex_loadedgame,
|
||||
ex_victorious,
|
||||
ex_abort,
|
||||
ex_demodone,
|
||||
ex_secretlevel
|
||||
*/
|
||||
} state_t;
|
||||
|
||||
// ------------------------- * types * -------------------------
|
||||
// Player structure: Holds all info about player
|
||||
typedef struct player_s
|
||||
{
|
||||
usercmd_t cmd; // movement / action command
|
||||
|
||||
placeonplane_t position; // player position
|
||||
int movx, movy, speed;
|
||||
int tilex, tiley;
|
||||
|
||||
// stats
|
||||
int health, lives, frags;
|
||||
int armor; // there are 2 types. The better one is indicated by high bit set
|
||||
int ammo[AMMO_TYPES];
|
||||
int old_score, score, next_extra;
|
||||
unsigned items; // (keys, weapon)
|
||||
int weapon, pendingweapon;
|
||||
// additional info
|
||||
int attackframe, attackcount, weaponframe; // attack info
|
||||
unsigned flags;
|
||||
int areanumber;
|
||||
|
||||
_boolean madenoise; // FIXME: move to flags?
|
||||
entity_t *LastAttacker;
|
||||
int faceframe, facecount; // bj's face in the HUD // FIXME decide something!
|
||||
_boolean face_gotgun, face_ouch;
|
||||
state_t playstate; // fixme: move to gamestate
|
||||
|
||||
} player_t;
|
||||
|
||||
extern player_t Player;
|
||||
|
||||
|
||||
|
||||
|
||||
extern void PL_Spawn( placeonplane_t location, LevelData_t *lvl );
|
||||
|
||||
extern void PL_Process( player_t *self, LevelData_t *lvl );
|
||||
|
||||
extern void PL_Damage( player_t *self, entity_t *attacker, int points );
|
||||
extern _boolean PL_GiveHealth( player_t *self, int points, int max );
|
||||
extern _boolean PL_GiveAmmo( player_t *self, int type, int ammo );
|
||||
extern void PL_GiveWeapon( player_t *self, int weapon );
|
||||
extern void PL_GivePoints( player_t *self, W32 points );
|
||||
extern void PL_GiveKey( player_t *self, int key );
|
||||
|
||||
extern void PL_NewGame( player_t *self );
|
||||
extern void PL_NextLevel( player_t *self );
|
||||
extern _boolean PL_Reborn( player_t *self );
|
||||
|
||||
extern void PL_Init( void );
|
||||
extern void PL_Reset( void );
|
||||
|
||||
|
||||
extern void fire_hit( player_t *self );
|
||||
extern void fire_lead( player_t *self );
|
||||
|
||||
|
||||
#endif /* __WOLF_PLAYER_H__ */
|
||||
385
wolf3d/code/wolf/wolf_powerups.c
Normal file
385
wolf3d/code/wolf/wolf_powerups.c
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2001 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_pushwalls.c: Wolfenstein3-D power-up handler.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
int Pow_Texture[ pow_last ] =
|
||||
{
|
||||
SPR_STAT_34, // pow_gibs
|
||||
SPR_STAT_38, // pow_gibs2
|
||||
SPR_STAT_6, // pow_alpo
|
||||
SPR_STAT_25, // pow_firstaid
|
||||
SPR_STAT_20, // pow_key1
|
||||
SPR_STAT_21, // pow_key2
|
||||
// not used
|
||||
SPR_STAT_20, // pow_key3
|
||||
SPR_STAT_20, // pow_key4
|
||||
|
||||
SPR_STAT_29, // pow_cross
|
||||
SPR_STAT_30, // pow_chalice
|
||||
SPR_STAT_31, // pow_bible
|
||||
SPR_STAT_32, // pow_crown
|
||||
SPR_STAT_26, // pow_clip
|
||||
SPR_STAT_26, // pow_clip2
|
||||
SPR_STAT_27, // pow_machinegun
|
||||
SPR_STAT_28, // pow_chaingun
|
||||
SPR_STAT_24, // pow_food
|
||||
SPR_STAT_33, // pow_fullheal
|
||||
// spear
|
||||
SPR_STAT_49, // pow_25clip
|
||||
SPR_STAT_51, // pow_spear
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void Pow_Remove( powerup_t *powerup )
|
||||
{
|
||||
powerup->x = -1;
|
||||
powerup->y = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE powerup_t *Pow_AddNew( void )
|
||||
{
|
||||
for ( int i = 0 ; i < levelData.numPowerups ; i++ ) {
|
||||
if ( levelData.powerups[i].x == -1 ) {
|
||||
return &levelData.powerups[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ( levelData.numPowerups == MAX_POWERUPS ) {
|
||||
return &levelData.powerups[0];
|
||||
}
|
||||
levelData.numPowerups++;
|
||||
return &levelData.powerups[levelData.numPowerups-1];
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Powerup_Reset( void )
|
||||
{
|
||||
levelData.numPowerups = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns: 1 if powerup is picked up, otherwise 0.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE int Pow_Give( pow_t type )
|
||||
{
|
||||
static const char *keynames[] = { "Gold", "Silver", "?", "?" };
|
||||
|
||||
switch( type )
|
||||
{
|
||||
//
|
||||
// Keys
|
||||
//
|
||||
case pow_key1:
|
||||
case pow_key2:
|
||||
case pow_key3:
|
||||
case pow_key4:
|
||||
type -= pow_key1;
|
||||
PL_GiveKey( &Player, type );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/012.wav" ), 1, ATTN_NORM, 0 );
|
||||
iphoneSetNotifyText( "%s key\n", keynames[ type ] );
|
||||
break;
|
||||
//
|
||||
// Treasure
|
||||
//
|
||||
case pow_cross:
|
||||
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
|
||||
PL_GivePoints( &Player, 100 );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/035.wav" ), 1, ATTN_NORM, 0 );
|
||||
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
|
||||
iphoneSetNotifyText( "You found the last treasure!" );
|
||||
}
|
||||
break;
|
||||
|
||||
case pow_chalice:
|
||||
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
|
||||
PL_GivePoints( &Player, 500 );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/036.wav" ), 1, ATTN_NORM, 0 );
|
||||
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
|
||||
iphoneSetNotifyText( "You found the last treasure!" );
|
||||
}
|
||||
break;
|
||||
|
||||
case pow_bible:
|
||||
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
|
||||
PL_GivePoints( &Player, 1000 );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/037.wav" ), 1, ATTN_NORM, 0 );
|
||||
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
|
||||
iphoneSetNotifyText( "You found the last treasure!" );
|
||||
}
|
||||
break;
|
||||
|
||||
case pow_crown:
|
||||
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
|
||||
PL_GivePoints( &Player, 5000 );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/045.wav" ), 1, ATTN_NORM, 0 );
|
||||
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
|
||||
iphoneSetNotifyText( "You found the last treasure!" );
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Health
|
||||
//
|
||||
case pow_gibs:
|
||||
if( ! PL_GiveHealth( &Player, 1, 11 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_alpo:
|
||||
if( ! PL_GiveHealth( &Player, 4, 0 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_food:
|
||||
if( ! PL_GiveHealth( &Player, 10, 0 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_firstaid:
|
||||
if( ! PL_GiveHealth( &Player, 25, 0 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/034.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
//
|
||||
// Weapon & Ammo
|
||||
//
|
||||
case pow_clip:
|
||||
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 8 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_clip2:
|
||||
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 4 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_25clip:
|
||||
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 25 ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/064.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case pow_machinegun:
|
||||
PL_GiveWeapon( &Player, WEAPON_AUTO );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/030.wav" ), 1, ATTN_NORM, 0 );
|
||||
iphoneSetNotifyText( "Machinegun" );
|
||||
break;
|
||||
|
||||
case pow_chaingun:
|
||||
PL_GiveWeapon( &Player, WEAPON_CHAIN );
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/038.wav" ), 1, ATTN_NORM, 0 );
|
||||
iphoneSetNotifyText( "Chaingun" );
|
||||
|
||||
Player.facecount = -100;
|
||||
Player.face_gotgun = true;
|
||||
break;
|
||||
|
||||
//
|
||||
// Artifacts
|
||||
//
|
||||
case pow_fullheal:
|
||||
// go to 150 health
|
||||
PL_GiveHealth( &Player, 150, 150 );
|
||||
PL_GiveAmmo( &Player, AMMO_BULLETS, 25 );
|
||||
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
|
||||
iphoneSetNotifyText( "You found the last treasure!" );
|
||||
} else {
|
||||
iphoneSetNotifyText( "Full Heal" );
|
||||
}
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/034.wav" ), 1, ATTN_NORM, 0 );
|
||||
// no extra lives on iPhone Com_Printf( "Extra life!\n" );
|
||||
break;
|
||||
|
||||
case pow_spear:
|
||||
{
|
||||
char szTextMsg[ 256 ];
|
||||
|
||||
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "sodsfx/109.wav" ), 1, ATTN_NORM, 0 );
|
||||
iphoneSetNotifyText( "Spear of Destiny" );
|
||||
|
||||
my_snprintf( szTextMsg, sizeof( szTextMsg ),
|
||||
"loading ; map s%.2d.map\n", 20 );
|
||||
Cbuf_AddText( szTextMsg );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Com_DPrintf( "Warning: Unknown item type: %d\n", type );
|
||||
break;
|
||||
}
|
||||
|
||||
iphoneStartBonusFlash();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: x, y -[in] In are in TILES.
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Powerup_Spawn( int x, int y, int type )
|
||||
{
|
||||
powerup_t *newp;
|
||||
|
||||
levelData.tilemap[ x ][ y ] |= POWERUP_TILE;
|
||||
newp = Pow_AddNew();
|
||||
newp->sprite = Sprite_GetNewSprite();
|
||||
Sprite_SetPos( newp->sprite, TILE2POS( newp->x = x ), TILE2POS( newp->y = y ), 0 );
|
||||
newp->type = type;
|
||||
Sprite_SetTex( newp->sprite, -1, Pow_Texture[ type ] );
|
||||
levelData.tilemap[ x ][ y ] |= POWERUP_TILE;
|
||||
// good place to update total treasure count!
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters: x, y -[in] In are in TILES.
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Powerup_PickUp( int x, int y )
|
||||
{
|
||||
int i;
|
||||
powerup_t *pow;
|
||||
_boolean p_left = false, p_pick = false;
|
||||
|
||||
for ( i = 0, pow = levelData.powerups ; i < levelData.numPowerups ; i++, pow++ ) {
|
||||
if( pow->x == x && pow->y == y)
|
||||
{// got a powerup here
|
||||
if( Pow_Give( pow->type ) ) //FIXME script
|
||||
{// picked up this stuff, remove it!
|
||||
p_pick = true;
|
||||
Sprite_RemoveSprite( pow->sprite );
|
||||
Pow_Remove( pow );
|
||||
}
|
||||
else
|
||||
{// player do not need it, so may be next time!
|
||||
p_left = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( p_left )
|
||||
{
|
||||
levelData.tilemap[ x ][ y ] |= POWERUP_TILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelData.tilemap[ x ][ y ] &= ~POWERUP_TILE;
|
||||
}
|
||||
}
|
||||
|
||||
85
wolf3d/code/wolf/wolf_powerups.h
Normal file
85
wolf3d/code/wolf/wolf_powerups.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_powerups.h: Wolfenstein3-D power-up handler.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_powerups.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_POWERUPS_H__
|
||||
#define __WOLF_POWERUPS_H__
|
||||
|
||||
typedef enum
|
||||
{
|
||||
//please provide description
|
||||
pow_gibs, // 1% if <=10%; SLURPIESND
|
||||
pow_gibs2, // 1% if <=10%; SLURPIESND
|
||||
pow_alpo, // 4% if <100%; HEALTH1SND
|
||||
pow_firstaid, // 25% if <100%; HEALTH2SND
|
||||
pow_key1, // gold key; GETKEYSND
|
||||
pow_key2, // silver key; GETKEYSND
|
||||
pow_key3, // not used
|
||||
pow_key4, // not used
|
||||
pow_cross, // 100pts; BONUS1SND
|
||||
pow_chalice, // 500pts; BONUS2SND
|
||||
pow_bible, // 1000pts; BONUS3SND
|
||||
pow_crown, // 5000pts; BONUS4SND
|
||||
pow_clip, // 8bul if <99bul; GETAMMOSND
|
||||
pow_clip2, // 4bul if <99bul; GETAMMOSND
|
||||
pow_machinegun, // machine gun; GETMACHINESND
|
||||
pow_chaingun, // gatling gun; GETGATLINGSND
|
||||
pow_food, // 10% if <100%; HEALTH1SND
|
||||
pow_fullheal, // 99%, 25bul; BONUS1UPSND
|
||||
pow_25clip, // 25bul if <99bul; GETAMMOBOXSND
|
||||
pow_spear, // spear of destiny!
|
||||
|
||||
pow_last
|
||||
// add new types <!only!> here (after last)
|
||||
|
||||
} pow_t;
|
||||
|
||||
typedef struct powerup_s
|
||||
{
|
||||
int x, y;
|
||||
pow_t type;
|
||||
int sprite;
|
||||
} powerup_t;
|
||||
|
||||
extern void Powerup_Reset( void );
|
||||
extern void Powerup_Spawn( int x, int y, int type );
|
||||
extern void Powerup_PickUp( int x, int y );
|
||||
|
||||
|
||||
#endif /* __WOLF_POWERUPS_H__ */
|
||||
|
||||
175
wolf3d/code/wolf/wolf_pushwalls.c
Normal file
175
wolf3d/code/wolf/wolf_pushwalls.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_pushwalls.c: Wolfenstein3-D push-wall handler.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
Pwall_t PWall;
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: PushWall_Reset() -Reset pushwall status.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PushWall_Reset(void)
|
||||
{
|
||||
memset( &PWall, 0, sizeof( Pwall_t ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: PushWall_Push() -Try to move push-wall.
|
||||
|
||||
Parameters: x, y -[in] Coordinates in tilemap.
|
||||
dir -[in] Direction in which push-wall is intended to move.
|
||||
|
||||
Returns: true if push successful, otherwise false.
|
||||
|
||||
Notes: Called whenever someone tries to push a secret wall.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir )
|
||||
{
|
||||
int dx, dy;
|
||||
|
||||
|
||||
if( PWall.active )
|
||||
{
|
||||
return false; // another PWall is moving [only one at a time!]
|
||||
}
|
||||
|
||||
dx = dx4dir[ dir ];
|
||||
dy = dy4dir[ dir ];
|
||||
|
||||
if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) )
|
||||
{ // noway (smth is blocking)
|
||||
return true;
|
||||
}
|
||||
|
||||
// remove secret flag & make everything needed when pushwall used!
|
||||
r_world->tilemap[ x ][ y ] &= (~SECRET_TILE);
|
||||
r_world->tilemap[ x ][ y ] &= (~WALL_TILE);
|
||||
r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE;
|
||||
|
||||
if ( ++levelstate.found_secrets == levelstate.total_secrets ) {
|
||||
iphoneSetNotifyText( "You found the last secret!" );
|
||||
} else {
|
||||
iphoneSetNotifyText( "You found a secret!" );
|
||||
}
|
||||
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 );
|
||||
}
|
||||
|
||||
// good way to avoid stuckness; [un]comment one more down!
|
||||
// it makes a tile behind pushwall unpassable
|
||||
r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE;
|
||||
r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ];
|
||||
r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ];
|
||||
|
||||
// write down PWall info
|
||||
PWall.active = true;
|
||||
PWall.PWtilesmoved = PWall.PWpointsmoved = 0;
|
||||
PWall.dir = dir;
|
||||
PWall.x = x; PWall.y = y;
|
||||
PWall.dx = dx; PWall.dy = dy;
|
||||
PWall.tex_x = r_world->wall_tex_x[ x ][ y ];
|
||||
PWall.tex_y = r_world->wall_tex_y[ x ][ y ];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: PushWall_Process() -Process push-walls.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void PushWall_Process( void )
|
||||
{
|
||||
if( ! PWall.active )
|
||||
{
|
||||
return; // no active PWall to work with
|
||||
}
|
||||
|
||||
PWall.PWpointsmoved += tics;
|
||||
|
||||
if( PWall.PWpointsmoved < 128 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PWall.PWpointsmoved -= 128;
|
||||
PWall.PWtilesmoved++;
|
||||
// Free tile
|
||||
r_world->tilemap[ PWall.x ][ PWall.y ] &= (~PUSHWALL_TILE);
|
||||
// Occupy new tile
|
||||
PWall.x += PWall.dx;
|
||||
PWall.y += PWall.dy;
|
||||
|
||||
// Shall we move further?
|
||||
if( r_world->tilemap[ PWall.x + PWall.dx ][ PWall.y + PWall.dy ] & (SOLID_TILE | DOOR_TILE | ACTOR_TILE | POWERUP_TILE) ||
|
||||
PWall.PWtilesmoved == 3 )
|
||||
{
|
||||
r_world->tilemap[ PWall.x ][ PWall.y ] &= (~PUSHWALL_TILE); // wall now
|
||||
r_world->tilemap[ PWall.x ][ PWall.y ] |= WALL_TILE; // wall now
|
||||
r_world->wall_tex_x[ PWall.x ][ PWall.y ] = PWall.tex_x;
|
||||
r_world->wall_tex_y[ PWall.x ][ PWall.y ] = PWall.tex_y;
|
||||
PWall.active = false; // Free Push Wall
|
||||
}
|
||||
else
|
||||
{
|
||||
r_world->tilemap[ PWall.x + PWall.dx ][ PWall.y + PWall.dy ] |= PUSHWALL_TILE;
|
||||
}
|
||||
|
||||
}
|
||||
373
wolf3d/code/wolf/wolf_raycast.c
Normal file
373
wolf3d/code/wolf/wolf_raycast.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_raycast.c: Wolfenstein3-D ray-casting.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
|
||||
W8 tile_visible[ 64 ][ 64 ]; // can player see this tile?
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: R_RayCast() -Ray cast viewport.
|
||||
|
||||
Parameters: viewport -[in] Position of camera.
|
||||
lvl -[in] Pointer to valid LevelData_t structure.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes: Marks all visible tiles in tile_visible[] array.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_RayCast( placeonplane_t viewport, LevelData_t *lvl )
|
||||
{
|
||||
int n, x, y, angle, vx, vy;
|
||||
r_trace_t trace;
|
||||
|
||||
memset( tile_visible, 0, sizeof( tile_visible ) ); // clear tile visible flags
|
||||
|
||||
// viewport tile coordinates
|
||||
x = viewport.origin[ 0 ];
|
||||
y = viewport.origin[ 1 ];
|
||||
angle = viewport.angle;
|
||||
|
||||
vx = POS2TILE( viewport.origin[ 0 ] );
|
||||
vy = POS2TILE( viewport.origin[ 1 ] );
|
||||
|
||||
trace.tile_vis = tile_visible;
|
||||
trace.flags = TRACE_SIGHT | TRACE_MARK_MAP;
|
||||
|
||||
//
|
||||
// Ray casting
|
||||
//
|
||||
|
||||
// FIXME: control ray count and make angle init
|
||||
for( n = 0 ; n < 640 ; ++n )
|
||||
{
|
||||
trace.x = x;
|
||||
trace.y = y;
|
||||
trace.a = NormalizeAngle( angle + ColumnAngle[ n ] );
|
||||
|
||||
R_Trace( &trace, lvl );
|
||||
}
|
||||
|
||||
//
|
||||
// Rendering
|
||||
//
|
||||
for( x = 0 ; x < 64; ++x )
|
||||
for( y = 0 ; y < 64; ++y )
|
||||
if( tile_visible[ x ][ y ] )
|
||||
{
|
||||
lvl->tileEverVisible[x][y] = 1; // for automap
|
||||
if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
|
||||
{
|
||||
/* door */
|
||||
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_open )
|
||||
{
|
||||
_boolean backside = false;
|
||||
|
||||
if( lvl->Doors.DoorMap[ x ][ y ].vertical )
|
||||
{
|
||||
if( x < vx )
|
||||
backside = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( y < vy )
|
||||
backside = true;
|
||||
}
|
||||
|
||||
R_Draw_Door( x, y, LOWERZCOORD, UPPERZCOORD,
|
||||
lvl->Doors.DoorMap[ x ][ y ].vertical,
|
||||
backside,
|
||||
lvl->Doors.DoorMap[ x ][ y ].texture,
|
||||
Door_Opened( &lvl->Doors, x, y ) );
|
||||
}
|
||||
/* door sides */
|
||||
if( lvl->Doors.DoorMap[ x ][ y ].vertical )
|
||||
{
|
||||
if( y <= vy )
|
||||
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, TEX_PLATE );
|
||||
|
||||
if( y >= vy )
|
||||
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, TEX_PLATE );
|
||||
|
||||
if( x <= vx && lvl->tilemap[ x - 1 ][ y ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, lvl->wall_tex_x[ x - 1 ][ y ] );
|
||||
|
||||
if( x >= vx && lvl->tilemap[ x + 1 ][ y ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, lvl->wall_tex_x[ x + 1 ][ y ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( x <= vx )
|
||||
R_Draw_Wall((float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, TEX_PLATE+1);
|
||||
|
||||
if( x >= vx )
|
||||
R_Draw_Wall((float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, TEX_PLATE+1);
|
||||
|
||||
if( y <= vy && lvl->tilemap[ x ][ y - 1 ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, lvl->wall_tex_y[x][y-1]);
|
||||
|
||||
if( y >= vy && lvl->tilemap[ x ][ y + 1 ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, lvl->wall_tex_y[x][y+1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push-Wall */
|
||||
if( (r_world->tilemap[ x ][ y ] & PUSHWALL_TILE) )
|
||||
{
|
||||
float dx, dy;
|
||||
|
||||
dx = PWall.dx * PWall.PWpointsmoved / 128.0f;
|
||||
dy = PWall.dy * PWall.PWpointsmoved / 128.0f;
|
||||
|
||||
if( PWall.x <= vx )
|
||||
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_east, PWall.tex_x );
|
||||
|
||||
if( PWall.x >= vx )
|
||||
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_west, PWall.tex_x );
|
||||
|
||||
if( PWall.y <= vy )
|
||||
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_north, PWall.tex_y );
|
||||
|
||||
if( PWall.y >= vy )
|
||||
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_south, PWall.tex_y );
|
||||
|
||||
}
|
||||
/* x-wall */
|
||||
if( x <= vx && r_world->tilemap[ x - 1 ][ y ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, r_world->wall_tex_x[x-1][y]);
|
||||
|
||||
if( x >= vx && r_world->tilemap[ x + 1 ][ y ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, r_world->wall_tex_x[x+1][y]);
|
||||
|
||||
/* y-wall */
|
||||
if( y <= vy && r_world->tilemap[ x ][ y - 1 ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, r_world->wall_tex_y[x][y-1]);
|
||||
|
||||
if( y >= vy && r_world->tilemap[ x ][ y + 1 ] & WALL_TILE )
|
||||
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, r_world->wall_tex_y[x][y+1]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// back to full brightness in case the last draw was a dim wall
|
||||
pfglColor3f( 1, 1, 1 );
|
||||
}
|
||||
|
||||
|
||||
int x_tile_step[ 4 ] = { 1, -1, -1, 1 };
|
||||
int y_tile_step[ 4 ] = { 1, 1, -1, -1 };
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: R_TraceCheck() -Trace ray check.
|
||||
|
||||
Parameters:
|
||||
lvl -[in] Pointer to valid LevelData_t structure.
|
||||
x, y -[in] In tiles.
|
||||
|
||||
Returns: true to stop tracing, false otherwise.
|
||||
|
||||
Notes: Tells ray casting if we hit a wall or door and to stop tracing.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE _boolean R_TraceCheck( LevelData_t *lvl, int x, int y, int frac, int dfrac, _boolean vert, _boolean flip, r_trace_t *trace )
|
||||
{
|
||||
if( lvl->tilemap[ x ][ y ] & WALL_TILE )
|
||||
{
|
||||
if( vert )
|
||||
{
|
||||
trace->x = (x << TILESHIFT) + (flip ? TILEGLOBAL : 0);
|
||||
trace->y = (y << TILESHIFT) + frac;
|
||||
trace->flags |= TRACE_HIT_VERT;
|
||||
}
|
||||
else
|
||||
{
|
||||
trace->x = (x << TILESHIFT) + frac;
|
||||
trace->y = (y << TILESHIFT) + (flip ? TILEGLOBAL : 0);
|
||||
trace->flags &= ~TRACE_HIT_VERT;
|
||||
}
|
||||
|
||||
return true; // wall, stop tracing
|
||||
}
|
||||
|
||||
if( trace->tile_vis )
|
||||
{
|
||||
trace->tile_vis[ x ][ y ] = true; // this tile is visible
|
||||
}
|
||||
|
||||
|
||||
if( lvl->tilemap[ x ][ y ] & DOOR_TILE &&
|
||||
lvl->Doors.DoorMap[ x ][ y ].action != dr_open )
|
||||
{
|
||||
frac += dfrac >> 1;
|
||||
if( POS2TILE( frac ) )
|
||||
return false;
|
||||
|
||||
if( vert )
|
||||
{
|
||||
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_closed &&
|
||||
(frac >> 10) > DOOR_FULLOPEN - Door_Opened( &lvl->Doors, x, y ) )
|
||||
{
|
||||
return false; // opened enough
|
||||
}
|
||||
|
||||
trace->x = TILE2POS( x );
|
||||
trace->y = (y << TILESHIFT) + frac;
|
||||
trace->flags |= TRACE_HIT_VERT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_closed &&
|
||||
(frac >> 10) < Door_Opened( &lvl->Doors, x, y ) )
|
||||
{
|
||||
return false; // opened enough
|
||||
}
|
||||
|
||||
trace->y = TILE2POS( y );
|
||||
trace->x = (x << TILESHIFT) + frac;
|
||||
trace->flags &= ~TRACE_HIT_VERT;
|
||||
}
|
||||
trace->flags |= TRACE_HIT_DOOR;
|
||||
|
||||
return true; // closed door, stop tracing
|
||||
}
|
||||
|
||||
return false; // no intersection, go on!
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: R_Trace() -Trace ray.
|
||||
|
||||
Parameters:
|
||||
trace -[in] Pointer to valid r_trace_t structure.
|
||||
lvl -[in] Pointer to valid LevelData_t structure.
|
||||
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_Trace( r_trace_t *trace, LevelData_t *lvl )
|
||||
{
|
||||
int xtilestep, ytilestep;
|
||||
int xstep, ystep;
|
||||
int xtile, ytile;
|
||||
int xintercept, yintercept;
|
||||
int YmapPos, XmapPos;
|
||||
quadrant q;
|
||||
|
||||
// Setup for ray casting
|
||||
q = GetQuadrant( FINE2RAD( trace->a ) );
|
||||
|
||||
xtilestep = x_tile_step[ q ];
|
||||
ytilestep = y_tile_step[ q ];
|
||||
|
||||
xtile = POS2TILE( trace->x ) + xtilestep;
|
||||
ytile = POS2TILE( trace->y ) + ytilestep;
|
||||
|
||||
xstep = ytilestep * XnextTable[ trace->a ];
|
||||
ystep = xtilestep * YnextTable[ trace->a ];
|
||||
|
||||
xintercept = (int)( ( ((ytilestep == -1 ? ytile+1 : ytile) << TILESHIFT) - trace->y ) / TanTable[ trace->a ]) + trace->x;
|
||||
yintercept = (int)( ( ((xtilestep == -1 ? xtile+1 : xtile) << TILESHIFT) - trace->x ) * TanTable[ trace->a ]) + trace->y;
|
||||
|
||||
YmapPos = yintercept >> TILESHIFT; // toXray
|
||||
XmapPos = xintercept >> TILESHIFT; // toYray
|
||||
|
||||
if( trace->tile_vis )
|
||||
{
|
||||
// this tile is visible
|
||||
trace->tile_vis[ POS2TILE( trace->x ) ][ POS2TILE( trace->y ) ] = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Start of ray-casting
|
||||
//
|
||||
while( 1 )
|
||||
{
|
||||
//
|
||||
// Vertical loop // an anologue for X-Ray
|
||||
//
|
||||
while( ! (ytilestep == -1 && YmapPos <= ytile) && ! (ytilestep == 1 && YmapPos >= ytile) )
|
||||
{
|
||||
if( xtile < 0 || xtile >= 64 || YmapPos < 0 || YmapPos >= 64 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( R_TraceCheck( lvl, xtile, YmapPos, yintercept % TILEGLOBAL, ystep, true, (_boolean)(xtilestep == -1), trace ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare for next step
|
||||
xtile += xtilestep;
|
||||
yintercept += ystep;
|
||||
YmapPos = yintercept >> TILESHIFT;
|
||||
}
|
||||
|
||||
//
|
||||
// Horizontal loop // an anologue for Y-Ray
|
||||
//
|
||||
while( ! (xtilestep == -1 && XmapPos <= xtile) && ! (xtilestep == 1 && XmapPos >= xtile) )
|
||||
{
|
||||
if( ytile < 0 || ytile >= 64 || XmapPos < 0 || XmapPos >= 64 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( R_TraceCheck( lvl, XmapPos, ytile, xintercept % TILEGLOBAL, xstep, false, (_boolean)(ytilestep == -1), trace ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare for next step
|
||||
ytile += ytilestep;
|
||||
xintercept += xstep;
|
||||
XmapPos = xintercept >> TILESHIFT;
|
||||
}
|
||||
|
||||
} // end of while( 1 )
|
||||
|
||||
}
|
||||
74
wolf3d/code/wolf/wolf_raycast.h
Normal file
74
wolf3d/code/wolf/wolf_raycast.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_raycast.h: Wolfenstein3-D ray-casting.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_raycast.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_RAYCAST_H__
|
||||
#define __WOLF_RAYCAST_H__
|
||||
|
||||
// marks
|
||||
#define TRACE_MARK_MAP 1 // marks traced area in 'AM_AutoMap.vis' array
|
||||
// obstacle levels
|
||||
#define TRACE_SIGHT 2 // player sight
|
||||
#define TRACE_SIGHT_AI 4 // enemy sight
|
||||
#define TRACE_BULLET 8 // bullet
|
||||
#define TRACE_OBJECT 16 // object
|
||||
|
||||
#define TRACE_HIT_VERT 32 // vertical wall was hit
|
||||
#define TRACE_HIT_DOOR 64 // door was hit
|
||||
#define TRACE_HIT_PWALL 128 // pushwall was hit
|
||||
|
||||
typedef struct r_trace_s
|
||||
{
|
||||
int x, y; // origin
|
||||
int a; // trace angle
|
||||
int flags;
|
||||
W8 (*tile_vis)[ 64 ]; // should point to [ 64 ][ 64 ] array
|
||||
|
||||
} r_trace_t;
|
||||
|
||||
#define UPPERZCOORD 0.6f
|
||||
#define LOWERZCOORD -0.6f
|
||||
|
||||
extern W8 tile_visible[ 64 ][ 64 ]; // can player see this tile?
|
||||
|
||||
|
||||
extern void R_RayCast( placeonplane_t viewport, LevelData_t *lvl );
|
||||
extern void R_Trace( r_trace_t *trace, LevelData_t *lvl );
|
||||
|
||||
|
||||
#endif /* __WOLF_RAYCAST_H__ */
|
||||
96
wolf3d/code/wolf/wolf_renderer.c
Normal file
96
wolf3d/code/wolf/wolf_renderer.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004-2005 Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_renderer.c: Wolfenstein 3-D renderer.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Quake II, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
LevelData_t *r_world;
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: R_BeginRegistration -Start the rendering registration sequence.
|
||||
|
||||
Parameters: map -[in] The name of the map to load.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void R_BeginRegistration( const char *map )
|
||||
{
|
||||
char fullname[ MAX_GAMEPATH ];
|
||||
|
||||
if( ! map || ! *map )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
++texture_registration_sequence;
|
||||
|
||||
|
||||
my_snprintf( fullname, sizeof( fullname ), "maps/%s.map", map );
|
||||
|
||||
// Door_ResetDoors( &r_world->Doors );
|
||||
Powerup_Reset();
|
||||
Sprite_Reset();
|
||||
Areas_InitAreas( Player.areanumber );
|
||||
PushWall_Reset();
|
||||
|
||||
memset( &levelstate, 0, sizeof( levelstate ) ); // Reset gamestate
|
||||
ResetGuards();
|
||||
|
||||
r_world = Level_LoadMap( fullname );
|
||||
|
||||
if( r_world == NULL )
|
||||
{
|
||||
Com_Printf( "Could not load map (%s)\n", map );
|
||||
return;
|
||||
}
|
||||
|
||||
levelstate.floornum = floornumber;
|
||||
|
||||
if( g_version->value == SPEAROFDESTINY )
|
||||
{
|
||||
if( strlen( map ) >= 2 )
|
||||
{
|
||||
levelstate.floornum = atoi( map+1 );
|
||||
|
||||
if( levelstate.floornum == 20 )
|
||||
{
|
||||
levelstate.floornum = 17;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
61
wolf3d/code/wolf/wolf_renderer.h
Normal file
61
wolf3d/code/wolf/wolf_renderer.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_renderer.h: Wolfenstein3-D renderer.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from Quake II, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_renderer.c and wolf_opengl.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_RENDERER_H__
|
||||
#define __WOLF_RENDERER_H__
|
||||
|
||||
extern void R_DrawBox( int x, int y, int w, int h, W32 color );
|
||||
|
||||
extern void R_Draw_Door( int x, int y, float z1, float z2, _boolean vertical, _boolean backside, int tex, int amount );
|
||||
extern void R_Draw_Wall( float x, float y, float z1, float z2, int type, int tex );
|
||||
|
||||
|
||||
|
||||
extern void R_DrawSprites( void );
|
||||
|
||||
extern void R_DrawPsyched( W32 percent );
|
||||
|
||||
extern void R_DrawHUD( void );
|
||||
extern void R_DrawNumber( int x, int y, int number );
|
||||
|
||||
|
||||
extern void R_put_line( int x, int y, const char *string );
|
||||
|
||||
|
||||
#endif /* __WOLF_RENDERER_H__ */
|
||||
287
wolf3d/code/wolf/wolf_sprites.c
Normal file
287
wolf3d/code/wolf/wolf_sprites.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_sprites.c: Wolfenstein3-D sprite handling.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* This code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_Reset -Reset sprite status.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes: Called only when client must reconnect will not set remove flag!
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Sprite_Reset( void )
|
||||
{
|
||||
levelData.numSprites = 0;
|
||||
memset( levelData.sprites, 0, sizeof( levelData.sprites ) );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_RemoveSprite -Remove sprite.
|
||||
|
||||
Parameters: sprite_id -[in] sprite id to remove.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Sprite_RemoveSprite( int sprite_id )
|
||||
{
|
||||
if( sprite_id == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
levelData.sprites[ sprite_id ].flags |= SPRT_REMOVE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_GetNewSprite -Get sprite index.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: "sprite id" index.
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int Sprite_GetNewSprite( void )
|
||||
{
|
||||
W32 n;
|
||||
sprite_t* sprt;
|
||||
|
||||
for( n = 0, sprt = levelData.sprites ; n < levelData.numSprites ; ++n, ++sprt )
|
||||
{
|
||||
if( sprt->flags & SPRT_REMOVE )
|
||||
{ // free spot: clear it first
|
||||
memset( sprt, 0, sizeof( sprite_t ) );
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
if( levelData.numSprites >= MAX_SPRITES )
|
||||
{
|
||||
Com_Printf( "Warning n_of_sprt == MAX_SPRITES\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
return levelData.numSprites++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_SetPos -Set sprite position.
|
||||
|
||||
Parameters: sprite_id -[in] sprite id to change.
|
||||
x, y -[in] new x, y.
|
||||
angle -[in] new angle to set.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Sprite_SetPos( int sprite_id, int x, int y, int angle )
|
||||
{
|
||||
if( sprite_id == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
levelData.sprites[ sprite_id ].x = x;
|
||||
levelData.sprites[ sprite_id ].y = y;
|
||||
levelData.sprites[ sprite_id ].ang = angle;
|
||||
levelData.sprites[ sprite_id ].tilex = POS2TILE( x );
|
||||
levelData.sprites[ sprite_id ].tiley = POS2TILE( y );
|
||||
levelData.sprites[ sprite_id ].flags |= SPRT_CHG_POS;
|
||||
|
||||
if( ! (x & HALFTILE) ) // (x%TILEGLOBAL>=HALFTILE)
|
||||
{
|
||||
levelData.sprites[ sprite_id ].tilex--;
|
||||
}
|
||||
|
||||
if( ! (y & HALFTILE) )
|
||||
{
|
||||
levelData.sprites[ sprite_id ].tiley--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_SetTex -Set sprite texture.
|
||||
|
||||
Parameters: sprite_id -[in] sprite id to change.
|
||||
index -[in] texture index.
|
||||
tex -[in] texture to set as.
|
||||
|
||||
Returns: Nothing.
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
void CacheTextures( W16 start, W16 end );
|
||||
PUBLIC void Sprite_SetTex( int sprite_id, int index, int tex )
|
||||
{
|
||||
if( sprite_id == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
CacheTextures( tex, tex );
|
||||
|
||||
if( index == -1 ) // one texture for each phase
|
||||
{
|
||||
levelData.sprites[ sprite_id ].tex[ 0 ] = tex;
|
||||
levelData.sprites[ sprite_id ].flags |= SPRT_ONE_TEX;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelData.sprites[ sprite_id ].tex[ index ] = tex;
|
||||
}
|
||||
|
||||
levelData.sprites[ sprite_id ].flags |= SPRT_CHG_TEX;
|
||||
}
|
||||
|
||||
|
||||
#define MAXVISABLE 128
|
||||
visobj_t vislist[ MAXVISABLE ];
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_CreateVisList -Compare function for vislist sorting.
|
||||
|
||||
Parameters: vis1, vis2 -[in] Two values to compare.
|
||||
|
||||
Returns:
|
||||
<0 elem1 further than elem2
|
||||
0 elem1 equal distance to elem2
|
||||
>0 elem1 closer than elem2
|
||||
|
||||
Notes:
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE int Sprite_cmpVis( const void *elem1, const void *elem2 )
|
||||
{
|
||||
// macro to get distance from a void pointer to visobj_t
|
||||
#define vis_dist( vis ) ( ((visobj_t *)vis)->dist )
|
||||
|
||||
if( vis_dist( elem1 ) == vis_dist( elem2 ) )
|
||||
{
|
||||
return 0; // process equal distance
|
||||
}
|
||||
else
|
||||
{
|
||||
// if dist > sprite must be first
|
||||
return vis_dist( elem1 ) < vis_dist( elem2 ) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function: Sprite_CreateVisList -Build and sort visibility list of sprites.
|
||||
|
||||
Parameters: Nothing.
|
||||
|
||||
Returns: Number of visible sprites.
|
||||
|
||||
Notes:
|
||||
List is sorted from far to near.
|
||||
List is based on tile visibility array, made by raycaster.
|
||||
Called only by client.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC int Sprite_CreateVisList( void )
|
||||
{
|
||||
W32 tx, ty, n, num_visible;
|
||||
visobj_t *visptr;
|
||||
sprite_t* sprt;
|
||||
|
||||
visptr = vislist;
|
||||
num_visible = 0;
|
||||
|
||||
for( n = 0, sprt = levelData.sprites; n < levelData.numSprites; ++n, ++sprt )
|
||||
{
|
||||
if( sprt->flags & SPRT_REMOVE )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
tx = sprt->tilex;
|
||||
ty = sprt->tiley;
|
||||
|
||||
if( tx > 63 )
|
||||
tx = 63;
|
||||
if( ty > 63 )
|
||||
ty = 63;
|
||||
|
||||
// can be in any of 4 surrounding tiles; not 9 - see definition of tilex & tiley
|
||||
if( tile_visible[ tx ][ ty ] || tile_visible[ tx + 1 ][ ty ] ||
|
||||
tile_visible[ tx ][ ty + 1 ] || tile_visible[ tx + 1 ][ ty + 1 ] )
|
||||
{ // player spoted it
|
||||
visptr->dist = LineLen2Point( sprt->x - Player.position.origin[ 0 ],
|
||||
sprt->y-Player.position.origin[ 1 ],
|
||||
Player.position.angle ); //FIXME viewport
|
||||
visptr->x = sprt->x;
|
||||
visptr->y = sprt->y;
|
||||
visptr->ang = sprt->ang;
|
||||
visptr->tex = sprt->tex[ 0 ]; //FIXME!
|
||||
if( ++num_visible > MAXVISABLE )
|
||||
{
|
||||
break; // vislist full
|
||||
}
|
||||
|
||||
visptr++;
|
||||
}
|
||||
}
|
||||
|
||||
// sorting list
|
||||
if( num_visible ) // do not sort if no entries
|
||||
{
|
||||
qsort( vislist, num_visible, sizeof( visobj_t ), Sprite_cmpVis );
|
||||
}
|
||||
|
||||
return num_visible;
|
||||
}
|
||||
|
||||
429
wolf3d/code/wolf/wolf_sprites.h
Normal file
429
wolf3d/code/wolf/wolf_sprites.h
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* wolf_sprites.h: Wolfenstein3-D sprite handling.
|
||||
*
|
||||
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
|
||||
* Date: 2004
|
||||
*
|
||||
* Acknowledgement:
|
||||
* Portion of this code was derived from NewWolf, and was originally
|
||||
* written by DarkOne the Hacker.
|
||||
*
|
||||
* Portion of this code was derived from Wolfenstein3-D, and was originally
|
||||
* written by Id Software, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Notes:
|
||||
This module is implemented by wolf_sprites.c
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __WOLF_SPRITES_H__
|
||||
#define __WOLF_SPRITES_H__
|
||||
|
||||
|
||||
//
|
||||
// sprite constants
|
||||
//
|
||||
|
||||
enum {
|
||||
SPR_DEMO,
|
||||
SPR_DEATHCAM,
|
||||
//
|
||||
// static sprites
|
||||
//
|
||||
SPR_STAT_0, SPR_STAT_1,SPR_STAT_2, SPR_STAT_3,
|
||||
SPR_STAT_4, SPR_STAT_5,SPR_STAT_6, SPR_STAT_7,
|
||||
|
||||
SPR_STAT_8, SPR_STAT_9,SPR_STAT_10,SPR_STAT_11,
|
||||
SPR_STAT_12,SPR_STAT_13,SPR_STAT_14,SPR_STAT_15,
|
||||
|
||||
SPR_STAT_16,SPR_STAT_17,SPR_STAT_18,SPR_STAT_19,
|
||||
SPR_STAT_20,SPR_STAT_21,SPR_STAT_22,SPR_STAT_23,
|
||||
|
||||
SPR_STAT_24,SPR_STAT_25,SPR_STAT_26,SPR_STAT_27,
|
||||
SPR_STAT_28,SPR_STAT_29,SPR_STAT_30,SPR_STAT_31,
|
||||
|
||||
SPR_STAT_32,SPR_STAT_33,SPR_STAT_34,SPR_STAT_35,
|
||||
SPR_STAT_36,SPR_STAT_37,SPR_STAT_38,SPR_STAT_39,
|
||||
|
||||
SPR_STAT_40,SPR_STAT_41,SPR_STAT_42,SPR_STAT_43,
|
||||
SPR_STAT_44,SPR_STAT_45,SPR_STAT_46,SPR_STAT_47,
|
||||
|
||||
|
||||
|
||||
|
||||
SPR_STAT_48,SPR_STAT_49,SPR_STAT_50,SPR_STAT_51,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Guard
|
||||
//
|
||||
SPR_GRD_S_1,SPR_GRD_S_2,SPR_GRD_S_3,SPR_GRD_S_4,
|
||||
SPR_GRD_S_5,SPR_GRD_S_6,SPR_GRD_S_7,SPR_GRD_S_8,
|
||||
|
||||
SPR_GRD_W1_1,SPR_GRD_W1_2,SPR_GRD_W1_3,SPR_GRD_W1_4,
|
||||
SPR_GRD_W1_5,SPR_GRD_W1_6,SPR_GRD_W1_7,SPR_GRD_W1_8,
|
||||
|
||||
SPR_GRD_W2_1,SPR_GRD_W2_2,SPR_GRD_W2_3,SPR_GRD_W2_4,
|
||||
SPR_GRD_W2_5,SPR_GRD_W2_6,SPR_GRD_W2_7,SPR_GRD_W2_8,
|
||||
|
||||
SPR_GRD_W3_1,SPR_GRD_W3_2,SPR_GRD_W3_3,SPR_GRD_W3_4,
|
||||
SPR_GRD_W3_5,SPR_GRD_W3_6,SPR_GRD_W3_7,SPR_GRD_W3_8,
|
||||
|
||||
SPR_GRD_W4_1,SPR_GRD_W4_2,SPR_GRD_W4_3,SPR_GRD_W4_4,
|
||||
SPR_GRD_W4_5,SPR_GRD_W4_6,SPR_GRD_W4_7,SPR_GRD_W4_8,
|
||||
|
||||
SPR_GRD_PAIN_1,SPR_GRD_DIE_1,SPR_GRD_DIE_2,SPR_GRD_DIE_3,
|
||||
SPR_GRD_PAIN_2,SPR_GRD_DEAD,
|
||||
|
||||
SPR_GRD_SHOOT1,SPR_GRD_SHOOT2,SPR_GRD_SHOOT3,
|
||||
|
||||
//
|
||||
// Dog
|
||||
//
|
||||
SPR_DOG_W1_1,SPR_DOG_W1_2,SPR_DOG_W1_3,SPR_DOG_W1_4,
|
||||
SPR_DOG_W1_5,SPR_DOG_W1_6,SPR_DOG_W1_7,SPR_DOG_W1_8,
|
||||
|
||||
SPR_DOG_W2_1,SPR_DOG_W2_2,SPR_DOG_W2_3,SPR_DOG_W2_4,
|
||||
SPR_DOG_W2_5,SPR_DOG_W2_6,SPR_DOG_W2_7,SPR_DOG_W2_8,
|
||||
|
||||
SPR_DOG_W3_1,SPR_DOG_W3_2,SPR_DOG_W3_3,SPR_DOG_W3_4,
|
||||
SPR_DOG_W3_5,SPR_DOG_W3_6,SPR_DOG_W3_7,SPR_DOG_W3_8,
|
||||
|
||||
SPR_DOG_W4_1,SPR_DOG_W4_2,SPR_DOG_W4_3,SPR_DOG_W4_4,
|
||||
SPR_DOG_W4_5,SPR_DOG_W4_6,SPR_DOG_W4_7,SPR_DOG_W4_8,
|
||||
|
||||
SPR_DOG_DIE_1,SPR_DOG_DIE_2,SPR_DOG_DIE_3,SPR_DOG_DEAD,
|
||||
SPR_DOG_JUMP1,SPR_DOG_JUMP2,SPR_DOG_JUMP3,
|
||||
|
||||
|
||||
|
||||
//
|
||||
// SS
|
||||
//
|
||||
SPR_SS_S_1,SPR_SS_S_2,SPR_SS_S_3,SPR_SS_S_4,
|
||||
SPR_SS_S_5,SPR_SS_S_6,SPR_SS_S_7,SPR_SS_S_8,
|
||||
|
||||
SPR_SS_W1_1,SPR_SS_W1_2,SPR_SS_W1_3,SPR_SS_W1_4,
|
||||
SPR_SS_W1_5,SPR_SS_W1_6,SPR_SS_W1_7,SPR_SS_W1_8,
|
||||
|
||||
SPR_SS_W2_1,SPR_SS_W2_2,SPR_SS_W2_3,SPR_SS_W2_4,
|
||||
SPR_SS_W2_5,SPR_SS_W2_6,SPR_SS_W2_7,SPR_SS_W2_8,
|
||||
|
||||
SPR_SS_W3_1,SPR_SS_W3_2,SPR_SS_W3_3,SPR_SS_W3_4,
|
||||
SPR_SS_W3_5,SPR_SS_W3_6,SPR_SS_W3_7,SPR_SS_W3_8,
|
||||
|
||||
SPR_SS_W4_1,SPR_SS_W4_2,SPR_SS_W4_3,SPR_SS_W4_4,
|
||||
SPR_SS_W4_5,SPR_SS_W4_6,SPR_SS_W4_7,SPR_SS_W4_8,
|
||||
|
||||
SPR_SS_PAIN_1,SPR_SS_DIE_1,SPR_SS_DIE_2,SPR_SS_DIE_3,
|
||||
SPR_SS_PAIN_2,SPR_SS_DEAD,
|
||||
|
||||
SPR_SS_SHOOT1,SPR_SS_SHOOT2,SPR_SS_SHOOT3,
|
||||
|
||||
//
|
||||
// Mutant
|
||||
//
|
||||
SPR_MUT_S_1,SPR_MUT_S_2,SPR_MUT_S_3,SPR_MUT_S_4,
|
||||
SPR_MUT_S_5,SPR_MUT_S_6,SPR_MUT_S_7,SPR_MUT_S_8,
|
||||
|
||||
SPR_MUT_W1_1,SPR_MUT_W1_2,SPR_MUT_W1_3,SPR_MUT_W1_4,
|
||||
SPR_MUT_W1_5,SPR_MUT_W1_6,SPR_MUT_W1_7,SPR_MUT_W1_8,
|
||||
|
||||
SPR_MUT_W2_1,SPR_MUT_W2_2,SPR_MUT_W2_3,SPR_MUT_W2_4,
|
||||
SPR_MUT_W2_5,SPR_MUT_W2_6,SPR_MUT_W2_7,SPR_MUT_W2_8,
|
||||
|
||||
SPR_MUT_W3_1,SPR_MUT_W3_2,SPR_MUT_W3_3,SPR_MUT_W3_4,
|
||||
SPR_MUT_W3_5,SPR_MUT_W3_6,SPR_MUT_W3_7,SPR_MUT_W3_8,
|
||||
|
||||
SPR_MUT_W4_1,SPR_MUT_W4_2,SPR_MUT_W4_3,SPR_MUT_W4_4,
|
||||
SPR_MUT_W4_5,SPR_MUT_W4_6,SPR_MUT_W4_7,SPR_MUT_W4_8,
|
||||
|
||||
SPR_MUT_PAIN_1,SPR_MUT_DIE_1,SPR_MUT_DIE_2,SPR_MUT_DIE_3,
|
||||
SPR_MUT_PAIN_2,SPR_MUT_DIE_4,SPR_MUT_DEAD,
|
||||
|
||||
SPR_MUT_SHOOT1,SPR_MUT_SHOOT2,SPR_MUT_SHOOT3,SPR_MUT_SHOOT4,
|
||||
|
||||
//
|
||||
// Officer
|
||||
//
|
||||
SPR_OFC_S_1,SPR_OFC_S_2,SPR_OFC_S_3,SPR_OFC_S_4,
|
||||
SPR_OFC_S_5,SPR_OFC_S_6,SPR_OFC_S_7,SPR_OFC_S_8,
|
||||
|
||||
SPR_OFC_W1_1,SPR_OFC_W1_2,SPR_OFC_W1_3,SPR_OFC_W1_4,
|
||||
SPR_OFC_W1_5,SPR_OFC_W1_6,SPR_OFC_W1_7,SPR_OFC_W1_8,
|
||||
|
||||
SPR_OFC_W2_1,SPR_OFC_W2_2,SPR_OFC_W2_3,SPR_OFC_W2_4,
|
||||
SPR_OFC_W2_5,SPR_OFC_W2_6,SPR_OFC_W2_7,SPR_OFC_W2_8,
|
||||
|
||||
SPR_OFC_W3_1,SPR_OFC_W3_2,SPR_OFC_W3_3,SPR_OFC_W3_4,
|
||||
SPR_OFC_W3_5,SPR_OFC_W3_6,SPR_OFC_W3_7,SPR_OFC_W3_8,
|
||||
|
||||
SPR_OFC_W4_1,SPR_OFC_W4_2,SPR_OFC_W4_3,SPR_OFC_W4_4,
|
||||
SPR_OFC_W4_5,SPR_OFC_W4_6,SPR_OFC_W4_7,SPR_OFC_W4_8,
|
||||
|
||||
SPR_OFC_PAIN_1,SPR_OFC_DIE_1,SPR_OFC_DIE_2,SPR_OFC_DIE_3,
|
||||
SPR_OFC_PAIN_2,SPR_OFC_DIE_4,SPR_OFC_DEAD,
|
||||
|
||||
SPR_OFC_SHOOT1,SPR_OFC_SHOOT2,SPR_OFC_SHOOT3,
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Ghosts
|
||||
//
|
||||
SPR_BLINKY_W1,SPR_BLINKY_W2,SPR_PINKY_W1,SPR_PINKY_W2,
|
||||
SPR_CLYDE_W1,SPR_CLYDE_W2,SPR_INKY_W1,SPR_INKY_W2,
|
||||
|
||||
//
|
||||
// Hans
|
||||
//
|
||||
SPR_BOSS_W1,SPR_BOSS_W2,SPR_BOSS_W3,SPR_BOSS_W4,
|
||||
SPR_BOSS_SHOOT1,SPR_BOSS_SHOOT2,SPR_BOSS_SHOOT3,SPR_BOSS_DEAD,
|
||||
|
||||
SPR_BOSS_DIE1,SPR_BOSS_DIE2,SPR_BOSS_DIE3,
|
||||
|
||||
//
|
||||
// Schabbs
|
||||
//
|
||||
SPR_SCHABB_W1,SPR_SCHABB_W2,SPR_SCHABB_W3,SPR_SCHABB_W4,
|
||||
SPR_SCHABB_SHOOT1,SPR_SCHABB_SHOOT2,
|
||||
|
||||
SPR_SCHABB_DIE1,SPR_SCHABB_DIE2,SPR_SCHABB_DIE3,SPR_SCHABB_DEAD,
|
||||
SPR_HYPO1,SPR_HYPO2,SPR_HYPO3,SPR_HYPO4,
|
||||
|
||||
//
|
||||
// Fake
|
||||
//
|
||||
SPR_FAKE_W1,SPR_FAKE_W2,SPR_FAKE_W3,SPR_FAKE_W4,
|
||||
SPR_FAKE_SHOOT,SPR_FIRE1,SPR_FIRE2,
|
||||
|
||||
SPR_FAKE_DIE1,SPR_FAKE_DIE2,SPR_FAKE_DIE3,SPR_FAKE_DIE4,
|
||||
SPR_FAKE_DIE5,SPR_FAKE_DEAD,
|
||||
|
||||
//
|
||||
// Hitler
|
||||
//
|
||||
SPR_MECHA_W1,SPR_MECHA_W2,SPR_MECHA_W3,SPR_MECHA_W4,
|
||||
SPR_MECHA_SHOOT1,SPR_MECHA_SHOOT2,SPR_MECHA_SHOOT3,SPR_MECHA_DEAD,
|
||||
|
||||
SPR_MECHA_DIE1,SPR_MECHA_DIE2,SPR_MECHA_DIE3,
|
||||
|
||||
SPR_HITLER_W1,SPR_HITLER_W2,SPR_HITLER_W3,SPR_HITLER_W4,
|
||||
SPR_HITLER_SHOOT1,SPR_HITLER_SHOOT2,SPR_HITLER_SHOOT3,SPR_HITLER_DEAD,
|
||||
|
||||
SPR_HITLER_DIE1,SPR_HITLER_DIE2,SPR_HITLER_DIE3,SPR_HITLER_DIE4,
|
||||
SPR_HITLER_DIE5,SPR_HITLER_DIE6,SPR_HITLER_DIE7,
|
||||
|
||||
//
|
||||
// Giftmacher
|
||||
//
|
||||
SPR_GIFT_W1,SPR_GIFT_W2,SPR_GIFT_W3,SPR_GIFT_W4,
|
||||
SPR_GIFT_SHOOT1,SPR_GIFT_SHOOT2,
|
||||
|
||||
SPR_GIFT_DIE1,SPR_GIFT_DIE2,SPR_GIFT_DIE3,SPR_GIFT_DEAD,
|
||||
|
||||
|
||||
//
|
||||
// Rocket, smoke and small explosion
|
||||
//
|
||||
SPR_ROCKET_1,SPR_ROCKET_2,SPR_ROCKET_3,SPR_ROCKET_4,
|
||||
SPR_ROCKET_5,SPR_ROCKET_6,SPR_ROCKET_7,SPR_ROCKET_8,
|
||||
|
||||
SPR_SMOKE_1,SPR_SMOKE_2,SPR_SMOKE_3,SPR_SMOKE_4,
|
||||
SPR_BOOM_1,SPR_BOOM_2,SPR_BOOM_3,
|
||||
|
||||
//
|
||||
// Angel of Death's DeathSparks(tm)
|
||||
//
|
||||
SPR_HROCKET_1,SPR_HROCKET_2,SPR_HROCKET_3,SPR_HROCKET_4,
|
||||
SPR_HROCKET_5,SPR_HROCKET_6,SPR_HROCKET_7,SPR_HROCKET_8,
|
||||
|
||||
SPR_HSMOKE_1,SPR_HSMOKE_2,SPR_HSMOKE_3,SPR_HSMOKE_4,
|
||||
SPR_HBOOM_1,SPR_HBOOM_2,SPR_HBOOM_3,
|
||||
|
||||
SPR_SPARK1,SPR_SPARK2,SPR_SPARK3,SPR_SPARK4,
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Gretel
|
||||
//
|
||||
SPR_GRETEL_W1,SPR_GRETEL_W2,SPR_GRETEL_W3,SPR_GRETEL_W4,
|
||||
SPR_GRETEL_SHOOT1,SPR_GRETEL_SHOOT2,SPR_GRETEL_SHOOT3,SPR_GRETEL_DEAD,
|
||||
|
||||
SPR_GRETEL_DIE1,SPR_GRETEL_DIE2,SPR_GRETEL_DIE3,
|
||||
|
||||
//
|
||||
// Fat Face
|
||||
//
|
||||
SPR_FAT_W1,SPR_FAT_W2,SPR_FAT_W3,SPR_FAT_W4,
|
||||
SPR_FAT_SHOOT1,SPR_FAT_SHOOT2,SPR_FAT_SHOOT3,SPR_FAT_SHOOT4,
|
||||
|
||||
SPR_FAT_DIE1,SPR_FAT_DIE2,SPR_FAT_DIE3,SPR_FAT_DEAD,
|
||||
|
||||
//
|
||||
// bj
|
||||
//
|
||||
SPR_BJ_W1,SPR_BJ_W2,SPR_BJ_W3,SPR_BJ_W4,
|
||||
SPR_BJ_JUMP1,SPR_BJ_JUMP2,SPR_BJ_JUMP3,SPR_BJ_JUMP4,
|
||||
|
||||
|
||||
//
|
||||
// SPEAR OF DESTINY
|
||||
//
|
||||
|
||||
//
|
||||
// Trans Grosse
|
||||
//
|
||||
SPR_TRANS_W1,SPR_TRANS_W2,SPR_TRANS_W3,SPR_TRANS_W4,
|
||||
SPR_TRANS_SHOOT1,SPR_TRANS_SHOOT2,SPR_TRANS_SHOOT3,SPR_TRANS_DEAD,
|
||||
|
||||
SPR_TRANS_DIE1,SPR_TRANS_DIE2,SPR_TRANS_DIE3,
|
||||
|
||||
//
|
||||
// Wilhelm
|
||||
//
|
||||
SPR_WILL_W1,SPR_WILL_W2,SPR_WILL_W3,SPR_WILL_W4,
|
||||
SPR_WILL_SHOOT1,SPR_WILL_SHOOT2,SPR_WILL_SHOOT3,SPR_WILL_SHOOT4,
|
||||
|
||||
SPR_WILL_DIE1,SPR_WILL_DIE2,SPR_WILL_DIE3,SPR_WILL_DEAD,
|
||||
|
||||
//
|
||||
// UberMutant
|
||||
//
|
||||
SPR_UBER_W1,SPR_UBER_W2,SPR_UBER_W3,SPR_UBER_W4,
|
||||
SPR_UBER_SHOOT1,SPR_UBER_SHOOT2,SPR_UBER_SHOOT3,SPR_UBER_SHOOT4,
|
||||
|
||||
SPR_UBER_DIE1,SPR_UBER_DIE2,SPR_UBER_DIE3,SPR_UBER_DIE4,
|
||||
SPR_UBER_DEAD,
|
||||
|
||||
//
|
||||
// Death Knight
|
||||
//
|
||||
SPR_DEATH_W1,SPR_DEATH_W2,SPR_DEATH_W3,SPR_DEATH_W4,
|
||||
SPR_DEATH_SHOOT1,SPR_DEATH_SHOOT2,SPR_DEATH_SHOOT3,SPR_DEATH_SHOOT4,
|
||||
|
||||
SPR_DEATH_DIE1,SPR_DEATH_DIE2,SPR_DEATH_DIE3,SPR_DEATH_DIE4,
|
||||
SPR_DEATH_DIE5,SPR_DEATH_DIE6,SPR_DEATH_DEAD,
|
||||
|
||||
//
|
||||
// Ghost
|
||||
//
|
||||
SPR_SPECTRE_W1,SPR_SPECTRE_W2,SPR_SPECTRE_W3,SPR_SPECTRE_W4,
|
||||
SPR_SPECTRE_F1,SPR_SPECTRE_F2,SPR_SPECTRE_F3,SPR_SPECTRE_F4,
|
||||
|
||||
//
|
||||
// Angel of Death
|
||||
//
|
||||
SPR_ANGEL_W1,SPR_ANGEL_W2,SPR_ANGEL_W3,SPR_ANGEL_W4,
|
||||
SPR_ANGEL_SHOOT1,SPR_ANGEL_SHOOT2,SPR_ANGEL_TIRED1,SPR_ANGEL_TIRED2,
|
||||
|
||||
SPR_ANGEL_DIE1,SPR_ANGEL_DIE2,SPR_ANGEL_DIE3,SPR_ANGEL_DIE4,
|
||||
SPR_ANGEL_DIE5,SPR_ANGEL_DIE6,SPR_ANGEL_DIE7,SPR_ANGEL_DEAD,
|
||||
|
||||
|
||||
|
||||
//
|
||||
// player attack frames
|
||||
//
|
||||
SPR_KNIFEREADY,SPR_KNIFEATK1,SPR_KNIFEATK2,SPR_KNIFEATK3,
|
||||
SPR_KNIFEATK4,
|
||||
|
||||
SPR_PISTOLREADY,SPR_PISTOLATK1,SPR_PISTOLATK2,SPR_PISTOLATK3,
|
||||
SPR_PISTOLATK4,
|
||||
|
||||
SPR_MACHINEGUNREADY,SPR_MACHINEGUNATK1,SPR_MACHINEGUNATK2,MACHINEGUNATK3,
|
||||
SPR_MACHINEGUNATK4,
|
||||
|
||||
SPR_CHAINREADY,SPR_CHAINATK1,SPR_CHAINATK2,SPR_CHAINATK3,
|
||||
SPR_CHAINATK4,
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#define SPRT_ONE_TEX 1
|
||||
#define SPRT_NO_ROT 2
|
||||
#define SPRT_CHG_POS 4
|
||||
#define SPRT_CHG_TEX 8
|
||||
#define SPRT_REMOVE 16
|
||||
|
||||
typedef struct sprite_s
|
||||
{
|
||||
vec3_t position;
|
||||
int x, y, ang;
|
||||
// very clever to make it not just (x>>TILESHIFT)
|
||||
// but also (x>>TILESHIFT)-1 if (x%TILEWIDTH)<HALFTILE
|
||||
// so we will check only 4 files instead of 9 as Carmack did!
|
||||
int tilex, tiley;
|
||||
// controls appearence of this sprite:
|
||||
// SPRT_ONE_TEX: use one texture for each rotation
|
||||
// SPRT_NO_ROT: do not rotate sprite (fence)
|
||||
// SPRT_CHG_POS
|
||||
// SPRT_CHG_TEX
|
||||
// SPRT_REMOVE
|
||||
int flags;
|
||||
// 8 textures: one for each rotation phase!
|
||||
// if SPRT_ONE_TEX flag use tex with index 0!
|
||||
|
||||
// these are Wolf sprite texture numbers, not OpenGL sprites
|
||||
// or indexes in the textureManager list
|
||||
int tex[ 8 ];
|
||||
} sprite_t;
|
||||
|
||||
// total sprites on level in a moment
|
||||
#define MAX_SPRITES 1024
|
||||
|
||||
typedef struct visobj_s
|
||||
{
|
||||
int viewx, viewheight; // obsolete, but will do in software rendering!
|
||||
int dist; // how we will sort them
|
||||
int x, y; // position in game space! (for OpenGL)
|
||||
int ang; // for md2 rotation
|
||||
int tex; // texture to draw (renderer must know what to draw by this number!
|
||||
|
||||
} visobj_t;
|
||||
|
||||
extern visobj_t vislist[];
|
||||
|
||||
|
||||
extern void Sprite_Reset( void );
|
||||
|
||||
|
||||
extern void Sprite_RemoveSprite( int sprite_id );
|
||||
extern int Sprite_GetNewSprite( void );
|
||||
extern void Sprite_SetPos( int sprite_id, int x, int y, int angle );
|
||||
extern void Sprite_SetTex( int sprite_id, int index, int tex );
|
||||
extern int Sprite_CreateVisList( void );
|
||||
|
||||
|
||||
#endif /* __WOLF_SPRITES_H__ */
|
||||
|
||||
95
wolf3d/code/wolf/wolf_sv_ccmds.c
Normal file
95
wolf3d/code/wolf/wolf_sv_ccmds.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
extern void Client_PrepRefresh( const char *r_mapname );
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PRIVATE void SV_GameMap_f( void )
|
||||
{
|
||||
char *map;
|
||||
char r_mapname[ 32 ];
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Com_Printf( "USAGE: gamemap <map>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Com_DPrintf( "SV_GameMap( %s )\n", Cmd_Argv( 1 ) );
|
||||
|
||||
FS_CreatePath( va( "%s/save/current/", FS_Gamedir() ) );
|
||||
|
||||
// check for clearing the current savegame
|
||||
map = Cmd_Argv( 1 );
|
||||
|
||||
// start up the next map
|
||||
my_strlcpy( r_mapname, Cmd_Argv( 1 ), sizeof( r_mapname ) );
|
||||
|
||||
Client_PrepRefresh( r_mapname );
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void Map_f( void )
|
||||
{
|
||||
char *map;
|
||||
char expanded[ MAX_GAMEPATH ];
|
||||
|
||||
// Check to make sure the level exists.
|
||||
map = Cmd_Argv( 1 );
|
||||
if( ! strstr( map, "." ) )
|
||||
{
|
||||
my_snprintf( expanded, sizeof( expanded ), "maps/%s.map", map );
|
||||
}
|
||||
else
|
||||
{
|
||||
my_snprintf( expanded, sizeof( expanded ), "maps/%s", map );
|
||||
}
|
||||
|
||||
|
||||
//sv.state = ss_dead; // don't save current level when changing
|
||||
// SV_WipeSavegame( "current" );
|
||||
SV_GameMap_f();
|
||||
}
|
||||
|
||||
194
wolf3d/code/wolf/wolf_weapon.c
Normal file
194
wolf3d/code/wolf/wolf_weapon.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
|
||||
Copyright (C) 2004 Michael Liebscher
|
||||
Copyright (C) 2000-2002 by DarkOne the Hacker
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include "../wolfiphone.h"
|
||||
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void fire_hit( player_t *self )
|
||||
{
|
||||
entity_t *closest;
|
||||
int dist, d1, n, shot_dist, damage;
|
||||
|
||||
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "lsfx/023.wav" ), 1, ATTN_NORM, 0 );
|
||||
|
||||
// actually fire
|
||||
dist = 0x7fffffff;
|
||||
closest = NULL;
|
||||
|
||||
for( n = 0 ; n < NumGuards ; ++n )
|
||||
{
|
||||
if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
|
||||
{
|
||||
shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
|
||||
|
||||
if( shot_dist > (2 * TILEGLOBAL / 3) )
|
||||
{
|
||||
continue; // miss
|
||||
}
|
||||
|
||||
d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
|
||||
|
||||
if( d1 < 0 || d1 > dist )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
|
||||
{
|
||||
//if( ! CheckLine( &Guards[ n ] ) )
|
||||
continue; // obscured
|
||||
}
|
||||
|
||||
dist = d1;
|
||||
closest = &Guards[ n ];
|
||||
}
|
||||
}
|
||||
|
||||
if( ! closest || dist > TILE2POS( 1 ) )
|
||||
{
|
||||
return; // missed if further than 1.5 tiles
|
||||
}
|
||||
|
||||
damage = US_RndT() >> 4;
|
||||
|
||||
A_DamageActor( closest, damage ); // hit something
|
||||
}
|
||||
|
||||
/*
|
||||
-----------------------------------------------------------------------------
|
||||
Function:
|
||||
|
||||
Parameters:
|
||||
|
||||
Returns:
|
||||
|
||||
Notes:
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
PUBLIC void fire_lead( player_t *self )
|
||||
{
|
||||
entity_t *closest;
|
||||
int damage;
|
||||
int dx, dy, dist;
|
||||
int d1, shot_dist, n;
|
||||
|
||||
switch( self->weapon )
|
||||
{
|
||||
case WEAPON_PISTOL:
|
||||
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/012.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case WEAPON_AUTO:
|
||||
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/011.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
|
||||
case WEAPON_CHAIN:
|
||||
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/013.wav" ), 1, ATTN_NORM, 0 );
|
||||
break;
|
||||
}
|
||||
self->madenoise = true;
|
||||
|
||||
dist = 0x7fffffffl;
|
||||
closest = NULL;
|
||||
|
||||
for( n = 0 ; n < NumGuards; ++n )
|
||||
{
|
||||
if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
|
||||
{
|
||||
shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
|
||||
if( shot_dist > (2 * TILEGLOBAL / 3) )
|
||||
{
|
||||
continue; // miss
|
||||
}
|
||||
|
||||
d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
|
||||
if( d1 < 0 || d1 > dist )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
|
||||
{
|
||||
//if( ! CheckLine( &Guards[ n ] ) )
|
||||
continue; // obscured
|
||||
}
|
||||
|
||||
dist = d1;
|
||||
closest = &Guards[ n ];
|
||||
}
|
||||
}
|
||||
|
||||
if( ! closest ) // missed
|
||||
{
|
||||
r_trace_t trace;
|
||||
|
||||
trace.a = NormalizeAngle( self->position.angle - DEG2FINE( 2 ) + rand() % (DEG2FINE( 4 ) ) );
|
||||
trace.x = self->position.origin[ 0 ];
|
||||
trace.y = self->position.origin[ 1 ];
|
||||
trace.flags = TRACE_BULLET;
|
||||
trace.tile_vis = NULL;
|
||||
R_Trace( &trace, r_world );
|
||||
|
||||
if( trace.flags & TRACE_HIT_DOOR )
|
||||
{
|
||||
Sound_StartSound( NULL, 0, CHAN_AUTO, Sound_RegisterSound( "lsfx/028.wav" ), 1, ATTN_NORM, 0 );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// hit something
|
||||
dx = ABS( closest->tilex - self->tilex );
|
||||
dy = ABS( closest->tiley - self->tiley );
|
||||
dist = max_of_2( dx, dy );
|
||||
|
||||
if( dist < 2 )
|
||||
{
|
||||
damage = US_RndT() / 4;
|
||||
}
|
||||
else if( dist < 4 )
|
||||
{
|
||||
damage = US_RndT() / 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( US_RndT() / 12 < dist )
|
||||
{
|
||||
return; // missed
|
||||
}
|
||||
|
||||
damage = US_RndT() / 6;
|
||||
}
|
||||
|
||||
A_DamageActor( closest, damage );
|
||||
}
|
||||
Reference in New Issue
Block a user