Files
lba1-classic/SOURCES/OBJECT.C

3445 lines
83 KiB
C

#include "c_extern.h"
/*
WORD GiveMaxLevel( WORD x, WORD y ) ;
void DrawOverBrick( WORD xm, WORD ym, WORD zm ) ;
void DrawOverBrick2( WORD xm, WORD ym, WORD zm ) ;
*/
UBYTE WorldColBrick( WORD xw, WORD yw, WORD zw ) ;
WORD Nxw, Nyw, Nzw ;
WORD SaveNxw, SaveNyw, SaveNzw ;
WORD OldX, OldY, OldZ ;
WORD AnimNumObj ;
T_OBJET *APtObj ;
WORD LastJoyFlag = FALSE ;
WORD LastMyJoy = 0 ;
WORD LastMyFire = 0 ;
WORD Col1 ;
void IncrustGrm( WORD numgrm ) ;
WORD ZoneGrm = -1 ;
WORD IndexGrm = -1 ;
WORD BetaUsedObj = 0 ;
extern LONG XMap, YMap, ZMap ;
extern WORD M_Xmin, M_Xmax, M_Ymin, M_Ymax, M_Zmin, M_Zmax ;
extern UBYTE *SearchPtrAnimAction ;
/*══════════════════════════════════════════════════════════════════════════*
█▀▀▀█ █▀▀█ █ █▀▀▀▀ █▀▀▀▀ ▀▀█▀▀ ██▀▀▀
██ █ ██▀▀█ ▄▄ █ ██▀▀ ██ ██ ▀▀▀▀█
▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
extern UBYTE *PtrScene ;
void InitObject( WORD numobj )
{
T_OBJET *ptrobj ;
UBYTE *ptr ;
ptrobj = &ListObjet[numobj] ;
ptrobj->GenBody = GEN_BODY_NORMAL ;
ptrobj->GenAnim = GEN_ANIM_RIEN ;
ptrobj->PosObjX = 0 ;
ptrobj->PosObjY = SIZE_BRICK_Y ;
ptrobj->PosObjZ = 0 ;
ptrobj->Xmin = 0 ;
ptrobj->Xmax = 0 ;
ptrobj->Ymin = 0 ;
ptrobj->Ymax = 0 ;
ptrobj->Zmin = 0 ;
ptrobj->Zmax = 0 ;
ptrobj->Beta = 0 ;
ptrobj->SRot = 40 ;
ptrobj->Move = NO_MOVE ;
ptrobj->Info = 0 ;
ptrobj->Info1 = 0 ;
ptrobj->Info2 = 0 ;
ptrobj->Info3 = 0 ;
ptrobj->Col = 0 ;
ptrobj->ObjCol = -1 ;
ptrobj->CarryBy = -1 ;
ptrobj->ZoneSce = -1 ;
ptrobj->Flags = 0 ;
ptrobj->WorkFlags = 0 ;
ptrobj->LifePoint = 50 ;
ptrobj->Armure = 1 ;
ptrobj->HitBy = -1 ;
ptrobj->AnimStepBeta = 0 ;
ptrobj->AnimStepX = 0 ;
ptrobj->AnimStepY = 0 ;
ptrobj->AnimStepZ = 0 ;
// ptrobj->GenBody = NO_BODY ;
// ptrobj->GenAnim = NO_ANIM ;
ptrobj->Body = -1 ;
ptrobj->Anim = -1 ;
ptrobj->FlagAnim = 0 ;
ptrobj->Frame = 0 ;
InitRealAngle( 0,0, 0, &ptrobj->RealAngle ) ;
ptrobj->OffsetTrack = -1 ;
ptrobj->OffsetLife = 0 ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void StartInitObj( WORD numobj )
{
T_OBJET *ptrobj ;
WORD m ;
ptrobj = &ListObjet[numobj] ;
if( ptrobj->Flags & SPRITE_3D )
{
if( ptrobj->HitForce != 0 )
ptrobj->WorkFlags |= OK_HIT ;
ptrobj->Body = -1 ;
InitSprite( ptrobj->Sprite, numobj ) ;
InitRealAngle( 0,0,0, &ptrobj->RealAngle ) ;
if( ptrobj->Flags & SPRITE_CLIP )
{
ptrobj->AnimStepX = ptrobj->PosObjX ;
ptrobj->AnimStepY = ptrobj->PosObjY ;
ptrobj->AnimStepZ = ptrobj->PosObjZ ;
}
}
else
{
ptrobj->Body = -1 ;
InitBody( ptrobj->GenBody, numobj ) ;
ptrobj->Anim = -1 ;
ptrobj->FlagAnim = 0 ;
if( ptrobj->Body != -1 )
{
InitAnim( ptrobj->GenAnim, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
InitRealAngle( ptrobj->Beta,
ptrobj->Beta,
0, &ptrobj->RealAngle ) ;
}
ptrobj->OffsetTrack = -1 ;
ptrobj->LabelTrack = -1 ;
ptrobj->OffsetLife = 0 ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void StartInitAllObjs()
{
WORD n ;
for( n=1; n<NbObjets; n++ )
{
StartInitObj( n ) ;
}
}
/*══════════════════════════════════════════════════════════════════════════*/
void LoadFicPerso()
{
T_OBJET *ptrobj ;
ptrobj = &ListObjet[NUM_PERSO] ;
HQRM_Load( PATH_RESSOURCE"FILE3D.HQR",FILE_3D_SPORTIF , &PtrFile3dSportif ) ;
CHECK_MEMORY
ptrobj->PtrFile3D = PtrFile3dSportif ;
AnimRienSportif = SearchAnim( GEN_ANIM_RIEN, NUM_PERSO ) ;
HQRM_Load( PATH_RESSOURCE"FILE3D.HQR",FILE_3D_AGRESSIF, &PtrFile3dAgressif ) ;
CHECK_MEMORY
ptrobj->PtrFile3D = PtrFile3dAgressif ;
AnimRienAgressif = SearchAnim( GEN_ANIM_RIEN, NUM_PERSO ) ;
HQRM_Load( PATH_RESSOURCE"FILE3D.HQR",FILE_3D_DISCRET, &PtrFile3dDiscret ) ;
CHECK_MEMORY
ptrobj->PtrFile3D = PtrFile3dDiscret ;
AnimRienDiscret = SearchAnim( GEN_ANIM_RIEN, NUM_PERSO ) ;
HQRM_Load( PATH_RESSOURCE"FILE3D.HQR",FILE_3D_PROTOPACK, &PtrFile3dProtopack ) ;
CHECK_MEMORY
ptrobj->PtrFile3D = PtrFile3dProtopack ;
AnimRienProtopack = SearchAnim( GEN_ANIM_RIEN, NUM_PERSO ) ;
HQRM_Load( PATH_RESSOURCE"FILE3D.HQR",FILE_3D_NORMAL, &PtrFile3dNormal ) ;
CHECK_MEMORY
ptrobj->PtrFile3D = PtrFile3dNormal ;
AnimRienNormal = SearchAnim( GEN_ANIM_RIEN, NUM_PERSO ) ;
ptrobj->PtrAnimAction = SearchPtrAnimAction ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void InitPerso()
{
T_OBJET *ptrobj ;
InitObject( NUM_PERSO ) ;
ptrobj = &ListObjet[NUM_PERSO] ;
ptrobj->GenBody = GEN_BODY_NORMAL ;
ptrobj->LifePoint = 50 ;
ptrobj->CoulObj = 4 ; /* bleu twinkel */
NbGoldPieces = 0 ;
NbLittleKeys = 0 ;
MagicPoint = 0 ;
MagicBall = -1 ;
NbCloverBox = 2 ;
NbFourLeafClover = 2 ;
Weapon = 0 ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void SetComportement( WORD comportement )
{
T_OBJET *ptrobj ;
WORD memogenbody ;
ptrobj = &ListObjet[ NUM_PERSO ] ;
switch( comportement )
{
case C_NORMAL:
Comportement = C_NORMAL ;
ptrobj->PtrFile3D = PtrFile3dNormal ;
break ;
case C_SPORTIF:
Comportement = C_SPORTIF ;
ptrobj->PtrFile3D = PtrFile3dSportif ;
break ;
case C_AGRESSIF:
Comportement = C_AGRESSIF ;
ptrobj->PtrFile3D = PtrFile3dAgressif ;
break ;
case C_DISCRET:
Comportement = C_DISCRET ;
ptrobj->PtrFile3D = PtrFile3dDiscret ;
break ;
case C_PROTOPACK:
Comportement = C_PROTOPACK ;
ptrobj->PtrFile3D = PtrFile3dProtopack ;
break ;
}
memogenbody = ptrobj->GenBody ;
ptrobj->GenBody = NO_BODY ;
ptrobj->Body = -1 ;
InitBody( memogenbody, NUM_PERSO ) ;
ptrobj->GenAnim = NO_ANIM ;
ptrobj->FlagAnim = 0 ;
InitAnim( GEN_ANIM_RIEN, ANIM_REPEAT, NO_ANIM, NUM_PERSO ) ;
}
/*──────────────────────────────────────────────────────────────────────────*/
// reinitialise tout perso sans toucher à sa position
void RestartPerso()
{
T_OBJET *ptrobj ;
UBYTE memogenbody ;
ptrobj = &ListObjet[NUM_PERSO] ;
ptrobj->Move = MOVE_MANUAL ;
ptrobj->WorkFlags = 0 ;
ptrobj->Flags = OBJ_FALLABLE
+ CHECK_ZONE
+ CHECK_OBJ_COL
+ CHECK_BRICK_COL
+ CHECK_CODE_JEU ;
ptrobj->Armure = 1 ;
ptrobj->OffsetTrack = -1 ;
ptrobj->LabelTrack = -1 ;
ptrobj->OffsetLife = 0 ;
ptrobj->ZoneSce = -1 ;
ptrobj->Beta = SaveBeta ;
InitRealAngle( ptrobj->Beta,
ptrobj->Beta,
0, &ptrobj->RealAngle ) ;
SetComportement( SaveComportement ) ;
// SetComportement( Comportement ) ;
FlagWater = FALSE ;
}
/*──────────────────────────────────────────────────────────────────────────*/
/* Call Every Change Cube */
void ClearFlagsCube()
{
WORD n ;
for( n=0; n<MAX_FLAGS_CUBE; n++ )
{
ListFlagCube[n] = 0 ;
}
}
/*══════════════════════════════════════════════════════════════════════════*
█▀▀▀▀ █▀▀▀▀ █▀▀▀█ █▀▀▀▀ ██▀▀▀ █▀▀▀▀ █▀▀▀▀ ██▄ █ █▀▀▀▀
██ ▀█ ██▀▀ ██▀█▀ ██▀▀ ▀▀▀▀█ ██ ██▀▀ ██▀██ ██▀▀
▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
void ClearScene()
{
UBYTE stringanim[256] ;
UBYTE stringbody[256] ;
LONG n ;
T_OBJET *ptrobj ;
UBYTE *ptr ;
ClearExtra() ;
ClearFlagsCube() ;
for( n=0; n<MAX_INCRUST_DISP; n++ )
{
ListIncrustDisp[n].Num = -1 ;
}
HQR_Reset_Ressource( HQR_Anims ) ;
HQM_Free_All() ;
NbBodys = 0 ;
FlagPalettePcx = FALSE ;
ClearDial() ;
}
/*══════════════════════════════════════════════════════════════════════════*/
// need: NewCube
// FlagChgCube == 1 : zone de chg cube recupere pos relative
// FlagChgCube == 2 : instruction chg cube positionne sur saved StartPos
void ChangeCube()
{
WORD oldcube ;
T_OBJET *ptrobj ;
WORD newjingle = -1 ;
// grosse rustine scenarique
if( (NewCube == 4) AND (ListFlagGame[30]!=0) )
{
NewCube = 118 ;
}
oldcube = NumCube ;
NumCube = NewCube ;
// clear
HQ_StopSample() ;
if( FlagPalettePcx ) FadeToBlack( PalettePcx ) ;
else FadeToBlack( PtrPal ) ;
if( !FlagMCGA )
{
Cls() ;
Flip() ;
}
// demo version
/*
#ifdef DEMO
if( NumCube == 3 )
{
// PlayMidiFile( 6 ) ;
// Credits() ;
// TheEnd( PROGRAM_OK, "* End of Demo version." ) ;
FlagTheEnd = 1 ;
return ;
}
#endif
*/
FreeGrille() ;
ClearScene() ;
// perso reinit
LoadFicPerso() ;
ListObjet[NUM_PERSO].Move = MOVE_MANUAL ;
ListObjet[NUM_PERSO].ZoneSce = -1 ;
ListObjet[NUM_PERSO].OffsetLife = 0 ;
ListObjet[NUM_PERSO].OffsetTrack = -1 ;
ListObjet[NUM_PERSO].LabelTrack = -1 ;
// lance usine
LoadScene( NewCube ) ;
if( NumHolomapTraj != -1 )
{
TestRestoreModeSVGA( FALSE ) ;
SetBlackPal() ;
HoloTraj( NumHolomapTraj ) ;
NumHolomapTraj = -1 ;
}
if( (NumCube == 116) OR (NumCube == 117) ) Island = 10 ;
InitDial( START_FILE_ISLAND+Island ) ;// Pas Mini (Loran)
// play midi
if( CubeJingle != 255 )
{
if( (NumXmi != CubeJingle) AND (IsMidiPlaying()) )
{
FadeMusicMidi( 1 ) ;
}
}
// load gri
InitGrille( NewCube ) ;/* HQR */
if( FlagChgCube == 1 )
{
SceneStartX = NewPosX ;
SceneStartY = NewPosY ;
SceneStartZ = NewPosZ ;
}
if( FlagChgCube == 2
OR FlagChgCube == 0 )
{
SceneStartX = CubeStartX ;
SceneStartY = CubeStartY ;
SceneStartZ = CubeStartZ ;
}
ListObjet[NUM_PERSO].PosObjX = SceneStartX ;
StartYFalling = ListObjet[NUM_PERSO].PosObjY = SceneStartY ;
ListObjet[NUM_PERSO].PosObjZ = SceneStartZ ;
// CopyListFlagGame() ; // save état en rentrant dans le cube
SetLightVector( AlphaLight, BetaLight, 0 ) ;
// PlayMidiFile( CubeJingle ) ;
if( NewCube != oldcube )
{
SaveComportement = Comportement ;
SaveBeta = ListObjet[NUM_PERSO].Beta ;
SaveGame() ;
}
RestartPerso() ;
StartInitAllObjs() ;
NbLittleKeys = 0 ;
MagicBall = -1 ;
LastJoyFlag = TRUE ;
ZoneGrm = -1 ;
IndexGrm = -1 ;
FirstTime = TRUE ;
FlagFade = TRUE ;
CameraZone = FALSE ;
// NumCube = NewCube ;
NewCube = -1 ;
FlagChgCube = 0 ;
FlagAffGrille = TRUE ;
SamplePlayed = 2+4+8 ; // joue le premier sample en 1er
TimerNextAmbiance = 0 ;
StartXCube = ((ListObjet[NumObjFollow].PosObjX+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
StartYCube = ((ListObjet[NumObjFollow].PosObjY+SIZE_BRICK_Y)/SIZE_BRICK_Y) ;
StartZCube = ((ListObjet[NumObjFollow].PosObjZ+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
SetLightVector( AlphaLight, BetaLight, 0 ) ;
if( CubeJingle != 255 )
{
PlayMusic( CubeJingle ) ;
}
}
/*══════════════════════════════════════════════════════════════════════════*
█▀▀▀▀ █▀▀▀█ █ █ █ ██▀▀▀ █ █▀▀▀█ ██▄ █ ██▀▀▀
██ ██ █ ██ ██ ██ ▀▀▀▀█ ██ ██ █ ██▀██ ▀▀▀▀█
▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
void HitObj( WORD numhitter, WORD num, WORD hitforce, WORD beta )
{
WORD memo ;
T_OBJET *ptrobjt ;
ptrobjt = &ListObjet[ num ] ;
if( ptrobjt->LifePoint <= 0 ) return ;
ptrobjt->HitBy = numhitter ;
if( ptrobjt->Armure <= hitforce )
{
if((ptrobjt->GenAnim == GEN_ANIM_CHOC)
OR (ptrobjt->GenAnim == GEN_ANIM_CHOC2) )
{
memo = ptrobjt->Frame ;
ptrobjt->Frame = 1 ;
GereAnimAction( ptrobjt, num ) ;
ptrobjt->Frame = memo ;
}
else
{
if( beta != -1 )
InitRealAngle( beta,beta, 0, &ptrobjt->RealAngle ) ;
if( !(rand()&1) )
InitAnim( GEN_ANIM_CHOC, ANIM_INSERT, NO_ANIM, num ) ;
else
InitAnim( GEN_ANIM_CHOC2, ANIM_INSERT, NO_ANIM, num ) ;
}
/* effet special choc */
/* etoile */
InitSpecial( ptrobjt->PosObjX,
ptrobjt->PosObjY+1000,
ptrobjt->PosObjZ,
0 ) ;
if( num == NUM_PERSO )
{
LastJoyFlag = TRUE ;
}
ptrobjt->LifePoint -= hitforce ;
/* attention dans l'outil LifePoint est un word
si ca devient un UBYTE pas de signe */
// if( ptrobjt->LifePoint > 127 ) ptrobjt->LifePoint = 0 ;
if( ptrobjt->LifePoint < 0 ) ptrobjt->LifePoint = 0 ;
}
else
{
InitAnim( GEN_ANIM_ENCAISSE, ANIM_INSERT, NO_ANIM, num ) ;
}
}
/*──────────────────────────────────────────────────────────────────────────*/
LONG CheckZvOnZv( WORD numobj, WORD numobjt )
{
T_OBJET *ptrobj ;
T_OBJET *ptrobjt ;
WORD x0,y0,z0, x1,y1,z1 ;
WORD xt0,yt0,zt0, xt1,yt1,zt1 ;
ptrobj = &ListObjet[numobj] ;
x0 = Nxw + ptrobj->Xmin ;
x1 = Nxw + ptrobj->Xmax ;
y0 = Nyw + ptrobj->Ymin ;
y1 = Nyw + ptrobj->Ymax ;
z0 = Nzw + ptrobj->Zmin ;
z1 = Nzw + ptrobj->Zmax ;
ptrobjt = &ListObjet[numobjt] ;
xt0 = ptrobjt->PosObjX + ptrobjt->Xmin ;
xt1 = ptrobjt->PosObjX + ptrobjt->Xmax ;
yt0 = ptrobjt->PosObjY + ptrobjt->Ymin ;
yt1 = ptrobjt->PosObjY + ptrobjt->Ymax ;
zt0 = ptrobjt->PosObjZ + ptrobjt->Zmin ;
zt1 = ptrobjt->PosObjZ + ptrobjt->Zmax ;
if( x0 < xt1
AND x1 > xt0
AND y0 <= (yt1+1)
AND y0 > (yt1 - SIZE_BRICK_Y)
AND y1 > yt0
AND z0 < zt1
AND z1 > zt0 )
{
return TRUE ;
}
return FALSE ;
}
/*──────────────────────────────────────────────────────────────────────────*/
WORD CheckObjCol( WORD numobj )
{
WORD n, angle ;
T_OBJET *ptrobj ;
T_OBJET *ptrobjt ;
WORD x0,y0,z0, x1,y1,z1 ;
WORD xt0,yt0,zt0, xt1,yt1,zt1 ;
ptrobj = &ListObjet[numobj] ;
x0 = Nxw + ptrobj->Xmin ;
x1 = Nxw + ptrobj->Xmax ;
y0 = Nyw + ptrobj->Ymin ;
y1 = Nyw + ptrobj->Ymax ;
z0 = Nzw + ptrobj->Zmin ;
z1 = Nzw + ptrobj->Zmax ;
ptrobjt = ListObjet ;
ptrobj->ObjCol = -1 ;
for( n=0; n<NbObjets; n++,ptrobjt++ )
{
if( (n != numobj)
AND (ptrobjt->Body != -1)
AND (!(ptrobj->Flags&INVISIBLE))
AND (ptrobjt->CarryBy != numobj) )
{
xt0 = ptrobjt->PosObjX + ptrobjt->Xmin ;
xt1 = ptrobjt->PosObjX + ptrobjt->Xmax ;
yt0 = ptrobjt->PosObjY + ptrobjt->Ymin ;
yt1 = ptrobjt->PosObjY + ptrobjt->Ymax ;
zt0 = ptrobjt->PosObjZ + ptrobjt->Zmin ;
zt1 = ptrobjt->PosObjZ + ptrobjt->Zmax ;
if( x0 < xt1
AND x1 > xt0
AND y0 < yt1
AND y1 > yt0
AND z0 < zt1
AND z1 > zt0 )
{
ptrobj->ObjCol = n ;
if( ptrobjt->Flags & OBJ_CARRIER )
{
// je touche un transporteur
if( ptrobj->WorkFlags & FALLING )
{
Nyw = yt1 - ptrobj->Ymin + 1 ;
ptrobj->CarryBy = n ;
continue ;
}
else
{
if( CheckZvOnZv( numobj, n ) )
{
// je marche sur un transporteur */
Nyw = yt1 - ptrobj->Ymin + 1 ;
ptrobj->CarryBy = n ;
continue ;
}
}
}
else
{ // je marche sur quelqu'un
if( CheckZvOnZv( numobj, n ) )
{
HitObj( numobj, n, 1, -1 ) ;
}
}
angle = GetAngle( Nxw,Nzw,
ptrobjt->PosObjX,ptrobjt->PosObjZ ) ;
// test obj pushable
if( (ptrobjt->Flags & PUSHABLE)
AND !(ptrobj->Flags & PUSHABLE) ) // protect reaction en chaine
{
/* if( numobj == NUM_PERSO )
{
InitAnim( "pousse", ANIM_REPEAT, 0, NUM_PERSO ) ;
}
*/
ptrobjt->AnimStepY = 0 ;
if( ptrobjt->Flags & MINI_ZV )
{ // magouille boxxle
if( angle >= 128 AND angle < 384 )
if( ptrobj->Beta >= 128 AND ptrobj->Beta < 384 )
ptrobjt->AnimStepX = SIZE_BRICK_XZ/4 + SIZE_BRICK_XZ/8 ;
if( angle >= 384 AND angle < 640 )
if( ptrobj->Beta >= 384 AND ptrobj->Beta < 640 )
ptrobjt->AnimStepZ = -SIZE_BRICK_XZ/4 + SIZE_BRICK_XZ/8 ;
if( angle >= 640 AND angle < 896 )
if( ptrobj->Beta >= 640 AND ptrobj->Beta < 896 )
ptrobjt->AnimStepX = -SIZE_BRICK_XZ/4 + SIZE_BRICK_XZ/8 ;
if( angle >= 896 OR angle < 128 )
if( ptrobj->Beta >= 896 OR ptrobj->Beta < 128 )
ptrobjt->AnimStepZ = SIZE_BRICK_XZ/4 + SIZE_BRICK_XZ/8 ;
}
else
{ // induit deplacement avant reajustement ?
ptrobjt->AnimStepX = Nxw - ptrobj->OldPosX ;
ptrobjt->AnimStepZ = Nzw - ptrobj->OldPosZ ;
}
}
// joli mais ne fonctionne qu'avec
// des ZV carres
// donc rustine tempo
// if( ptrobjt->Xmax-ptrobjt->Xmin ==
// ptrobjt->Zmax-ptrobjt->Zmin )
if( (ptrobjt->Xmax-ptrobjt->Xmin ==
ptrobjt->Zmax-ptrobjt->Zmin )
AND
(ptrobj->Xmax-ptrobj->Xmin ==
ptrobj->Zmax-ptrobj->Zmin) )
{ // si ZV carre
if( angle >= 128 AND angle < 384 )
Nxw = xt0 - ptrobj->Xmax ;
if( angle >= 384 AND angle < 640 )
Nzw = zt1 - ptrobj->Zmin ;
if( angle >= 640 AND angle < 896 )
Nxw = xt1 - ptrobj->Xmin ;
if( angle >= 896 OR angle < 128 )
Nzw = zt0 - ptrobj->Zmax ;
}
else
{
if( !(ptrobj->WorkFlags & FALLING) ) // gloups
{
// refuse pos
Nxw = OldX ;
Nyw = OldY ;
Nzw = OldZ ;
}
}
}
}
}
// test deplace la ZV plus en avant si frappe
if( ptrobj->WorkFlags & OK_HIT )
{
Rotate( 0, 200, ptrobj->Beta ) ;
x0 = Nxw + ptrobj->Xmin + X0 ;
x1 = Nxw + ptrobj->Xmax + X0 ;
y0 = Nyw + ptrobj->Ymin ;
y1 = Nyw + ptrobj->Ymax ;
z0 = Nzw + ptrobj->Zmin + Y0 ;
z1 = Nzw + ptrobj->Zmax + Y0 ;
ptrobjt = ListObjet ;
for( n=0; n<NbObjets; n++,ptrobjt++ )
{
if( (n != numobj)
AND (ptrobjt->Body != -1)
AND (!(ptrobj->Flags&INVISIBLE))
AND (ptrobjt->CarryBy != numobj) )
{
xt0 = ptrobjt->PosObjX + ptrobjt->Xmin ;
xt1 = ptrobjt->PosObjX + ptrobjt->Xmax ;
yt0 = ptrobjt->PosObjY + ptrobjt->Ymin ;
yt1 = ptrobjt->PosObjY + ptrobjt->Ymax ;
zt0 = ptrobjt->PosObjZ + ptrobjt->Zmin ;
zt1 = ptrobjt->PosObjZ + ptrobjt->Zmax ;
if( x0 < xt1
AND x1 > xt0
AND y0 < yt1
AND y1 > yt0
AND z0 < zt1
AND z1 > zt0 )
{
HitObj( numobj, n, ptrobj->HitForce, ptrobj->Beta+512 ) ;
ptrobj->WorkFlags &= ~OK_HIT ;
}
}
}
}
return ptrobj->ObjCol ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void CheckCarrier( WORD numobj )
{
WORD n ;
if( ListObjet[numobj].Flags & OBJ_CARRIER )
{
for( n=0; n<NbObjets; n++ )
{
if( ListObjet[n].CarryBy == numobj )
{
ListObjet[n].CarryBy = -1 ;
}
}
}
}
/*──────────────────────────────────────────────────────────────────────────*/
LONG CheckValidObjPos( WORD numobj )
{
WORD n, angle ;
T_OBJET *ptrobj ;
T_OBJET *ptrobjt ;
WORD x0,y0,z0, x1,y1,z1 ;
WORD xt0,yt0,zt0, xt1,yt1,zt1 ;
ptrobj = &ListObjet[numobj] ;
x0 = ptrobj->PosObjX + ptrobj->Xmin ;
x1 = ptrobj->PosObjX + ptrobj->Xmax ;
y0 = ptrobj->PosObjY + ptrobj->Ymin ;
y1 = ptrobj->PosObjY + ptrobj->Ymax ;
z0 = ptrobj->PosObjZ + ptrobj->Zmin ;
z1 = ptrobj->PosObjZ + ptrobj->Zmax ;
if( (x0<0) OR (x0>SIZE_BRICK_XZ*63) ) return FALSE ;
if( (x1<0) OR (x1>SIZE_BRICK_XZ*63) ) return FALSE ;
if( (z0<0) OR (z0>SIZE_BRICK_XZ*63) ) return FALSE ;
if( (z1<0) OR (z1>SIZE_BRICK_XZ*63) ) return FALSE ;
// test decors
if( WorldColBrickFull( x0, y0, z0, ptrobj->Ymax ) ) return FALSE ;
if( WorldColBrickFull( x1, y0, z0, ptrobj->Ymax ) ) return FALSE ;
if( WorldColBrickFull( x1, y0, z1, ptrobj->Ymax ) ) return FALSE ;
if( WorldColBrickFull( x0, y0, z1, ptrobj->Ymax ) ) return FALSE ;
// test liste des objets
ptrobjt = ListObjet ;
for( n=0; n<NbObjets; n++,ptrobjt++ )
{
if( (n != numobj)
AND (ptrobjt->Body != -1)
AND (!(ptrobj->Flags&INVISIBLE))
AND (ptrobjt->CarryBy != numobj) )
{
xt0 = ptrobjt->PosObjX + ptrobjt->Xmin ;
xt1 = ptrobjt->PosObjX + ptrobjt->Xmax ;
yt0 = ptrobjt->PosObjY + ptrobjt->Ymin ;
yt1 = ptrobjt->PosObjY + ptrobjt->Ymax ;
zt0 = ptrobjt->PosObjZ + ptrobjt->Zmin ;
zt1 = ptrobjt->PosObjZ + ptrobjt->Zmax ;
if( x0 < xt1
AND x1 > xt0
AND y0 < yt1
AND y1 > yt0
AND z0 < zt1
AND z1 > zt0 )
{ // collision pos refusée
return FALSE ;
}
}
}
return TRUE ;
}
/*══════════════════════════════════════════════════════════════════════════*
█▀▀█ █▀▀▀█ █▀▀▀▄ █ ▄▀
██▀▀█ ██ █ ██ █ ██▀
▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
void InitBody( UBYTE gennewbody,
WORD numobj )
{
WORD newbody ;
WORD oldbody ;
T_OBJET *ptrobj ;
WORD *ptr ;
WORD size ;
WORD x0,x1,z0,z1 ;
UBYTE *ptr3do ;
ptrobj = &ListObjet[numobj] ;
if( ptrobj->Flags & SPRITE_3D ) return ;
// grosse rustine anti boom okazou
if( numobj == NUM_PERSO )
{
if( Comportement == C_PROTOPACK )
{
if( (gennewbody != GEN_BODY_NORMAL)
AND (gennewbody != GEN_BODY_TUNIQUE) )
{
SetComportement( C_NORMAL ) ;
}
}
}
// if( gennewbody == ptrobj->GenBody ) return ;
if( gennewbody != NO_BODY )
{
newbody = SearchBody( gennewbody, numobj ) ;
}
else
{
newbody = -1 ;
}
if( newbody != -1 )
{
if( newbody != ptrobj->Body )
{
oldbody = ptrobj->Body ;
ptrobj->Body = newbody ;
ptrobj->GenBody = gennewbody ;
if( M_Xmin == -32000 )
{
ptr = (WORD*)(PtrBody[ptrobj->Body] + 2) ;
x0 = *ptr++ ;
x1 = *ptr++ ;
ptrobj->Ymin = *ptr++ ;
ptrobj->Ymax = *ptr++ ;
z0 = *ptr++ ;
z1 = *ptr++ ;
if( ptrobj->Flags & MINI_ZV )
{
// plus petit
if( x1 - x0 < z1 - z0 )
size = (x1 - x0) / 2 ;
else
size = (z1 - z0) / 2 ;
}
else
{
// moyenne
size = ((x1 - x0) + (z1 - z0)) / 4 ;
}
ptrobj->Xmin = -size ;
ptrobj->Xmax = +size ;
ptrobj->Zmin = -size ;
ptrobj->Zmax = +size ;
}
else
{
ptrobj->Xmin = M_Xmin ;
ptrobj->Xmax = M_Xmax ;
ptrobj->Ymin = M_Ymin ;
ptrobj->Ymax = M_Ymax ;
ptrobj->Zmin = M_Zmin ;
ptrobj->Zmax = M_Zmax ;
}
if( (oldbody != -1) AND (ptrobj->Anim != -1) )
{
CopyInterAnim( PtrBody[oldbody], PtrBody[ptrobj->Body] ) ;
}
}
}
else
{
ptrobj->GenBody = NO_BODY ;
ptrobj->Body = -1 ;
ptrobj->Ymin = 0 ;
ptrobj->Ymax = 0 ;
ptrobj->Xmin = 0 ;
ptrobj->Xmax = 0 ;
ptrobj->Zmin = 0 ;
ptrobj->Zmax = 0 ;
}
}
/*──────────────────────────────────────────────────────────────────────────*/
void InitSprite( WORD newsprite,
WORD numobj )
{
T_OBJET *ptrobj ;
WORD *ptr ;
ptrobj = &ListObjet[numobj] ;
if( !(ptrobj->Flags & SPRITE_3D) ) return ;
if( newsprite != -1 AND newsprite != ptrobj->Body )
{
ptrobj->Body = newsprite ;
ptr = &PtrZvExtra[ newsprite*8 + 2 ] ;
ptrobj->Xmin = *ptr++ ;
ptrobj->Xmax = *ptr++ ;
ptrobj->Ymin = *ptr++ ;
ptrobj->Ymax = *ptr++ ;
ptrobj->Zmin = *ptr++ ;
ptrobj->Zmax = *ptr++ ;
}
}
/*══════════════════════════════════════════════════════════════════════════*
█▀▀▀█ ██▄ █ █ █▄ ▄█ ██▀▀▀
██▀▀█ ██▀██ ██ ██▀ █ ▀▀▀▀█
▀▀ ▀ ▀▀ ▀ ▀▀ ▀▀ ▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
WORD InitAnim( UBYTE gennewanim,
WORD flag,
UBYTE gennextanim,
WORD numobj )
{
WORD newanim, nextanim ;
T_OBJET *ptrobj ;
UBYTE tempstringnext[256] ;
ptrobj = &ListObjet[numobj] ;
/*
if( numobj == 11 )
{
CoulText( 15,0 ) ;
Text( 40,40, "%Fanim %d sur 11", gennewanim ) ;
}
if( numobj == 5 )
{
CoulText( 15,0 ) ;
Text( 40,100, "%Fanim %d sur 5", gennewanim ) ;
if( gennewanim != 0 )
{
Text( 70,100, "%Fexplose" ) ;
}
}
*/
// debug protect
if( ptrobj->Body == -1 )
{
#ifdef DEBUG_TOOLS
Message( "Anim sur un objet avec Body = -1 !", TRUE ) ;
#endif
return FALSE ;
}
if( ptrobj->Flags & SPRITE_3D ) return FALSE ; // -1 ;
if( (gennewanim == ptrobj->GenAnim)
AND (ptrobj->Anim != -1)
// AND (newanim == ptrobj->Anim)
// AND (flag == ptrobj->FlagAnim)
) return TRUE ;
if( gennextanim == NO_ANIM )
{
if( ptrobj->FlagAnim != ANIM_ALL_THEN )
{
gennextanim = ptrobj->GenAnim ;
}
}
newanim = SearchAnim( gennewanim, numobj ) ;
if( newanim == -1 )
{
newanim = SearchAnim( GEN_ANIM_RIEN, numobj ) ;
}
if( flag != ANIM_SET )
{
if( ptrobj->FlagAnim == ANIM_ALL_THEN )
{
ptrobj->NextGenAnim = gennewanim ;
return FALSE ;
}
}
/*if( numobj==2 )
{
CoulText( 15, 0 ) ;
Text( 10,100, "%FInitAnim GenAnim:%d Anim:%d ", gennewanim, newanim ) ;
}*/
// if( (newanim != ptrobj->Anim) OR (flag != ptrobj->FlagAnim) )
{
if( flag == ANIM_INSERT )
{
flag = ANIM_ALL_THEN ;
gennextanim = ptrobj->GenAnim ;
if( (gennextanim == GEN_ANIM_LANCE)
OR (gennextanim == GEN_ANIM_TOMBE)
OR (gennextanim == GEN_ANIM_RECEPTION)
OR (gennextanim == GEN_ANIM_RECEPTION_2) )
gennextanim = GEN_ANIM_RIEN ;
// peut etre gennextanim = ptrobj->GenNextAnim ;
}
if( flag == ANIM_SET )
{
flag = ANIM_ALL_THEN ;
}
/* if( flag == ANIM_REPEAT )
{
gennextanim = ptrobj->GenAnim ;
}
*/
if( ptrobj->Anim == -1 )
{
SetAnimObjet( 0,
HQR_Get( HQR_Anims, newanim ),
PtrBody[ptrobj->Body] ) ;
}
else
{
PtrBufferAnim += StockInterAnim( PtrBufferAnim, PtrBody[ptrobj->Body] ) ;
if( PtrBufferAnim > BufferAnim + 5000 - 512 ) PtrBufferAnim = BufferAnim ;
}
ptrobj->Anim = newanim ;
ptrobj->GenAnim = gennewanim ;
ptrobj->NextGenAnim = gennextanim ;
ptrobj->PtrAnimAction = SearchPtrAnimAction ;
ptrobj->FlagAnim = flag ;
ptrobj->Frame = 0 ;
ptrobj->WorkFlags &= ~(OK_HIT + ANIM_END) ;
ptrobj->WorkFlags |= NEW_FRAME ;
if( ptrobj->PtrAnimAction != 0 )
{
/*
if( numobj == 11 )
{
CoulText( 15,0 ) ;
Text( 40,50, "%Faction sur 11" ) ;
}
if( numobj == 5 )
{
CoulText( 15,0 ) ;
Text( 40,110, "%Faction sur 5" ) ;
}
*/
GereAnimAction( ptrobj, numobj ) ;
}
/*
if( numobj == 5 )
{
CoulText( 15,0 ) ;
Text( 40,120, "%Fapres sur 5" ) ;
}
*/
ptrobj->AnimStepBeta = 0 ;
ptrobj->AnimStepX = 0 ;
ptrobj->AnimStepY = 0 ;
ptrobj->AnimStepZ = 0 ;
}
return TRUE ;
}
/*══════════════════════════════════════════════════════════════════════════*/
/* gestion anim */
void ReajustPos( UBYTE col )
{
WORD xw, yw, zw ;
if( !col ) return ;
xw = XMap * SIZE_BRICK_XZ - DEMI_BRICK_XZ ; /* coin superieur gauche de la brick */
yw = YMap * SIZE_BRICK_Y ;
zw = ZMap * SIZE_BRICK_XZ - DEMI_BRICK_XZ ;
switch( col ) /* collision complexes */
{
case 6:
if( Nxw-xw < Nzw-zw ) col = 3 ;
else col = 2 ;
break ;
case 7:
if( Nxw-xw < Nzw-zw ) col = 5 ;
else col = 4 ;
break ;
case 10:
if( Nxw-xw < Nzw-zw ) col = 2 ;
else col = 3 ;
break ;
case 11:
if( Nxw-xw < Nzw-zw ) col = 4 ;
else col = 5 ;
break ;
case 8:
if( SIZE_BRICK_XZ-(Nxw-xw) > Nzw-zw ) col = 4 ;
else col = 2 ;
break ;
case 9:
if( SIZE_BRICK_XZ-(Nxw-xw) > Nzw-zw ) col = 5 ;
else col = 3 ;
break ;
case 12:
if( SIZE_BRICK_XZ-(Nxw-xw) > Nzw-zw ) col = 2 ;
else col = 4 ;
break ;
case 13:
if( SIZE_BRICK_XZ-(Nxw-xw) > Nzw-zw ) col = 3 ;
else col = 5 ;
break ;
}
switch( col ) /* collision de base */
{
case 2:
Nyw = yw + BoundRegleTrois( 0, SIZE_BRICK_Y, SIZE_BRICK_XZ, Nxw - xw ) ;
break ;
case 3:
Nyw = yw + BoundRegleTrois( 0, SIZE_BRICK_Y, SIZE_BRICK_XZ, Nzw - zw ) ;
break ;
case 4:
Nyw = yw + BoundRegleTrois( SIZE_BRICK_Y, 0, SIZE_BRICK_XZ, Nzw - zw ) ;
break ;
case 5:
Nyw = yw + BoundRegleTrois( SIZE_BRICK_Y, 0, SIZE_BRICK_XZ, Nxw - xw ) ;
break ;
}
}
/*──────────────────────────────────────────────────────────────────────────*/
void ReceptionObj()
{
if( AnimNumObj == NUM_PERSO )
{
if( StartYFalling - Nyw >= 16 * SIZE_BRICK_Y )
{ // trop haut mort directe
InitSpecial( APtObj->PosObjX,
APtObj->PosObjY+1000,
APtObj->PosObjZ,
0 ) ;
APtObj->LifePoint = 0 ;
InitAnim( GEN_ANIM_RECEPTION_2, ANIM_ALL_THEN, GEN_ANIM_RIEN, AnimNumObj ) ;
}
else
if( StartYFalling - Nyw >= 8 * SIZE_BRICK_Y )
{ // se fait mal
InitSpecial( APtObj->PosObjX,
APtObj->PosObjY+1000,
APtObj->PosObjZ,
0 ) ;
APtObj->LifePoint -- ;
InitAnim( GEN_ANIM_RECEPTION_2, ANIM_ALL_THEN, GEN_ANIM_RIEN, AnimNumObj ) ;
}
else
if( StartYFalling - Nyw > 1 )
{ // reception normale
InitAnim( GEN_ANIM_RECEPTION, ANIM_ALL_THEN, GEN_ANIM_RIEN, AnimNumObj ) ;
}
else
{
InitAnim( GEN_ANIM_RIEN, ANIM_REPEAT, 0, AnimNumObj ) ;
}
StartYFalling = 0 ;
}
else
{
InitAnim( GEN_ANIM_RECEPTION, ANIM_ALL_THEN, APtObj->NextGenAnim, AnimNumObj ) ;
}
// APtObj->Falling = FALSE ;
APtObj->WorkFlags &= ~FALLING ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void DoCornerReajust( WORD nx, WORD ny, WORD nz, WORD coin )
{
UBYTE col, orgcol ;
orgcol = WorldColBrick( Nxw, Nyw, Nzw ) ;
Nxw += nx ;
Nyw += ny ;
Nzw += nz ;
if( Nxw < 0 ) goto fincorner ;
if( Nzw < 0 ) goto fincorner ;
if( Nxw > 63*SIZE_BRICK_XZ ) goto fincorner ;
if( Nzw > 63*SIZE_BRICK_XZ ) goto fincorner ;
ReajustPos( orgcol ) ;
if( (col = WorldColBrick( Nxw, Nyw, Nzw )) != 0 )
{
if( col == 1 )
{
Col1 |= coin ;
if( WorldColBrick( Nxw, Nyw, OldZ+nz ) == 1 )
{
if( WorldColBrick( OldX+nx, Nyw, Nzw ) != 1 )
{
SaveNxw = OldX ;
}
}
else
{
SaveNzw = OldZ ;
}
}
}
fincorner:
Nxw = SaveNxw ;
Nyw = SaveNyw ;
Nzw = SaveNzw ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void DoCornerReajustTwinkel( WORD nx, WORD ny, WORD nz, WORD coin )
{
UBYTE col, orgcol ;
orgcol = WorldColBrick( Nxw, Nyw, Nzw ) ;
Nxw += nx ;
Nyw += ny ;
Nzw += nz ;
if( Nxw < 0 ) goto fincorner ;
if( Nzw < 0 ) goto fincorner ;
if( Nxw > 63*SIZE_BRICK_XZ ) goto fincorner ;
if( Nzw > 63*SIZE_BRICK_XZ ) goto fincorner ;
ReajustPos( orgcol ) ;
if( (col = WorldColBrickFull( Nxw, Nyw, Nzw, APtObj->Ymax )) != 0 )
{
if( col == 1 )
{
Col1 |= coin ;
if( WorldColBrickFull( Nxw, Nyw, OldZ+nz, APtObj->Ymax ) == 1 )
{
if( WorldColBrickFull( OldX+nx, Nyw, Nzw, APtObj->Ymax ) != 1 )
{
SaveNxw = OldX ;
}
}
else
{
SaveNzw = OldZ ;
}
}
}
fincorner:
Nxw = SaveNxw ;
Nyw = SaveNyw ;
Nzw = SaveNzw ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void DoAnim( WORD numobj )
{
LONG flag ;
T_OBJET *ptrobj ;
WORD numanim ;
UBYTE *ptranim ;
UBYTE *ptrbody ;
WORD xw, yw, zw ;
UBYTE col, orgcol ;
LONG angle ;
WORD nb, n, nu ;
APtObj = ptrobj = &ListObjet[(AnimNumObj = numobj)] ;
if( APtObj->Body == -1 ) return ;
OldX = APtObj->OldPosX ;
OldY = APtObj->OldPosY ;
OldZ = APtObj->OldPosZ ;
/*──────────────────────────────────────────────────────────────────────────*/
/* gestion DEP OBJET SPRITE */
if( APtObj->Flags & SPRITE_3D )
{
if( APtObj->HitForce != 0 )
APtObj->WorkFlags |= OK_HIT ;
/* gestion anim pour sprite */
Nxw = APtObj->PosObjX ;
Nyw = APtObj->PosObjY ;
Nzw = APtObj->PosObjZ ;
if( !(APtObj->WorkFlags & FALLING) )
{
if( APtObj->SRot != 0 ) /* vitesse deplacement */
{
n = GetRealValue( &APtObj->RealAngle ) ;
if( !n ) /* tanpis machine trop speed */
{
if( APtObj->RealAngle.EndValue > 0 )
n = 1 ;
else
n = -1 ;
}
Rotate( n,0, APtObj->FlagAnim ) ; /* alpha */
Nyw = APtObj->PosObjY - Y0 ;
Rotate( 0, X0, APtObj->Beta ) ;
Nxw = APtObj->PosObjX + X0 ;
Nzw = APtObj->PosObjZ + Y0 ;
InitRealValue( 0, APtObj->SRot,
50, &APtObj->RealAngle ) ;
if( APtObj->WorkFlags & AUTO_STOP_DOOR )
{
// c'est obligatoirement un sprite_clip
if( APtObj->DoorWidth )
{
// distance ouverture max
if( Distance2D( Nxw,
Nzw,
APtObj->AnimStepX,
APtObj->AnimStepZ )
>= APtObj->DoorWidth )
{
// recalage violent
switch( APtObj->Beta )
{
case 768: // left
Nxw = APtObj->AnimStepX - APtObj->DoorWidth ;
break ;
case 256: // right
Nxw = APtObj->AnimStepX + APtObj->DoorWidth ;
break ;
case 512: // up
Nzw = APtObj->AnimStepZ - APtObj->DoorWidth ;
break ;
case 0: // down
Nzw = APtObj->AnimStepZ + APtObj->DoorWidth ;
break ;
}
APtObj->WorkFlags &= ~AUTO_STOP_DOOR ;
APtObj->SRot = 0 ;
}
}
else
{ // je me ferme
flag = FALSE ;
switch( APtObj->Beta )
{
case 768: // left
if( Nxw >= APtObj->AnimStepX ) flag = TRUE ;
break ;
case 256: // right
if( Nxw <= APtObj->AnimStepX ) flag = TRUE ;
break ;
case 512: // up
if( Nzw >= APtObj->AnimStepZ ) flag = TRUE ;
break ;
case 0: // down
if( Nzw <= APtObj->AnimStepZ ) flag = TRUE ;
break ;
}
/* if( Distance2D( Nxw,
Nzw,
APtObj->AnimStepX,
APtObj->AnimStepZ )
< 100 )
// attention si porte decalée
*/ if( flag )
{
// position d'origine
Nxw = APtObj->AnimStepX ;
Nyw = APtObj->AnimStepY ;
Nzw = APtObj->AnimStepZ ;
APtObj->WorkFlags &= ~AUTO_STOP_DOOR ;
APtObj->SRot = 0 ;
}
}
} // auto stop door
}
if( APtObj->Flags & PUSHABLE )
{
Nxw += APtObj->AnimStepX ;
Nyw += APtObj->AnimStepY ;
Nzw += APtObj->AnimStepZ ;
if( APtObj->Flags & MINI_ZV ) // boxxle
{
Nxw = (Nxw / (SIZE_BRICK_XZ/4)) * (SIZE_BRICK_XZ/4) ;
Nzw = (Nzw / (SIZE_BRICK_XZ/4)) * (SIZE_BRICK_XZ/4) ;
}
APtObj->AnimStepX = 0 ;
APtObj->AnimStepY = 0 ;
APtObj->AnimStepZ = 0 ;
}
}
/* if( Nxw == OldX
AND Nyw == OldY
AND Nzw == OldZ ) return ; // did not move
*/
}
/*──────────────────────────────────────────────────────────────────────────*/
/* gestion anim/DEP OBJET 3D */
else /* pas SPRITE_3D donc obj articulés */
if( APtObj->Anim != -1 )
{
numanim = APtObj->Anim ;
ptranim = HQR_Get( HQR_Anims, numanim ) ;
ptrbody = PtrBody[APtObj->Body] ;
flag = SetInterDepObjet( APtObj->Frame, ptranim, ptrbody ) ;
if( AnimMasterRot )
APtObj->WorkFlags |= ANIM_MASTER_ROT ;
else
APtObj->WorkFlags &= ~ANIM_MASTER_ROT ;
APtObj->Beta = (APtObj->Beta + AnimStepBeta - APtObj->AnimStepBeta) & 1023 ;
APtObj->AnimStepBeta = AnimStepBeta ;
Rotate( AnimStepX, AnimStepZ, APtObj->Beta ) ;
AnimStepX = X0 ;
AnimStepZ = Y0 ;
Nxw = APtObj->PosObjX + AnimStepX - APtObj->AnimStepX ;
Nyw = APtObj->PosObjY + AnimStepY - APtObj->AnimStepY ;
Nzw = APtObj->PosObjZ + AnimStepZ - APtObj->AnimStepZ ;
APtObj->AnimStepX = AnimStepX ;
APtObj->AnimStepY = AnimStepY ;
APtObj->AnimStepZ = AnimStepZ ;
APtObj->WorkFlags &= ~(ANIM_END+NEW_FRAME) ;
if( flag )
{
/*-----------------------------------------------------------------*/
/* si nouvelle frame */
APtObj->Frame++ ;
APtObj->WorkFlags |= NEW_FRAME ;
/*-----------------------------------------------------------------*/
/* gestion des actions déclenchées par des anims/frames */
if( APtObj->PtrAnimAction != 0 )
{
GereAnimAction( APtObj, numobj ) ;
}
/*-----------------------------------------------------------------*/
/* frame suivante test fin anim */
if( APtObj->Frame == GetNbFramesAnim( ptranim ) )
{
APtObj->WorkFlags &= ~OK_HIT ;
if( APtObj->FlagAnim == ANIM_REPEAT )
{
APtObj->Frame = GetBouclageAnim( ptranim ) ;
}
else /* ANIM[_ALL]_THEN */
{
APtObj->GenAnim = APtObj->NextGenAnim ;
APtObj->Anim = SearchAnim( APtObj->GenAnim, numobj ) ;
if( APtObj->Anim == -1 )
{
APtObj->Anim = SearchAnim( GEN_ANIM_RIEN, numobj ) ;
APtObj->GenAnim = GEN_ANIM_RIEN ;
}
APtObj->PtrAnimAction = SearchPtrAnimAction ;
APtObj->FlagAnim = ANIM_REPEAT ;
APtObj->Frame = 0 ;
APtObj->HitForce = 0 ;
}
if( APtObj->PtrAnimAction != 0 )
{
GereAnimAction( APtObj, numobj ) ;
}
APtObj->WorkFlags |= ANIM_END ;
}
APtObj->AnimStepBeta = 0 ;
APtObj->AnimStepX = 0 ;
APtObj->AnimStepY = 0 ;
APtObj->AnimStepZ = 0 ;
/*-----------------------------------------------------------------*/
}/* new frame */
}/* if anim != -1 */
/*──────────────────────────────────────────────────────────────────────────*/
// pour tous obj/sprite 3d
// je suis porte par un CARRIER / par quelqu'un ?
if( (nu = APtObj->CarryBy) != -1 )
{
Nxw -= ListObjet[nu].OldPosX ;
Nyw -= ListObjet[nu].OldPosY ;
Nzw -= ListObjet[nu].OldPosZ ;
Nxw += ListObjet[nu].PosObjX ;
Nyw += ListObjet[nu].PosObjY ;
Nzw += ListObjet[nu].PosObjZ ;
if( !CheckZvOnZv( numobj, nu ) )
{
APtObj->CarryBy = -1 ;
}
}
/*──────────────────────────────────────────────────────────────────────────*/
// je tombe
if( APtObj->WorkFlags & FALLING )
{
/* gestion chute avec proportion sur y */
Nxw = OldX ;
Nyw = OldY + StepFalling ;
Nzw = OldZ ;
}
/*──────────────────────────────────────────────────────────────────────────*/
/* test/reajuste pos */
// ? APtObj->ObjCol = -1 ;
if( APtObj->Flags & CHECK_BRICK_COL )
{
YMap = 0 ;
/* reajuste le nyw (nouvelle pos) par rapport à la col en cours */
if( (col = WorldColBrick( OldX, OldY, OldZ )) != 0 )
{
if( col == 1 )
{
Message( "currentpos dans col 1 ?", FALSE ) ;
Nyw = (Nyw/SIZE_BRICK_Y)*SIZE_BRICK_Y+SIZE_BRICK_Y ;
APtObj->PosObjY = Nyw ; // essai rejette perso
}
else
{
ReajustPos( col ) ;
}
}
if( APtObj->Flags & CHECK_OBJ_COL )
{
CheckObjCol( numobj ) ;
}
if( APtObj->CarryBy != -1 )
{
if( APtObj->WorkFlags & FALLING )
{
ReceptionObj() ;
}
}
// ■■■■■■■■■ 4 coins test la col de la nouvelle pos + size zv
// if( !(APtObj->Flags & SPRITE_3D) )
{
SaveNxw = Nxw ;
SaveNyw = Nyw ;
SaveNzw = Nzw ;
Col1 = 0 ;
if( (numobj == NUM_PERSO) AND ((ptrobj->Flags&COL_BASSE) == 0) )
{
DoCornerReajustTwinkel( APtObj->Xmin, APtObj->Ymin, APtObj->Zmin, 1 ) ;
DoCornerReajustTwinkel( APtObj->Xmax, APtObj->Ymin, APtObj->Zmin, 2 ) ;
DoCornerReajustTwinkel( APtObj->Xmax, APtObj->Ymin, APtObj->Zmax, 4 ) ;
DoCornerReajustTwinkel( APtObj->Xmin, APtObj->Ymin, APtObj->Zmax, 8 ) ;
}
else
{
DoCornerReajust( APtObj->Xmin, APtObj->Ymin, APtObj->Zmin, 1 ) ;
DoCornerReajust( APtObj->Xmax, APtObj->Ymin, APtObj->Zmin, 2 ) ;
DoCornerReajust( APtObj->Xmax, APtObj->Ymin, APtObj->Zmax, 4 ) ;
DoCornerReajust( APtObj->Xmin, APtObj->Ymin, APtObj->Zmax, 8 ) ;
}
// choc si on court
if( (Col1 != 0)
AND !(APtObj->WorkFlags & FALLING)
AND (AnimNumObj == NUM_PERSO)
AND (Comportement == C_SPORTIF)
AND (APtObj->GenAnim == GEN_ANIM_MARCHE) )
{
Rotate( APtObj->Xmin, APtObj->Zmin, APtObj->Beta + 896 + 512 ) ;
X0 += Nxw ;
Y0 += Nzw ;
if( (X0 >= 0) AND (Y0 >= 0) AND (X0 <= 63*SIZE_BRICK_XZ) AND (Y0 <= 63*SIZE_BRICK_XZ)
AND (WorldColBrick( X0, Nyw+256, Y0 ) != 0) )
{
InitSpecial( APtObj->PosObjX,
APtObj->PosObjY+1000,
APtObj->PosObjZ,
0 ) ;
InitAnim( GEN_ANIM_CHOC, ANIM_ALL_THEN, GEN_ANIM_RIEN, AnimNumObj ) ;
if( AnimNumObj == NUM_PERSO ) LastJoyFlag = TRUE ;
APtObj->LifePoint -= 1 ;
}
}
}
// ■■■■■■■■■ test la col de la nouvelle pos reelle
/* if( (AnimNumObj == NUM_PERSO) AND ((ptrobj->Flags&COL_BASSE) == 0) )
{
col = WorldColBrickFull( Nxw, Nyw, Nzw, APtObj->Ymax ) ;
}
else
{
*/
col = WorldColBrick( Nxw, Nyw, Nzw ) ;
// }
APtObj->Col = col ;
// if( (APtObj->Col = col = WorldColBrick( Nxw, Nyw, Nzw )) != 0 )
if( col != 0 )
{
if( col == 1 )
{
if( APtObj->WorkFlags & FALLING )
{
ReceptionObj() ;
Nyw = YMap*SIZE_BRICK_Y+SIZE_BRICK_Y ;
}
else
{
if( numobj == NUM_PERSO )
{
if( (Comportement == C_SPORTIF)
AND (APtObj->GenAnim == GEN_ANIM_MARCHE) )
{
InitSpecial( APtObj->PosObjX,
APtObj->PosObjY+1000,
APtObj->PosObjZ,
0 ) ;
InitAnim( GEN_ANIM_CHOC, ANIM_ALL_THEN, GEN_ANIM_RIEN, AnimNumObj ) ;
if( numobj == NUM_PERSO ) LastJoyFlag = TRUE ;
APtObj->LifePoint -= 1 ;
}
}
/* if( (AnimNumObj == NUM_PERSO) AND ((ptrobj->Flags&COL_BASSE) == 0) )
{
// fait glisser twinsen
//■■■■■■■■■ // regarde de dep X puis Z par rapport à old pos
if( WorldColBrickFull( Nxw, Nyw, OldZ, APtObj->Ymax ) != 0 )
{
if( WorldColBrickFull( OldX, Nyw, Nzw, APtObj->Ymax ) != 0 )
{
return ; // pos pas acceptee
}
else
{
Nxw = OldX ;
}
}
else
{
Nzw = OldZ ;
}
}
else
{
*/
// fait glisser
//■■■■■■■■■ // regarde de dep X puis Z par rapport à old pos
if( WorldColBrick( Nxw, Nyw, OldZ ) != 0 )
{
if( WorldColBrick( OldX, Nyw, Nzw ) != 0 )
{
return ; /* pos pas acceptee */
}
else
{
Nxw = OldX ;
}
}
else
{
Nzw = OldZ ;
}
// }
}
}
else
{
// if( APtObj->Falling )
if( APtObj->WorkFlags & FALLING )
{
ReceptionObj() ;
}
ReajustPos( col ) ;
}
// APtObj->Falling = FALSE ;
APtObj->WorkFlags &= ~FALLING ;
}
else /* col == 0 */
{
/* si sous les pieds != cube plein: susceptible de tomber ou reajuste y */
if( (APtObj->Flags & OBJ_FALLABLE) AND (APtObj->CarryBy == -1) )
{
col = WorldColBrick( Nxw, Nyw-1, Nzw ) ;
if( col )
{
if( APtObj->WorkFlags & FALLING )
{
ReceptionObj() ;
}
ReajustPos( col ) ;
}
else
{
if( !(APtObj->WorkFlags & ANIM_MASTER_ROT) )
{
APtObj->WorkFlags |= FALLING ;
if( numobj == NUM_PERSO AND !StartYFalling )
StartYFalling = Nyw ;
InitAnim( GEN_ANIM_TOMBE, ANIM_REPEAT, NO_ANIM , numobj ) ;
}
}
}
}
if( YMap == -1 ) APtObj->LifePoint = 0 ; // bye bye
}
else /* ! Flags & CHECK_BRICK_COL */
{
if( APtObj->Flags & CHECK_OBJ_COL )
{
CheckObjCol( numobj ) ;
}
}
if( Col1 ) APtObj->Col |= 128 ;
/* protege sortie du cube */
if( Nxw < 0 ) Nxw = 0 ;
if( Nzw < 0 ) Nzw = 0 ;
if( Nyw < 0 ) Nyw = 0 ;
if( Nxw > 63*SIZE_BRICK_XZ ) Nxw = 63*SIZE_BRICK_XZ ;
if( Nzw > 63*SIZE_BRICK_XZ ) Nzw = 63*SIZE_BRICK_XZ ;
/* ok enregistre position */
APtObj->PosObjX = Nxw ;
APtObj->PosObjY = Nyw ;
APtObj->PosObjZ = Nzw ;
}
/*══════════════════════════════════════════════════════════════════════════*
█▄ ▄█ █▀▀▀█ █ █ █▀▀▀▀
██▀ █ ██ █ ██ ▄▀ ██▀▀
▀▀ ▀ ▀▀▀▀▀ ▀▀▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
void ManualRealAngle( T_OBJET *ptrobj )
{
WORD angle = 0 ;
if( MyJoy & J_LEFT ) angle = +256 ;
if( MyJoy & J_RIGHT ) angle = -256 ;
InitRealAngleConst( ptrobj->Beta,
ptrobj->Beta + angle,
ptrobj->SRot,
&ptrobj->RealAngle ) ;
}
/*──────────────────────────────────────────────────────────────────────────*/
void ClearRealAngle( T_OBJET *ptrobj )
{
InitRealAngle( ptrobj->Beta,
ptrobj->Beta,
0,
&ptrobj->RealAngle ) ;
}
/*══════════════════════════════════════════════════════════════════════════*/
/*══════════════════════════════════════════════════════════════════════════*/
/* T_OBJET. Info Info1 Info2 Info3
FOLLOW num obj
FOLLOW_2 etat label1/label2 distance num obj
NumTrack OffsetTrack
TRACK
TRACK_ATTACK
*/
/*══════════════════════════════════════════════════════════════════════════*/
void DoDir( WORD numobj )
{
LONG f ;
T_OBJET *ptrobj ;
UBYTE *ptr ;
WORD info,info1,info2,info3 ;
WORD flag, angle ;
UBYTE macro ;
UBYTE string[256] ;
ptrobj = &ListObjet[numobj] ;
if( ptrobj->Body == -1 ) return ;
/*-------------------------------------------------------------------------*/
if( ptrobj->WorkFlags & FALLING )
{
if( ptrobj->Move == MOVE_MANUAL )
{
ManualRealAngle( ptrobj ) ;
LastMyJoy = MyJoy ;
}
return ;
}
// if( !(ptrobj->WorkFlags & ANIM_MASTER_ROT) )
{
if( !(ptrobj->Flags & SPRITE_3D)
AND ptrobj->Move != MOVE_MANUAL )
{
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
}
}
/* else
{
ClearRealAngle( ptrobj ) ;
}
*/
switch( ptrobj->Move )
{
/*-------------------------------------------------------------------------*/
case MOVE_MANUAL:
if( numobj == NUM_PERSO ) /* protection anim speciales */
{
ActionNormal = FALSE ;
/*
if( MyKey == K_F1 ) SetComportement( C_NORMAL ) ;
if( MyKey == K_F2 ) SetComportement( C_SPORTIF ) ;
if( MyKey == K_F3 ) SetComportement( C_AGRESSIF ) ;
if( MyKey == K_F4 ) SetComportement( C_DISCRET ) ;
*/
switch( Comportement )
{
case C_NORMAL:
if( MyFire & F_SPACE )
{
ActionNormal = TRUE ;
}
break ;
case C_SPORTIF:
if( MyFire & F_SPACE )
{
InitAnim( GEN_ANIM_SAUTE, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
}
break ;
case C_AGRESSIF:
if( MyFire & F_SPACE )
{
if( CombatAuto )
{
LastJoyFlag = TRUE ;
/* essai control direction pendant combat */
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
if( (LastFire & F_SPACE)
AND( ptrobj->GenAnim != GEN_ANIM_RIEN ) )
break ;
switch( Rnd(3) )
{
case 0:
InitAnim( GEN_ANIM_COUP_1, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
break ;
case 1:
InitAnim( GEN_ANIM_COUP_2, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
break ;
case 2:
InitAnim( GEN_ANIM_COUP_3, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
break ;
}
}
else
{
if( MyJoy & J_RIGHT )
InitAnim( GEN_ANIM_COUP_2, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
if( MyJoy & J_LEFT )
InitAnim( GEN_ANIM_COUP_3, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
if( MyJoy & J_UP )
InitAnim( GEN_ANIM_COUP_1, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
}
}
break ;
case C_DISCRET:
if( MyFire & F_SPACE )
{
InitAnim( GEN_ANIM_CACHE, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
break ;
}
/* lance balle magique */
if( (MyFire & F_ALT)
AND (ListFlagGame[FLAG_CONSIGNE] == 0) )
{
if( Weapon == 0 ) // balle magique
{
if( ListFlagGame[FLAG_BALLE_MAGIQUE] == 1 )
{
if( MagicBall == -1 )
{
InitAnim( GEN_ANIM_LANCE, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
}
LastJoyFlag = TRUE ;
/* control direction pendant visée */
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
}
}
else // sabre magique
{
if( ListFlagGame[FLAG_SABRE_MAGIQUE] == 1 )
{
if( ptrobj->GenBody != GEN_BODY_SABRE )
{
InitBody( GEN_BODY_SABRE, NUM_PERSO ) ;
}
// anim frappe rapide
InitAnim( GEN_ANIM_SABRE, ANIM_THEN, GEN_ANIM_RIEN, numobj ) ;
LastJoyFlag = TRUE ;
/* control direction pendant visée */
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
}
}
}
} /* endif numperso */
if( !MyFire OR ActionNormal )
{
if( MyJoy & J_UP+J_DOWN ) LastJoyFlag = FALSE ;
if( ((MyJoy != LastMyJoy) OR (MyFire != LastMyFire) )
AND LastJoyFlag )
{
InitAnim( GEN_ANIM_RIEN, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
LastJoyFlag = FALSE ;
if( MyJoy & J_UP )
{
if( !FlagClimbing )
{
InitAnim( GEN_ANIM_MARCHE, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
LastJoyFlag = TRUE ;
}
if( MyJoy & J_DOWN )
{
InitAnim( GEN_ANIM_RECULE, ANIM_REPEAT, NO_ANIM, numobj ) ;
LastJoyFlag = TRUE ;
}
if( MyJoy & J_LEFT )
{
LastJoyFlag = TRUE ;
// if( ptrobj->Anim == AnimRien )
if( ptrobj->GenAnim == GEN_ANIM_RIEN )
{
InitAnim( GEN_ANIM_GAUCHE, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
else
{
if( !(ptrobj->WorkFlags & ANIM_MASTER_ROT) )
{
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
}
}
}
if( MyJoy & J_RIGHT )
{
LastJoyFlag = TRUE ;
// if( ptrobj->Anim == AnimRien )
if( ptrobj->GenAnim == GEN_ANIM_RIEN )
{
InitAnim( GEN_ANIM_DROITE, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
else
{
if( !(ptrobj->WorkFlags & ANIM_MASTER_ROT) )
{
ptrobj->Beta = GetRealAngle( &ptrobj->RealAngle ) ;
}
}
}
}
ManualRealAngle( ptrobj ) ;
LastMyJoy = MyJoy ;
LastMyFire = MyFire ;
break ;
/*-------------------------------------------------------------------------*/
case MOVE_FOLLOW:
// if( !(ptrobj->WorkFlags & ANIM_MASTER_ROT) )
{
info3 = ptrobj->Info3 ; /* num obj to follow */
angle = GetAngle( ptrobj->PosObjX,
ptrobj->PosObjZ,
ListObjet[info3].PosObjX,
ListObjet[info3].PosObjZ ) ;
if( ptrobj->Flags & SPRITE_3D )
{
ptrobj->Beta = angle ;
}
else
{
InitRealAngleConst( ptrobj->Beta,
angle,
ptrobj->SRot,
&ptrobj->RealAngle ) ;
}
}
break ;
/*-------------------------------------------------------------------------*/
case MOVE_RANDOM:
if( !(ptrobj->WorkFlags & ANIM_MASTER_ROT) )
{
if( ptrobj->Col & 128 )
{
angle = (ptrobj->Beta + (rand()&511) - 256 + 512) & 1023 ;
InitRealAngleConst( ptrobj->Beta,
angle,
ptrobj->SRot,
&ptrobj->RealAngle ) ;
*(ULONG*)(&ptrobj->Info) = TimerRef + Rnd( 300 ) + 300 ;
InitAnim( GEN_ANIM_RIEN, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
if( !ptrobj->RealAngle.TimeValue )
{
InitAnim( GEN_ANIM_MARCHE, ANIM_REPEAT, NO_ANIM, numobj ) ;
if( TimerRef > *(ULONG*)(&ptrobj->Info) )
{
angle = (ptrobj->Beta + (rand()&511) - 256) & 1023 ;
InitRealAngleConst( ptrobj->Beta,
angle,
ptrobj->SRot,
&ptrobj->RealAngle ) ;
*(ULONG*)(&ptrobj->Info) = TimerRef + Rnd( 300 ) + 300 ;
}
}
}
break ;
/*-------------------------------------------------------------------------*/
/* case MOVE_FOLLOW_2:
break ;
case MOVE_TRACK_ATTACK:
break ;
*/
/*-------------------------------------------------------------------------*/
case MOVE_TRACK:
if( ptrobj->OffsetTrack == -1 ) ptrobj->OffsetTrack = 0 ;
break ;
/*-------------------------------------------------------------------------*/
case MOVE_SAME_XZ:
info3 = ptrobj->Info3 ; /* num obj to follow */
ptrobj->PosObjX = ListObjet[info3].PosObjX ;
ptrobj->PosObjZ = ListObjet[info3].PosObjZ ;
break ;
}
/*──────────────────────────────────────────────────────────────────────────*/
}
/*══════════════════════════════════════════════════════════════════════════*
█▀▀▀▄ █ ██▀▀▀ █▀▀▀█ █ █▀▀▀█ █ ▄▀
██ █ ██ ▀▀▀▀█ ██▀▀▀ ██ ██▀▀█ ██▀
▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀
*══════════════════════════════════════════════════════════════════════════*/
#ifdef DEBUG_TOOLS
LONG DrawCube( WORD xw0, WORD yw0, WORD zw0,
WORD xw1, WORD yw1, WORD zw1 )
{
LONG x0,y0,x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,x7,y7 ;
WORD coul = 11 ;
WORD coul1 = 13 ;
ClearScreenMinMax() ;
ProjettePoint( xw0,yw0,zw0 ) ;
AdjustScreenMax() ;
x0 = Xp ;
y0 = Yp ;
ProjettePoint( xw1,yw0,zw0 ) ;
AdjustScreenMax() ;
x1 = Xp ;
y1 = Yp ;
ProjettePoint( xw1,yw0,zw1 ) ;
AdjustScreenMax() ;
x2 = Xp ;
y2 = Yp ;
ProjettePoint( xw0,yw0,zw1 ) ;
AdjustScreenMax() ;
x3 = Xp ;
y3 = Yp ;
ProjettePoint( xw0,yw1,zw0 ) ;
AdjustScreenMax() ;
x4 = Xp ;
y4 = Yp ;
ProjettePoint( xw1,yw1,zw0 ) ;
AdjustScreenMax() ;
x5 = Xp ;
y5 = Yp ;
ProjettePoint( xw1,yw1,zw1 ) ;
AdjustScreenMax() ;
x6 = Xp ;
y6 = Yp ;
ProjettePoint( xw0,yw1,zw1 ) ;
AdjustScreenMax() ;
x7 = Xp ;
y7 = Yp ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
Line( x0,y0, x1,y1, coul ) ;
Line( x1,y1, x2,y2, coul ) ;
Line( x2,y2, x3,y3, coul ) ;
Line( x3,y3, x0,y0, coul ) ;
Line( x0,y0, x4,y4, coul1 ) ;
Line( x1,y1, x5,y5, coul1 ) ;
Line( x2,y2, x6,y6, coul1 ) ;
Line( x3,y3, x7,y7, coul1 ) ;
Line( x4,y4, x5,y5, coul1 ) ;
Line( x5,y5, x6,y6, coul1 ) ;
Line( x6,y6, x7,y7, coul1 ) ;
Line( x7,y7, x4,y4, coul1 ) ;
return 1 ;
}
return 0 ;
}
void DrawZV( T_OBJET *ptr )
{
if( DrawCube( ptr->Xmin - WorldXCube,
ptr->Ymin - WorldYCube,
ptr->Zmin - WorldZCube,
ptr->Xmax - WorldXCube,
ptr->Ymax - WorldYCube,
ptr->Zmax - WorldZCube ) )
{
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
UnSetClip() ;
}
#endif
/*──────────────────────────────────────────────────────────────────────────*/
void AffScene( LONG flagflip )
{
LONG n, c, cmpt ;
LONG xmin, ymin, xmax, ymax, dx, dy ;
T_OBJET *ptrobj ;
T_EXTRA *ptrextra ;
T_TRACK *ptrtrack ;
T_ZONE *ptrz ;
T_INCRUST_DISP *ptrdisp ;
T_SORT *ptrtri ;
WORD *ptr ;
LONG nbobjets ;
LONG err ;
WORD numobj, typeobj ;
WORD x,y,z, x0,y0, xw, yw, zw, xm, ym, zm ;
WORD num ;
WORD ztri ;
WORD oldxporg ;
WORD oldyporg ;
UBYTE string[40] ;
UBYTE *ptranim, *ptrbody ;
WORD txmin, tymin, tzmin, txmax, tymax, tzmax ;
WORD pxmin, pymin, pzmin, pxmax, pymax, pzmax ;
WORD twinsenpos, twinsenz ;
LONG shadowtwinsen, i ;
/*------------------------------------------------------------------------*/
// xw = StartXCube*SIZE_BRICK_XZ ;
// yw = StartYCube*SIZE_BRICK_Y ;
// zw = StartZCube*SIZE_BRICK_XZ ;
oldxporg = XpOrgw ;
oldyporg = YpOrgw ;
/*------------------------------------------------------------------------*/
/* cls */
UnSetClip() ;
if( !flagflip )
{
ClsBoxes() ; /* nettoie Log */
}
else
{
SaveTimer() ;
Cls() ;
AffGrille() ;
ChangeIncrustPos( oldxporg,oldyporg, XpOrgw, YpOrgw ) ;
HQ_ChangeBalanceSamples( oldxporg, oldyporg ) ;
CopyScreen( Log, Screen ) ;
}
/*------------------------------------------------------------------------*/
/* objets scenarique 3D ou sprite */
nbobjets = 0 ;
ptrobj = ListObjet ;
for( n=0; n<NbObjets; n++, ptrobj++ )
{
ptrobj->WorkFlags &= ~WAS_DRAWN ;
// si zone grm en cours n'affiche pas les objets au dessus !
if( ZoneGrm != -1 )
{
ptrz = &ListZone[IndexGrm] ;
if( ptrobj->PosObjY > ListZone[IndexGrm].Y1 )
{
continue ;
}
}
if( (ptrobj->Flags & OBJ_BACKGROUND)
AND (flagflip == FALSE) )
{
// rustine: renseigne qd meme moteur presence sprite
// pour obj_back si dans l'écran
ProjettePoint( ptrobj->PosObjX-WorldXCube,
ptrobj->PosObjY-WorldYCube,
ptrobj->PosObjZ-WorldZCube ) ;
if( (Xp>VIEW_X0) AND (Xp<VIEW_X1) AND (Yp>VIEW_Y0) AND (Yp<VIEW_Y1) )
{
ptrobj->WorkFlags |= WAS_DRAWN ;
}
continue ;
}
if( (ptrobj->Body != -1)
AND (!(ptrobj->Flags&INVISIBLE)) )
{
/* preclip */
ProjettePoint( ptrobj->PosObjX-WorldXCube,
ptrobj->PosObjY-WorldYCube,
ptrobj->PosObjZ-WorldZCube ) ;
// agrandie la zone de visualisation que pour les portes (sprite_clip)
if( ( (ptrobj->Flags&SPRITE_CLIP)
AND (Xp>-112) AND (Xp<(640+112)) AND (Yp>-50) AND (Yp<(480+171)))
OR ( (!(ptrobj->Flags&SPRITE_CLIP))
AND (Xp>VIEW_X0) AND (Xp<VIEW_X1) AND (Yp>VIEW_Y0) AND (Yp<VIEW_Y1)) )
// if( (Xp>VIEW_X0) AND (Xp<VIEW_X1) AND (Yp>VIEW_Y0) AND (Yp<VIEW_Y1) )
{
ztri = ptrobj->PosObjX - WorldXCube
+ ptrobj->PosObjZ - WorldZCube ;
/* magouille pour etre sur qu'un carrier est
dessous l'eventuel objet porté */
// arg ! moche si 2 obj sur carrier
if( (num=ptrobj->CarryBy) != -1 )
{
ztri = ListObjet[num].PosObjX - WorldXCube
+ ListObjet[num].PosObjZ - WorldZCube
+ 2 ;
}
if( ptrobj->Flags & SPRITE_3D )
{
ListTri[nbobjets].NumObj = n + TYPE_OBJ_SPRITE ;
if( ptrobj->Flags & SPRITE_CLIP )
{
ztri = ptrobj->AnimStepX - WorldXCube
+ ptrobj->AnimStepZ - WorldZCube ;
}
}
else
{
ListTri[nbobjets].NumObj = n + TYPE_OBJ_3D ;
}
ListTri[nbobjets].Z = ztri ;
nbobjets++ ;
if( Shadow )
{
if( !(ptrobj->Flags & NO_SHADOW) )
{
if( (c=ptrobj->CarryBy) != -1 )
{
ShadowX = ptrobj->PosObjX ;
ShadowY = ptrobj->PosObjY-1 ;
ShadowZ = ptrobj->PosObjZ ;
}
else
{
GetShadow( ptrobj->PosObjX,ptrobj->PosObjY,ptrobj->PosObjZ ) ;
}
ListTri[nbobjets].Z = ztri - 1 ;
/* ptrobj->PosObjX-xw + ptrobj->PosObjZ-zw - 1 ; */
ListTri[nbobjets].NumObj = TYPE_SHADOW + n ; /* shadow */
ListTri[nbobjets].Num = 2 ;
ListTri[nbobjets].Xw = ShadowX ;
ListTri[nbobjets].Yw = ShadowY ;
ListTri[nbobjets].Zw = ShadowZ ;
nbobjets++ ;
}
}
if( FlagMCGA )
{
if( n == NumObjFollow )
{
xmin = Xp ;
ymin = Yp ;
}
}
}
}
}
/*------------------------------------------------------------------------*/
/* objet temporaires (throw, bonus...) */
ptrextra = ListExtra ;
for( n=0; n<MAX_EXTRAS; n++, ptrextra++ )
{
if( ptrextra->Sprite != -1 )
{
if( ptrextra->Flags & EXTRA_TIME_IN )
{
if( (TimerRef - ptrextra->Timer) > 35 )
{
ptrextra->Timer = TimerRef ;
ptrextra->Flags &= ~EXTRA_TIME_IN ;
HQ_3D_MixSample( 11, 0x1000, 1,
ptrextra->PosX, ptrextra->PosY, ptrextra->PosZ ) ;
}
continue ;
}
if( ptrextra->Flags & EXTRA_TIME_OUT )
{
/* fait clignoter aff */
if( ptrextra->Flags & EXTRA_FLASH )
{
if( TimerRef >= ptrextra->Timer + ptrextra->TimeOut - 50 * 3 )
{
if( (TimerRef+ptrextra->Timer) & 8 )
continue ;
}
}
}
ProjettePoint( ptrextra->PosX-WorldXCube,
ptrextra->PosY-WorldYCube,
ptrextra->PosZ-WorldZCube ) ;
/* mettre test du preclip en fonction de la taille */
if( (Xp>VIEW_X0) AND (Xp<VIEW_X1) AND (Yp>VIEW_Y0) AND (Yp<VIEW_Y1) )
{
ListTri[nbobjets].Z = ptrextra->PosX-WorldXCube + ptrextra->PosZ-WorldZCube ;
ListTri[nbobjets].NumObj = n + TYPE_EXTRA ;
nbobjets++ ;
/* les effets n'ont pas d'ombres */
if( (Shadow==2) AND !(ptrextra->Sprite&32768) )
{
GetShadow( ptrextra->PosX,ptrextra->PosY,ptrextra->PosZ ) ;
ListTri[nbobjets].Z = ptrextra->PosX-WorldXCube + ptrextra->PosZ-WorldZCube - 1 ;
ListTri[nbobjets].NumObj = TYPE_SHADOW ; /* shadow */
/* GetDxDyGraph( ptrextra->Sprite, &dx, &dy, PtrSpriteExtra ) ; */
ListTri[nbobjets].Num = 0 ;
ListTri[nbobjets].Xw = ShadowX ;
ListTri[nbobjets].Yw = ShadowY ;
ListTri[nbobjets].Zw = ShadowZ ;
nbobjets++ ;
}
}
}
}
/*------------------------------------------------------------------------*/
/* tri objets */
SmallSort( ListTri, nbobjets, sizeof( T_SORT ) ) ;
// corrections des erreurs de tri
ptrobj = &ListObjet[NUM_PERSO] ; // Twinsen ZV
// cherche twinsen
if( (ptrobj->Body != -1)
AND (!(ptrobj->Flags&INVISIBLE)) )
{
txmin = ptrobj->PosObjX + ptrobj->Xmin ;
tymin = ptrobj->PosObjY + ptrobj->Ymin ;
tzmin = ptrobj->PosObjZ + ptrobj->Zmin ;
txmax = ptrobj->PosObjX + ptrobj->Xmax ;
tymax = ptrobj->PosObjY + ptrobj->Ymax ;
tzmax = ptrobj->PosObjZ + ptrobj->Zmax ;
twinsenpos = -1 ;
ptrtri = ListTri ;
for( n=0; n<nbobjets; n++, ptrtri++ )
{
if( ptrtri->NumObj == NUM_PERSO + TYPE_OBJ_3D )
{
twinsenpos = n ;
twinsenz = ptrtri->Z ;
break ;
}
}
// cherche bug porte
if( twinsenpos != -1 )
{
ptrtri = ListTri ;
for( n=0; n<nbobjets; n++, ptrtri++ )
{
numobj = ptrtri->NumObj ;
typeobj = numobj & ~1023 ;
numobj &= 1023 ;
ptrobj = &ListObjet[ numobj ] ;
switch( typeobj )
{
case TYPE_OBJ_SPRITE:
if( ptrobj->Flags & SPRITE_CLIP ) // tiens une porte ?
{
pxmin = ptrobj->AnimStepX + ptrobj->Xmin ;
pymin = ptrobj->AnimStepY + ptrobj->Ymin ;
pzmin = ptrobj->AnimStepZ + ptrobj->Zmin ;
pxmax = ptrobj->AnimStepX + ptrobj->Xmax ;
pymax = ptrobj->AnimStepY + ptrobj->Ymax ;
pzmax = ptrobj->AnimStepZ + ptrobj->Zmax ;
if( (pxmax > txmin) AND (pxmin < txmax) )
{
// axe des x commun
// regarde Z
if( pzmax <= tzmin ) // twinsen aprés
{
if( twinsenz < ptrtri->Z )
{
// correction erreur
ListTri[twinsenpos].Z = ptrtri->Z ;
ListTri[twinsenpos].NumObj = ptrtri->NumObj ;
ptrtri->NumObj = NUM_PERSO + TYPE_OBJ_3D ;
ptrtri->Z = twinsenz ;
twinsenpos = n ;
numobj = -1 ;
break ;
}
}
if( pzmin >= tzmax ) // twinsen avant
{
if( twinsenz > ptrtri->Z )
{
// correction erreur
ListTri[twinsenpos].Z = ptrtri->Z ;
ListTri[twinsenpos].NumObj = ptrtri->NumObj ;
ptrtri->NumObj = NUM_PERSO + TYPE_OBJ_3D ;
ptrtri->Z = twinsenz ;
twinsenpos = n ;
numobj = -1 ;
break ;
}
}
// axe des Z commun
// regarde Y min
// tanpis
break ;
}
if( (pzmax > tzmin) AND (pzmin < tzmax ) )
{
// axe des Z commun
// regarde X
if( pxmax <= txmin ) // twinsen aprés
{
if( twinsenz < ptrtri->Z )
{
// correction erreur
ListTri[twinsenpos].Z = ptrtri->Z ;
ListTri[twinsenpos].NumObj = ptrtri->NumObj ;
ptrtri->NumObj = NUM_PERSO + TYPE_OBJ_3D ;
ptrtri->Z = twinsenz ;
twinsenpos = n ;
numobj = -1 ;
break ;
}
}
else
{ // twinsen avant
if( twinsenz > ptrtri->Z )
{
// correction erreur
ListTri[twinsenpos].Z = ptrtri->Z ;
ListTri[twinsenpos].NumObj = ptrtri->NumObj ;
ptrtri->NumObj = NUM_PERSO + TYPE_OBJ_3D ;
ptrtri->Z = twinsenz ;
twinsenpos = n ;
numobj = -1 ;
break ;
}
}
}
}
break ;
}
if( numobj == -1 ) break ;
}
}
}
/*------------------------------------------------------------------------*/
/* boucle aff all objs */
shadowtwinsen = FALSE ;
NbPhysBox = 0 ;
for( n=0; n<nbobjets; n++ )
{
numobj = ListTri[n].NumObj ;
typeobj = numobj & ~1023 ;
numobj &= 1023 ;
ptrobj = &ListObjet[ numobj ] ;
switch( typeobj )
{
/*------------------------------------------------------------------------*/
case TYPE_OBJ_3D:
if( numobj == NUM_PERSO )
{
// correction rustine du petit bug créé par la grosse maguouille du tri
if( Shadow )
{
if( !shadowtwinsen )
{
// cherche ombre twinsen
for( i=n; i<nbobjets; i++ )
{
numobj = ListTri[i].NumObj ;
typeobj = numobj & ~1023 ;
numobj &= 1023 ;
if( ListTri[i].NumObj == TYPE_SHADOW + NUM_PERSO )
{
// affiche ombre twinsen
shadowtwinsen = TRUE ;
ProjettePoint( ListTri[i].Xw-WorldXCube,
ListTri[i].Yw-WorldYCube,
ListTri[i].Zw-WorldZCube ) ;
GetDxDyGraph( ListTri[n].Num, &dx, &dy, BufferShadow ) ;
ScreenXmin = Xp -(dx/2) ;
ScreenXmax = Xp +(dx/2) ;
ScreenYmin = Yp -(dy/2) ;
ScreenYmax = Yp +(dy/2) ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AffGraph( ListTri[i].Num, ScreenXmin, ScreenYmin, BufferShadow ) ;
xm = ((ListTri[i].Xw+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ListTri[i].Yw)/SIZE_BRICK_Y) ;
zm = ((ListTri[i].Zw+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick( xm, ym, zm ) ;
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
UnSetClip() ;
// detruit entree liste
ListTri[i].NumObj = -1 ; // type inconnu
break ; // sort boucle for
}
}
}
}
// gestion cliping noyade
if( FlagWater )
{
SetClip( 0,0, 639,FlagWater ) ;
}
// affiche twinsen
}
ptranim = HQR_Get( HQR_Anims, ptrobj->Anim ) ;
ptrbody = PtrBody[ ptrobj->Body ] ;
SetInterAnimObjet2( ptrobj->Frame, ptranim, ptrbody ) ;
err = AffObjetIso( ptrobj->PosObjX-WorldXCube, ptrobj->PosObjY-WorldYCube, ptrobj->PosObjZ-WorldZCube,
0, ptrobj->Beta, 0,
ptrbody ) ;
if( !err ) /* objet pas tout clippé */
{
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
ptrobj->WorkFlags |= WAS_DRAWN ;
xm = ((ptrobj->PosObjX+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ptrobj->PosObjY)/SIZE_BRICK_Y) ;
if( (ptrobj->Col&127) != 0 ) ym++ ;
zm = ((ptrobj->PosObjZ+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick( xm, ym, zm ) ;
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
if( (ptrobj->Flags & OBJ_BACKGROUND)
AND (flagflip == TRUE) )
{
CopyBlock( ClipXmin, ClipYmin, ClipXmax, ClipYmax, Log,
ClipXmin, ClipYmin, Screen ) ;
}
//DrawZV( &ListObjet[numobj] ) ;
}
}
break ;
/*------------------------------------------------------------------------*/
case TYPE_OBJ_SPRITE:
ProjettePoint( ptrobj->PosObjX-WorldXCube,
ptrobj->PosObjY-WorldYCube,
ptrobj->PosObjZ-WorldZCube ) ;
num = ptrobj->Body ;
GetDxDyGraph( 0, &dx, &dy, HQR_Get(HQRPtrSpriteExtra,num) ) ;
ScreenXmin = Xp + PtrZvExtra[ num*8 + 0 ] ;
ScreenYmin = Yp + PtrZvExtra[ num*8 + 1 ] ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
if( ptrobj->Flags & SPRITE_CLIP )
{
SetClip(ptrobj->Info+XpOrgw, ptrobj->Info1+YpOrgw,
ptrobj->Info2+XpOrgw, ptrobj->Info3+YpOrgw ) ;
}
else
{
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
}
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AffGraph( 0, ScreenXmin, ScreenYmin, HQR_Get(HQRPtrSpriteExtra,num) ) ;
ptrobj->WorkFlags |= WAS_DRAWN ;
if( ptrobj->Flags & SPRITE_CLIP )
{
xm = ((ptrobj->AnimStepX+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ptrobj->AnimStepY)/SIZE_BRICK_Y) ;
/* if( ptrobj->Col != 0 ) ym++ ; */
zm = ((ptrobj->AnimStepZ+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick3( xm, ym, zm ) ;
}
else
{
xm = ((ptrobj->PosObjX+ptrobj->Xmax+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ptrobj->PosObjY)/SIZE_BRICK_Y) ;
if( (ptrobj->Col&127) != 0 ) ym++ ;
zm = ((ptrobj->PosObjZ+ptrobj->Zmax+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick3( xm, ym, zm ) ;
}
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
if( (ptrobj->Flags & OBJ_BACKGROUND)
AND (flagflip == TRUE) )
{
CopyBlock( ClipXmin, ClipYmin, ClipXmax, ClipYmax, Log,
ClipXmin, ClipYmin, Screen ) ;
}
}
break ;
/*------------------------------------------------------------------------*/
case TYPE_SHADOW:
if( numobj == NUM_PERSO ) shadowtwinsen = TRUE ;
ProjettePoint( ListTri[n].Xw-WorldXCube,
ListTri[n].Yw-WorldYCube,
ListTri[n].Zw-WorldZCube ) ;
GetDxDyGraph( ListTri[n].Num, &dx, &dy, BufferShadow ) ;
ScreenXmin = Xp -(dx/2) ;
ScreenXmax = Xp +(dx/2) ;
ScreenYmin = Yp -(dy/2) ;
ScreenYmax = Yp +(dy/2) ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
/* mettre affpoly (lba2) */
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AffGraph( ListTri[n].Num, ScreenXmin, ScreenYmin, BufferShadow ) ;
// ptrobj = ListObjet ; ?
xm = ((ListTri[n].Xw+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ListTri[n].Yw)/SIZE_BRICK_Y) ;
zm = ((ListTri[n].Zw+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick( xm, ym, zm ) ;
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
/*------------------------------------------------------------------------*/
case TYPE_EXTRA:
ptrextra = &ListExtra[ numobj ] ;
ProjettePoint( ptrextra->PosX-WorldXCube,
ptrextra->PosY-WorldYCube,
ptrextra->PosZ-WorldZCube ) ;
num = ptrextra->Sprite ;
if( num & 32768 ) /* effet spécial */
{
AffSpecial( numobj, Xp, Yp ) ;
}
else /* sprite */
{
GetDxDyGraph( 0, &dx, &dy, HQR_Get(HQRPtrSpriteExtra,num) ) ;
ScreenXmin = Xp + PtrZvExtra[ num*8 + 0 ] ;
ScreenYmin = Yp + PtrZvExtra[ num*8 + 1 ] ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
AffGraph( 0, ScreenXmin, ScreenYmin, HQR_Get(HQRPtrSpriteExtra,num) ) ;
}
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
xm = ((ptrextra->PosX+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
ym = ((ptrextra->PosY)/SIZE_BRICK_Y) ;
zm = ((ptrextra->PosZ+DEMI_BRICK_XZ)/SIZE_BRICK_XZ) ;
DrawOverBrick( xm, ym, zm ) ;
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
/*------------------------------------------------------------------------*/
} /* end switch typeobj */
UnSetClip() ;
} /* end for nbobjets */
/*------------------------------------------------------------------------*/
// special incrust disp
ptrdisp = ListIncrustDisp ;
for( n=0; n<MAX_INCRUST_DISP; n++, ptrdisp++ )
{
if( ptrdisp->Num == -1 ) continue ;
switch( ptrdisp->Move )
{
case 0: // wait nb sec and die
if( TimerRef > ptrdisp->TimerEnd )
{
ptrdisp->Num = -1 ;
continue ;
}
break ;
case 1: // follow obj coor for nb sec and die
num = ptrdisp->Info ;
ProjettePoint( ListObjet[num].PosObjX - WorldXCube,
ListObjet[num].PosObjY + ListObjet[num].Ymax - WorldYCube,
ListObjet[num].PosObjZ - WorldZCube ) ;
ptrdisp->X = Xp ;
ptrdisp->Y = Yp ;
if( TimerRef > ptrdisp->TimerEnd )
{
ptrdisp->Num = -1 ;
continue ;
}
break ;
}
switch( ptrdisp->Type )
{
case INCRUST_NUM:
strcpy( string, Itoa( ptrdisp->Num ) ) ;
dx = SizeFont( string ) ;
dy = 48 ;
ScreenXmin = ptrdisp->X - dx/2 ;
ScreenYmin = ptrdisp->Y - dy/2 ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
CoulFont( ptrdisp->Info ) ;
Font( ScreenXmin, ScreenYmin, string ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
case INCRUST_TEXT:
GetMultiText( ptrdisp->Num, string ) ;
dx = SizeFont( string ) + 1 ; // because /2
dy = 48 ;
ScreenXmin = ptrdisp->X - dx/2 ;
ScreenYmin = ptrdisp->Y - dy/2 ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
if( ScreenXmax >= 640 )
{
ScreenXmin -= ScreenXmax - 639 ;
ScreenXmax = 639 ;
}
if( ScreenXmin < 0 )
{
ScreenXmax = dx ;
ScreenXmin = 0 ;
}
if( ScreenYmax >= 480 )
{
ScreenYmin -= ScreenYmax - 479 ;
ScreenYmax = 479 ;
}
if( ScreenYmin < 0 )
{
ScreenYmax = dy ;
ScreenYmin = 0 ;
}
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
// CoulFont( 0 ) ;
// Font( ClipXmin+2, ClipYmin+4, string ) ;
CoulFont( ListObjet[ptrdisp->Info].CoulObj*16 + 14 ) ;
Font( ClipXmin, ClipYmin, string ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
case INCRUST_SPRITE:
GetDxDyGraph( 0, &dx, &dy, HQR_Get(HQRPtrSpriteExtra,ptrdisp->Num) ) ;
ScreenXmin = ptrdisp->X + PtrZvExtra[ ptrdisp->Num*8 + 0 ] ;
ScreenYmin = ptrdisp->Y + PtrZvExtra[ ptrdisp->Num*8 + 1 ] ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
AffGraph( 0, ScreenXmin, ScreenYmin, HQR_Get(HQRPtrSpriteExtra,ptrdisp->Num) ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
case INCRUST_CMPT:
cmpt = ptrdisp->TimerEnd-TimerRef ;
c = BoundRegleTrois( ptrdisp->Info, ptrdisp->Num, 50*2, cmpt-50 ) ;
strcpy( string, Itoa( c ) ) ;
dx = SizeFont( string ) ;
dy = 48 ;
ScreenXmin = ptrdisp->X ;
ScreenYmin = ptrdisp->Y - dy/2 ;
ScreenXmax = ScreenXmin + dx ;
ScreenYmax = ScreenYmin + dy ;
SetClip( ScreenXmin, ScreenYmin, ScreenXmax, ScreenYmax ) ;
CoulFont( 155 ) ;
Font( ScreenXmin, ScreenYmin, string ) ;
if( ClipXmin <= ClipXmax
AND ClipYmin <= ClipYmax )
{
AddPhysBox( ClipXmin, ClipYmin, ClipXmax, ClipYmax ) ;
}
break ;
case INCRUST_OBJ:
{
UBYTE *ptr3do ;
Box( 10, 10, 69, 69, 0 ) ;
SetClip( 10, 10, 69, 69 ) ;
ptr3do = HQR_Get( InventoryObj, ptrdisp->Num ) ;
if( HQR_Flag )
{
PatchObjet( ptr3do ) ;
}
SetProjection( 40,40, 128,200,200 ) ;
SetFollowCamera( 0,0,0, 60,0,0, 16000 ) ;
AffObjetIso( 0,0,0, 0,BetaUsedObj+=8,0, ptr3do ) ;
DrawCadre( 10, 10, 69, 69 ) ;
AddPhysBox( 10, 10, 69, 69 ) ;
Init3DGame() ;
}
break ;
}
}
UnSetClip() ;
/*------------------------------------------------------------------------*/
/* flip boxes */
if( FlagVsync ) Vsync() ;
if( FlagMCGA )
{
CopyBlockPhysMCGA( xmin, ymin, xmax, ymax ) ;
FlipOptList() ;
if( flagflip ) RestoreTimer() ;
}
else
{
if( !flagflip )
{
FlipBoxes() ; /* Flip Log vers Phys */
}
else
{
Flip() ;
FlipOptList() ;
RestoreTimer() ;
}
}
if( FlagFade )
{
if( FlagPalettePcx ) FadeToPal( PalettePcx ) ;
else FadeToPal( PtrPal ) ;
FlagFade = FALSE ;
}
}
/*══════════════════════════════════════════════════════════════════════════*
▀▀▀█▀ █▀▀▀█ ██▄ █ █▀▀▀▀ █▀▀▀▄ █▀▀▀▀ █▀▀▀▀
▄█ ██ █ ██▀██ ██▀▀ ██ █ ██▀▀ ██
▀▀▀▀▀ ▀▀▀▀▀ ▀▀ ▀ ▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀ ▀▀▀▀▀ ▀▀▀▀▀
*══════════════════════════════════════════════════════════════════════════*/
/*──────────────────────────────────────────────────────────────────────────*/
/*══════════════════════════════════════════════════════════════════════════*/
void CheckZoneSce( T_OBJET *ptrobj, WORD numobj )
{
WORD n ;
T_ZONE *ptrz ;
WORD x,y,z ;
WORD flaggrm = FALSE ;
x = ptrobj->PosObjX ;
y = ptrobj->PosObjY ;
z = ptrobj->PosObjZ ;
ptrz = ListZone ;
ptrobj->ZoneSce = -1 ;
if( numobj == NUM_PERSO )
{
FlagClimbing = FALSE ;
}
for( n=0; n<NbZones; n++ )
{
if( x >= ptrz->X0
AND x <= ptrz->X1
AND y >= ptrz->Y0
AND y <= ptrz->Y1
AND z >= ptrz->Z0
AND z <= ptrz->Z1 )
{
// si type test angle
switch( ptrz->Type )
{
case 0: // change cube perso
if( numobj == NUM_PERSO )
{
// protection meurt dans un autre cube
if( ptrobj->LifePoint > 0 )
{
NewCube = ptrz->Num ;
NewPosX = ptrobj->PosObjX - ptrz->X0 + ptrz->Info0 ;
NewPosY = ptrobj->PosObjY - ptrz->Y0 + ptrz->Info1 ;
NewPosZ = ptrobj->PosObjZ - ptrz->Z0 + ptrz->Info2 ;
FlagChgCube = 1 ;
return ;
}
}
break ;
case 1: // set pos camera
if( numobj == NumObjFollow )
{
// signale pos forcée
CameraZone = TRUE ;
if( StartXCube != ptrz->Info0
OR StartYCube != ptrz->Info1
OR StartZCube != ptrz->Info2 )
{
StartXCube = ptrz->Info0 ;
StartYCube = ptrz->Info1 ;
StartZCube = ptrz->Info2 ;
FirstTime = TRUE ;
}
}
break ;
case 2: // zone scenarique
ptrobj->ZoneSce = ptrz->Num ;
break ;
case 3: // zone grm
if( numobj == NumObjFollow )
{
flaggrm = TRUE ;
if( ZoneGrm != ptrz->Num )
{
if( ZoneGrm != -1 )
CopyMapToCube() ;
ZoneGrm = ptrz->Num ;
IndexGrm = n ;
SaveTimer() ;
IncrustGrm( ptrz->Num ) ;
RestoreTimer() ;
}
}
break ;
case 4: // zone giver
if( numobj == NUM_PERSO )
{
if( ActionNormal )
{
InitAnim( GEN_ANIM_ACTION, ANIM_THEN, GEN_ANIM_RIEN, NUM_PERSO ) ;
ZoneGiveExtraBonus( ptrz ) ;
}
}
break ;
case 5: // zone message
if( numobj == NUM_PERSO )
{
if( ActionNormal )
{
SaveTimer() ;
TestRestoreModeSVGA( TRUE ) ;
TestCoulDial( ptrz->Info0 ) ;
#ifdef CDROM
NumObjSpeak = NUM_PERSO ;
#endif
Dial( ptrz->Num ) ;
RestoreTimer() ;
AffScene(TRUE) ;
WaitReleaseSpace() ;
}
}
break ;
case 6: // echelle
if( (numobj==NUM_PERSO) AND (Comportement!=C_PROTOPACK) )
{
if( ( ptrobj->GenAnim == GEN_ANIM_MARCHE )
OR ( ptrobj->GenAnim == GEN_ANIM_ECHELLE )
OR ( ptrobj->GenAnim == GEN_ANIM_MONTE ) )
{
Rotate( ptrobj->Xmin, ptrobj->Zmin, ptrobj->Beta + 896 + 512 ) ;
X0 += Nxw ;
Y0 += Nzw ;
if( (X0 >= 0) AND (Y0 >= 0)
AND (X0 <= 63*SIZE_BRICK_XZ) AND (Y0 <= 63*SIZE_BRICK_XZ)
AND (WorldColBrick( X0, ptrobj->PosObjY+256, Y0 ) != 0) )
{
FlagClimbing = TRUE ;
if( ptrobj->PosObjY >= ((ptrz->Y0+ptrz->Y1)/2) )
{
InitAnim( GEN_ANIM_ECHELLE, ANIM_ALL_THEN, GEN_ANIM_RIEN, numobj ) ;
}
else
{
InitAnim( GEN_ANIM_MONTE, ANIM_REPEAT, NO_ANIM, numobj ) ;
}
}
}
}
break ;
}
}
ptrz++ ;
}
if( flaggrm == FALSE
AND numobj == NumObjFollow
AND ZoneGrm != -1 )
{
IndexGrm = ZoneGrm = -1 ;
CopyMapToCube() ;
FirstTime = TRUE;
}
}
#ifdef DEBUG_TOOLS
void ClearZoneSce()
{
WORD n ;
T_ZONE *ptrz ;
ptrz = ListZone ;
for( n=0; n<NbZones; n++ )
{
switch( ptrz->Type )
{
case 4: // zone giver
ptrz->Info2 = 0 ;
break ;
}
ptrz++ ;
}
}
#endif