#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; nPtrFile3D = 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; nLifePoint <= 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; nBody != -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; nBody != -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; nPosObjX + 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; nBody != -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; nWorkFlags &= ~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 (XpVIEW_Y0) AND (YpWorkFlags |= 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 (XpVIEW_Y0) AND (YpVIEW_X0) AND (XpVIEW_Y0) AND (YpPosObjX - 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; nSprite != -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 (XpVIEW_Y0) AND (YpPosX-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; nNumObj == NUM_PERSO + TYPE_OBJ_3D ) { twinsenpos = n ; twinsenz = ptrtri->Z ; break ; } } // cherche bug porte if( twinsenpos != -1 ) { ptrtri = ListTri ; for( n=0; nNumObj ; 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; nAnim ) ; 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; nNum == -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= 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; nType ) { case 4: // zone giver ptrz->Info2 = 0 ; break ; } ptrz++ ; } } #endif