📄 sector.c
字号:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is NOT part of Duke Nukem 3D version 1.5 - Atomic EditionHowever, it is either an older version of a file that is, or issome test code written during the development of Duke Nukem 3D.This file is provided purely for educational interest.Duke Nukem 3D 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.
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "duke3d.h"
// PRIMITIVE
char haltsoundhack;
short callsound(short sn,short whatsprite)
{
short i;
if(haltsoundhack)
{
haltsoundhack = 0;
return -1;
}
i = headspritesect[sn];
while(i >= 0)
{
if( PN == MUSICANDSFX && SLT < 1000 )
{
if(whatsprite == -1) whatsprite = i;
if(T1 == 0)
{
if( (soundm[SLT]&16) == 0)
{
if(SLT)
{
spritesound(SLT,whatsprite);
if(SHT && SLT != SHT && SHT < NUM_SOUNDS)
stopsound(SHT);
}
if( (sector[SECT].lotag&0xff) != 22)
T1 = 1;
}
}
else if(SHT < NUM_SOUNDS)
{
if(SHT) spritesound(SHT,whatsprite);
if( (soundm[SLT]&1) || ( SHT && SHT != SLT ) )
stopsound(SLT);
T1 = 0;
}
return SLT;
}
i = nextspritesect[i];
}
return -1;
}
short check_activator_motion( short lotag )
{
short i, j;
spritetype *s;
i = headspritestat[8];
while ( i >= 0 )
{
if ( sprite[i].lotag == lotag )
{
s = &sprite[i];
for ( j = animatecnt-1; j >= 0; j-- )
if ( s->sectnum == animatesect[j] )
return( 1 );
j = headspritestat[3];
while ( j >= 0 )
{
if(s->sectnum == sprite[j].sectnum)
switch(sprite[j].lotag)
{
case 11:
case 30:
if ( hittype[j].temp_data[4] )
return( 1 );
break;
case 20:
case 31:
case 32:
case 18:
if ( hittype[j].temp_data[0] )
return( 1 );
break;
}
j = nextspritestat[j];
}
}
i = nextspritestat[i];
}
return( 0 );
}
char isadoorwall(short dapic)
{
switch(dapic)
{
case DOORTILE1:
case DOORTILE2:
case DOORTILE3:
case DOORTILE4:
case DOORTILE5:
case DOORTILE6:
case DOORTILE7:
case DOORTILE8:
case DOORTILE9:
case DOORTILE10:
case DOORTILE11:
case DOORTILE12:
case DOORTILE14:
case DOORTILE15:
case DOORTILE16:
case DOORTILE17:
case DOORTILE18:
case DOORTILE19:
case DOORTILE20:
case DOORTILE21:
case DOORTILE22:
case DOORTILE23:
return 1;
}
return 0;
}
char isanunderoperator(short lotag)
{
switch(lotag&0xff)
{
case 15:
case 16:
case 17:
case 18:
case 19:
case 22:
case 26:
return 1;
}
return 0;
}
char isanearoperator(short lotag)
{
switch(lotag&0xff)
{
case 9:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 25:
case 26:
case 29://Toothed door
return 1;
}
return 0;
}
short checkcursectnums(short sect)
{
short i;
for(i=connecthead;i>=0;i=connectpoint2[i])
if( sprite[ps[i].i].sectnum == sect ) return i;
return -1;
}
long ldist(spritetype *s1,spritetype *s2)
{
long vx,vy;
vx = s1->x - s2->x;
vy = s1->y - s2->y;
return(FindDistance2D(vx,vy) + 1);
}
long dist(spritetype *s1,spritetype *s2)
{
long vx,vy,vz;
vx = s1->x - s2->x;
vy = s1->y - s2->y;
vz = s1->z - s2->z;
return(FindDistance3D(vx,vy,vz>>4));
}
short findplayer(spritetype *s,long *d)
{
short j, closest_player;
long x, closest;
if(ud.multimode < 2)
{
*d = klabs(ps[myconnectindex].oposx-s->x) + klabs(ps[myconnectindex].oposy-s->y) + ((klabs(ps[myconnectindex].oposz-s->z+(28<<8)))>>4);
return myconnectindex;
}
closest = 0x7fffffff;
closest_player = 0;
for(j=connecthead;j>=0;j=connectpoint2[j])
{
x = klabs(ps[j].oposx-s->x) + klabs(ps[j].oposy-s->y) + ((klabs(ps[j].oposz-s->z+(28<<8)))>>4);
if( x < closest && sprite[ps[j].i].extra > 0 )
{
closest_player = j;
closest = x;
}
}
*d = closest;
return closest_player;
}
short findotherplayer(short p,long *d)
{
short j, closest_player;
long x, closest;
closest = 0x7fffffff;
closest_player = p;
for(j=connecthead;j>=0;j=connectpoint2[j])
if(p != j && sprite[ps[j].i].extra > 0)
{
x = klabs(ps[j].oposx-ps[p].posx) + klabs(ps[j].oposy-ps[p].posy) + (klabs(ps[j].oposz-ps[p].posz)>>4);
if( x < closest )
{
closest_player = j;
closest = x;
}
}
*d = closest;
return closest_player;
}
void doanimations(void)
{
long i, j, a, p, v, dasect;
for(i=animatecnt-1;i>=0;i--)
{
a = *animateptr[i];
v = animatevel[i]*TICSPERFRAME;
dasect = animatesect[i];
if (a == animategoal[i])
{
stopinterpolation(animateptr[i]);
animatecnt--;
animateptr[i] = animateptr[animatecnt];
animategoal[i] = animategoal[animatecnt];
animatevel[i] = animatevel[animatecnt];
animatesect[i] = animatesect[animatecnt];
if( sector[animatesect[i]].lotag == 18 || sector[animatesect[i]].lotag == 19 )
if(animateptr[i] == §or[animatesect[i]].ceilingz)
continue;
if( (sector[dasect].lotag&0xff) != 22 )
callsound(dasect,-1);
continue;
}
if (v > 0) { a = min(a+v,animategoal[i]); }
else { a = max(a+v,animategoal[i]); }
if( animateptr[i] == §or[animatesect[i]].floorz)
{
for(p=connecthead;p>=0;p=connectpoint2[p])
if (ps[p].cursectnum == dasect)
if ((sector[dasect].floorz-ps[p].posz) < (64<<8))
if (sprite[ps[p].i].owner >= 0)
{
ps[p].posz += v;
ps[p].poszv = 0;
if (p == myconnectindex)
{
myz += v;
myzvel = 0;
myzbak[((movefifoplc-1)&(MOVEFIFOSIZ-1))] = ps[p].posz;
}
}
for(j=headspritesect[dasect];j>=0;j=nextspritesect[j])
if (sprite[j].statnum != 3)
{
hittype[j].bposz = sprite[j].z;
sprite[j].z += v;
hittype[j].floorz = sector[dasect].floorz+v;
}
}
*animateptr[i] = a;
}
}
getanimationgoal(long *animptr)
{
long i, j;
j = -1;
for(i=animatecnt-1;i>=0;i--)
if (animptr == (long *)animateptr[i])
{
j = i;
break;
}
return(j);
}
setanimation(short animsect,long *animptr, long thegoal, long thevel)
{
long i, j;
if (animatecnt >= MAXANIMATES-1)
return(-1);
j = animatecnt;
for(i=0;i<animatecnt;i++)
if (animptr == animateptr[i])
{
j = i;
break;
}
animatesect[j] = animsect;
animateptr[j] = animptr;
animategoal[j] = thegoal;
if (thegoal >= *animptr)
animatevel[j] = thevel;
else
animatevel[j] = -thevel;
if (j == animatecnt) animatecnt++;
setinterpolation(animptr);
return(j);
}
void animatecamsprite(void)
{
short i;
if(camsprite <= 0) return;
i = camsprite;
if(T1 >= 11)
{
T1 = 0;
if(ps[screenpeek].newowner >= 0)
OW = ps[screenpeek].newowner;
else if(OW >= 0 && dist(&sprite[ps[screenpeek].i],&sprite[i]) < 2048)
xyzmirror(OW,PN);
}
else T1++;
}
void animatewalls(void)
{
long i, j, p, t;
for(p=0;p < numanimwalls ;p++)
// for(p=numanimwalls-1;p>=0;p--)
{
i = animwall[p].wallnum;
j = wall[i].picnum;
switch(j)
{
case SCREENBREAK1:
case SCREENBREAK2:
case SCREENBREAK3:
case SCREENBREAK4:
case SCREENBREAK5:
case SCREENBREAK9:
case SCREENBREAK10:
case SCREENBREAK11:
case SCREENBREAK12:
case SCREENBREAK13:
case SCREENBREAK14:
case SCREENBREAK15:
case SCREENBREAK16:
case SCREENBREAK17:
case SCREENBREAK18:
case SCREENBREAK19:
if( (TRAND&255) < 16)
{
animwall[p].tag = wall[i].picnum;
wall[i].picnum = SCREENBREAK6;
}
continue;
case SCREENBREAK6:
case SCREENBREAK7:
case SCREENBREAK8:
if(animwall[p].tag >= 0 && wall[i].extra != FEMPIC2 && wall[i].extra != FEMPIC3 )
wall[i].picnum = animwall[p].tag;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -