reman3/Rayman_X/cpa/tempgrp/GAM/Always.c

1088 lines
39 KiB
C

/*=========================================================================
* Always.c : This module contain all always functions
* This is a part of the Game project.
*
* Version 1.0
* Creation date 09/08/96
* Revision date
*
* That file needs to be compatible for all platforms.
*
* (c) Ubi Studios 1996
*=======================================================================*/
/*
*=======================================================================
Modifications: New LST_M_??? Macros / Michaël / 070297
*=======================================================================*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#define D_3dData_StructureDefine
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "ToolsCPA.h"
#include "Options/Options.h"
#include "Macros.h"
#include "safe.h"
#include "Actions/AllActs.h"
#define D_SectInfo_StructureDefine
#include "Actions/SectInfo.h"
#undef D_SectInfo_StructureDefine
#include "Structur/Anim_s.h"
#include "Structur/EngMode.h"
#include "Structur/ErrGame.h"
#include "Structur/MemGame.h"
#include "Structur/Objects.h"
#include "Structur/State.h"
#include "Structur/StdObjSt.h"
#include "Family.h"
#include "Always.h"
#include "GameEng.h"
#include "ObjInit.h"
#include "ZeMem.h"
#include "ChanList.h"
#include "MainChar.h"
#include "Micros.h"
#include "PlayAnim/PlayAnim.h"
#ifdef U64
#include "RastMem.h"
#endif /* U64 */
/* ANNECY AV DEMO {*/
#ifndef U64
#include "Specif/Demos.h"
#endif
/* END ANNECY AV }*/
#include "Micros.h"
#include "objtype.h"
#include "textfrmt.h"
#ifdef GAM_USE_SNA
#include "SNA.h"
/*#include "PTC.h"*/
#endif /* GAM_USE_SNA */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef U64
extern void fn_vFirstInitMorphTaskList(unsigned long _ulNbMorphTasks,
unsigned long _ulNbElements,
unsigned long _ulNbPoints);
#else /* U64 */
extern void fn_vFirstInitMorphTaskList();
#endif /* U64 */
extern void fn_vLastDeinitMorphTaskList();
extern ACP_tdxBool fn_bIsInFix(struct tdstEngineObject_ *p_stObject);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#if defined (ACTIVE_EDITOR) || defined (RETAIL)
#define ENGassert(param)
#else
#define ENGassert(param) assert(param)
#endif
#if (!defined(FINAL_VERSION) || defined(FINAL_VERSION_FOR_TESTERS)) && defined(U64)
#define D_WANT_OPTIMIZE_MEMORY
#endif /* (!defined(FINAL_VERSION) || defined(FINAL_VERSION_FOR_TESTERS)) && defined(U64) */
#ifdef D_WANT_OPTIMIZE_MEMORY
long g_lNbAllocatedAlways;
long g_lMaxNbAllocatedAlways;
long g_lAllowedNbAllocatedAlways;
#endif /* D_WANT_OPTIMIZE_MEMORY */
//End XB
/*-----------------------------------------------------------------------------
* Description : Allocate an always engine object
* with all game structures
*-----------------------------------------------------------------------------
* Input : Family, model and personal
* Output : Pointer to the object
*-----------------------------------------------------------------------------
* Creation date : 09/10/96 Author : Francois
*---------------------------------------------------------------------------*/
struct tdstEngineObject_ *fn_p_stAllocateAlwaysEngineObject(tdObjectType otObjectFamilyType,tdObjectType otObjectModelType,tdObjectType otObjectPersonalType)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
tdstEngineObject *p_stTempObject;
/* long i;*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeEngineObject , 0 );
p_stTempObject=(tdstEngineObject *)M_p_GameMallocInHLM(sizeof(tdstEngineObject));
/* ANNECY AV {*/
/* Now, the mini-structures are allocated only when necessary
M_ForAllMiniStructure(i)
{
g_a_stStructureHandleFunction[i].p_fn_vAllocFunction(p_stTempObject);
}
*/
/*memset (p_stTempObject , 0 , sizeof (tdstEngineObject));*/ /* AR9904 Already done in alloc function */
/* We only allocated the StandardGame, 3dData and Brain mini-structures*/
#ifdef SHOW_RAST_MEM
/*h_StandardGame*/
RM_fn_vInitAddInfo();
fn_vStdGameAlloc(p_stTempObject);
RM_fn_vAddInfo(eMS4AStandardGame,eSubAlwaysGam,eGam);
/*h_3dData*/
RM_fn_vInitAddInfo();
fn_v3dDataAlloc (p_stTempObject);
RM_fn_vAddInfo(eMS4A3dData,eSubAlwaysGam,eGam);
/*h_Brain*/
RM_fn_vInitAddInfo();
fn_vBrainAlloc(p_stTempObject);
RM_fn_vAddInfo(eMS4ABrain,eSubAlwaysGam,eGam);
#else
fn_vStdGameAlloc (p_stTempObject);
fn_v3dDataAlloc (p_stTempObject);
fn_vBrainAlloc (p_stTempObject);
#endif
/* END ANNECY AV }*/
M_ObjectSetFamilyType(p_stTempObject,otObjectFamilyType);
#ifndef U64
M_ObjectSetModelType(p_stTempObject,otObjectModelType);
#endif
M_ObjectSetPersonalType(p_stTempObject,otObjectPersonalType);
/* ANNECY AV {*/
/*
if (otObjectFamilyType!=C_InvalidObjectType)
fn_v3dDataSetFamily(p_stTempObject->h_3dData,fn_hFindOrAddFAmily(otObjectFamilyType));
*/
/* END ANNECY AV }*/
return(p_stTempObject);
}
/*-----------------------------------------------------------------------------
* Description : Initialize the always structure (when the map is loaded)
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 08/10/96 Author : Francois
*---------------------------------------------------------------------------*/
void fn_vFirstInitAlwaysStructure()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
tdstEngineObject *p_stTempEngineObject;
unsigned long i;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef D_WANT_OPTIMIZE_MEMORY
g_lNbAllocatedAlways=0;
g_lMaxNbAllocatedAlways=0;
g_lAllowedNbAllocatedAlways=g_stAlways.ulMaxNumberOfAlways;
#endif /* D_WANT_OPTIMIZE_MEMORY */
/**** We allocate all structures used by a engine super-object ****/
if (g_stAlways.ulMaxNumberOfAlways)
{
#ifdef U64
RM_fn_vInitAddInfo();
#endif /* U64 */
g_stAlways.d_stAlwaysSuperObject = HIE_fn_p_stCreateSuperObjectTab(g_stAlways.ulMaxNumberOfAlways);
MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeEngineObject , 0 );
#ifdef U64
RM_fn_vAddInfo(e4ASuperObject,eSubAlwaysGeo,eGeo);
RM_fn_vInitAddInfo();
#endif /* U64 */
g_stAlways.d_stAlwaysEngineObjectInit = (struct tdstEngineObject_*)M_p_GameMallocInHLM(g_stAlways.ulMaxNumberOfAlways*sizeof(struct tdstEngineObject_));
MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeAlwaysGenerator , 0 );
#ifdef U64
RM_fn_vAddInfo(e4AEngineObject,eSubAlwaysGam,eGam);
RM_fn_vInitAddInfo();
#endif /* U64 */
g_stAlways.d_hAlwaysGenerator = (HIE_tdxHandleToSuperObject *)M_p_GameMallocInHLM(g_stAlways.ulMaxNumberOfAlways * sizeof(HIE_tdxHandleToSuperObject) );
#if defined(ACTIVE_EDITOR)
g_stAlways.d_bIsReferencedInLevel = (ACP_tdxBool *)M_p_GameMallocInHLM(g_stAlways.ulMaxNumberOfAlways * sizeof(ACP_tdxBool) );
#endif /* ACTIVE_EDITOR */
#ifdef U64
RM_fn_vAddInfo(e4AGenerator,eSubAlwaysGam,eGam);
#endif /* U64 */
/* ANNECY AV DEMO {*/
#ifndef U64
DEMO_fn_vStartOfAlwaysCreation (); /* For the DEMO module to know the number of the first created always*/
#endif
/* END ANNECY AV }*/
for (i=0;i<g_stAlways.ulMaxNumberOfAlways;i++)
{
/*
* init generator array
*/
g_stAlways.d_hAlwaysGenerator[ i ] = NULL;
#if defined(ACTIVE_EDITOR)
g_stAlways.d_bIsReferencedInLevel[i] = FALSE;
#endif /* ACTIVE_EDITOR */
/*
* create engine object
*/
p_stTempEngineObject=fn_p_stAllocateAlwaysEngineObject(C_InvalidObjectType,C_InvalidObjectType,C_AlwaysObjectType);
/* ANNECY AV DEMO {*/
#ifndef U64
DEMO_fn_vPutCharacterInList (HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i));
#endif
/* END ANNECY AV }*/
/**** Link the object with the super object ****/
HIE_fn_vSetSuperObjectObjectAndType(HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i),(void *)p_stTempEngineObject,HIE_C_ulActor);
HIE_fn_vSetSuperObjectMatrix(HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i),fn_p_st3dDataGetMatrix(p_stTempEngineObject->h_3dData));
M_SetSuperObject(p_stTempEngineObject,HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i));
/* ANNECY AV {*/
/* This is already done in the fn_p_stAllocatedAlwaysEngineObject function
// *** Allocate all object's structures *** - Oliv' - Portage v15 - 1 warning removed here
M_ForAllMiniStructureNULL(p_stTempEngineObject,j)
{
g_a_stStructureHandleFunction[j].p_fn_vAllocFunction(p_stTempEngineObject);
}
*/
/* END ANNECY AV }*/
memcpy(&(g_stAlways.d_stAlwaysEngineObjectInit[i]),p_stTempEngineObject,sizeof(struct tdstEngineObject_));
memset(p_stTempEngineObject,0,sizeof(struct tdstEngineObject_));
}
}
}
/*-----------------------------------------------------------------------------
* Description : Desinitialize the always structure (when the map is finish)
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 08/10/96 Author : Francois
*---------------------------------------------------------------------------*/
void fn_vLastDesinitAlwaysStructure()
{
/**** Start by kill all active always in the map ****/
fn_vKillAllAlways();
if (g_stAlways.ulMaxNumberOfAlways)
{
g_stAlways.d_stAlwaysEngineObjectInit = NULL;
g_stAlways.d_stAlwaysSuperObject = NULL;
g_stAlways.d_hAlwaysGenerator = NULL;
#if defined(ACTIVE_EDITOR)
g_stAlways.d_bIsReferencedInLevel = NULL;
#endif /* ACTIVE_EDITOR */
}
}
/*-----------------------------------------------------------------------------
* Description : Add a always model to the chain list
*-----------------------------------------------------------------------------
* Input : engine object's pointer
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*---------------------------------------------------------------------------*/
void fn_vAddAnAlwaysModel(struct tdstEngineObject_ *p_stAlwaysObject)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Oliv' - Portage v15*/
#ifndef U64
long i;
ALW_tdxHandleToModelList h_AlwaysModelChild;
#endif
/* EndOfOliv'*/
ALW_tdxHandleToModelList h_NewAlwaysModel;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifndef U64
LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
{
if (h_AlwaysModelChild->otObjectModelType==M_ObjectGetModelType(p_stAlwaysObject))
{
M_GameWarningError(E_uwGameAddAnAlwaysModelAlreadyExist);
p_stAlwaysObject = fn_p_stFreeEngineObject(p_stAlwaysObject);
Erm_M_ClearLastError(C_ucErmDefaultChannel);
}
}
#endif
if (p_stAlwaysObject!=NULL)
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeGAM , MMG_C_lSubTypeAlwaysModel , 0 );
h_NewAlwaysModel = (struct tdstAlwaysModelList_ *)M_p_GameMallocInHLM(sizeof(struct tdstAlwaysModelList_));
h_NewAlwaysModel->p_stAlwaysObject = p_stAlwaysObject;
#ifdef U64
h_NewAlwaysModel->otObjectModelType = M_ObjectGetPersonalType(p_stAlwaysObject);
#else
h_NewAlwaysModel->otObjectModelType = M_ObjectGetModelType(p_stAlwaysObject);
#endif
LST2_M_DynamicAddTail(&(g_stAlways.ALW_h_LstAlwaysModel),h_NewAlwaysModel);
/* Oliv' - Portage v15*/
if( p_stAlwaysObject->h_StandardGame )
fn_vStandardGameSetAlways( p_stAlwaysObject->h_StandardGame, TRUE );
/* Gus: Le flag Always dans la dynam sert uniquement a savoir ou elle est allouee.
IL NE FAUT PAS LE CHANGER !!!!!
if( p_stAlwaysObject->h_Dynam )
{
DNM_tdstDynamics* p_stDynamic;
if( (p_stDynamic = fn_p_stDynamGetDynamics(p_stAlwaysObject->h_Dynam)) != NULL )
DNM_M_vDynamicsSetAlways ( p_stDynamic, TRUE );
}
*/
/* EndOfOliv'*/
}
}
/*-----------------------------------------------------------------------------
* Description : Destroy all always model chain list
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*---------------------------------------------------------------------------*/
void fn_vKillAllAlwaysModel()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
long i;
ALW_tdxHandleToModelList h_AlwaysModelChild,h_AlwaysModelNextChild;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
LST2_M_DynamicForEachMovingElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,h_AlwaysModelNextChild,i)
{
/* if the always model is in fix, then desinit it*/
/* else, destroy it !*/
if ( fn_bIsInFix(h_AlwaysModelChild->p_stAlwaysObject) )
{
/* desinit*/
fn_vDesinitOneObject(h_AlwaysModelChild->p_stAlwaysObject,OTI_MapLoaded);
}
else
{
LST2_M_DynamicIsolate(h_AlwaysModelChild);
/* Oliv - 14/10/1998 - Cannot free Gam Level Memory*/
#if !defined(U64)
h_AlwaysModelChild->p_stAlwaysObject = fn_p_stFreeEngineObject(h_AlwaysModelChild->p_stAlwaysObject);
#else
h_AlwaysModelChild->p_stAlwaysObject = NULL;
#endif
/* EndOfOliv'*/
}
/*h_AlwaysModelChild->p_stAlwaysObject=fn_p_stFreeEngineObject(h_AlwaysModelChild->p_stAlwaysObject);*/
/*M_GameFreeInHLM(h_AlwaysModelChild);*/
}
}
/*-----------------------------------------------------------------------------
* Description : init all always model chain list
*-----------------------------------------------------------------------------
* Input : type of initialisation
* Output : none
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*---------------------------------------------------------------------------*/
void fn_vInitAlwaysModel(enum tdeObjectTreeInit_ eObjIniType)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
ALW_tdxHandleToModelList h_AlwaysModelChild;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
{
fn_vInitOneObject(h_AlwaysModelChild->p_stAlwaysObject,eObjIniType);
}
}
/*-----------------------------------------------------------------------------
* Description : Allocate a always by a type
*-----------------------------------------------------------------------------
* Input : Type of always, father in hierarchy
* Output : Engine super object structure (NULL if error)
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*---------------------------------------------------------------------------*/
unsigned char fn_ucIsAnAlwaysObject(struct tdstEngineObject_ *p_stEngineObject)
{
/* ANNECY MT - 12/10/98 {*/
return (fn_bStandardGameIsAlways (p_stEngineObject -> h_StandardGame));
/* END ANNECY MT }*/
}
/*-----------------------------------------------------------------------------
* Description :
*-----------------------------------------------------------------------------
* Input :
* Output :
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*---------------------------------------------------------------------------*/
unsigned char fn_ucIsAnAlwaysModel(struct tdstEngineObject_ *p_stEngineObject)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
ALW_tdxHandleToModelList h_AlwaysModelChild;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if (M_ObjectGetPersonalType(p_stEngineObject) >= C_AlwaysObjectType)
return TRUE;
LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
{
if (M_ObjectGetPersonalType(p_stEngineObject)==M_ObjectGetPersonalType(h_AlwaysModelChild->p_stAlwaysObject))
return TRUE;
}
return( FALSE );
}
/*-----------------------------------------------------------------------------
* Description : Allocate a always by a type
*-----------------------------------------------------------------------------
* Input : Type of always, father in hierarchy
* Output : Engine super object structure (NULL if error)
*-----------------------------------------------------------------------------
* Creation date : 11/10/96 Author : Francois
*-----------------------------------------------------------------------------
* Modification : 18/09/98 Author : Marc
*---------------------------------------------------------------------------*/
HIE_tdxHandleToSuperObject fn_p_stAllocateAlways
(
tdObjectType otObjectModelType,
HIE_tdxHandleToSuperObject p_stFatherSuperObject,
HIE_tdxHandleToSuperObject _hGenerator,
unsigned short uwAction,
POS_tdstCompletePosition *p_stMatrix
)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
HIE_tdxHandleToSuperObject h_stSuperObject=NULL;
HIE_tdxHandleToSuperObject h_SOSector;
unsigned long i,j;
ALW_tdxHandleToModelList h_AlwaysModelChild;
struct tdstEngineObject_ *p_stEngineObject=NULL;
MTH3D_tdstVector *p_stTempVector=NULL;
#ifdef __DEBUG_AI__
AI_tdstMind *p_stMind;
#endif /* __DEBUG_AI__*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
{
/*
* Search for the model
*/
if (h_AlwaysModelChild->otObjectModelType == otObjectModelType)
{
/*
* search for a free case in always array
*/
h_stSuperObject = g_stAlways.d_stAlwaysSuperObject;
for ( i = 0; ( i < g_stAlways.ulMaxNumberOfAlways ) && ( g_stAlways.d_hAlwaysGenerator[i] != NULL || HIE_M_hNextChild(h_stSuperObject) != NULL ); i ++ , h_stSuperObject ++ );
/*
* none found : return NULL
*/
if (i >= g_stAlways.ulMaxNumberOfAlways)
{
#ifdef U64
M_PrintfWarningN64(("\n\nCan't create an always"));
#endif /* U64 */
return NULL;
}
#ifdef D_WANT_OPTIMIZE_MEMORY
g_lNbAllocatedAlways++;
if(g_lMaxNbAllocatedAlways<g_lNbAllocatedAlways)
{
g_lMaxNbAllocatedAlways=g_lNbAllocatedAlways;
}
#endif /* D_WANT_OPTIMIZE_MEMORY */
/*
* set generator
*/
g_stAlways.d_hAlwaysGenerator[ i ] = _hGenerator;
/*
* get super object and engine object
*/
p_stEngineObject = (tdstEngineObject *)HIE_fn_hGetSuperObjectObject(h_stSuperObject);
/*
* init SPO
*/
HIE_fn_SO_vSetFlags(h_stSuperObject,0);
HIE_fn_vSetSuperObjectDrawMask(h_stSuperObject, GLI_C_lAllIsEnable);
/*
* init MS
*/
M_ForAllMiniStructureExceptNULL(h_AlwaysModelChild->p_stAlwaysObject,j)
{
/* ANNECY AV {*/
/* Now, we allocate the mini-structure only when necessary*/
if (M_VoidMiniStructurePointer (& g_stAlways.d_stAlwaysEngineObjectInit [i] , j) == NULL)
g_a_stStructureHandleFunction [j] . p_fn_vAllocFunction (& g_stAlways . d_stAlwaysEngineObjectInit [i]);
/* END ANNECY AV }*/
M_CopyMSPointer(p_stEngineObject,&(g_stAlways.d_stAlwaysEngineObjectInit[i]),j);
g_a_stStructureHandleFunction[j].p_fn_vCopyCloneMSFunction( p_stEngineObject,h_AlwaysModelChild->p_stAlwaysObject );
}
M_ObjectSetPersonalType(p_stEngineObject,C_AlwaysObjectType+i);
M_SetSuperObject(p_stEngineObject,h_stSuperObject);
/*
* Setting an initial state
*/
if( p_stEngineObject->h_3dData )
{
fn_v3dDataSetMatrix(p_stEngineObject->h_3dData,p_stMatrix);
}
/* ANNECY AV DEMO {*/
#ifndef U64
#ifndef RETAIL
DEMO_fn_vSaveAlwaysActivationDesactivation (h_stSuperObject,p_stTempVector,TRUE);
#endif /* RETAIL */
#endif
/* END ANNECY AV }*/
/*
* Update GlobalMatrix
*/
POS_fn_vMulMatrixMatrix( HIE_fn_hGetSuperObjectGlobalMatrix(h_stSuperObject) , HIE_fn_hGetSuperObjectGlobalMatrix(p_stFatherSuperObject) , HIE_fn_hGetSuperObjectMatrix(h_stSuperObject) );
HIE_fn_vValidateGlobalMatrix(h_stSuperObject);
/* ANNECY MT - 18/09/98 {*/
/*
* Testing if always is generated in a good sector
*/
p_stTempVector = POS_fn_p_stGetTranslationVector (HIE_fn_hGetSuperObjectGlobalMatrix(h_stSuperObject));
h_SOSector = GAM_fn_hGetCurrentSector( _hGenerator );
if( ! SECT_fn_bIsInBorderBox( p_stTempVector, (SECT_tdxHandleOfSectorObject)HIE_fn_hGetSuperObjectObject(h_SOSector) ) )
{
h_SOSector=SECT_fn_hResearchInWhatSectorIAm(SECT_hFatherSector,p_stTempVector);
}
if( !h_SOSector )
{
g_stAlways.d_hAlwaysGenerator[ i ] = NULL;
return NULL;
}
fn_vSectInfoSetCurrentSector(p_stEngineObject->h_SectInfo,h_SOSector);
M_ForAllMiniStructureExceptNULL(p_stEngineObject,j)
{
g_a_stStructureHandleFunction[j].p_fn_vInitFunction(p_stEngineObject,OTI_AlwaysCreated);
}
/*
* Add In Hierarchy
*/
if ( fn_ucStandardGameGetPlatFormType(M_GetMSHandle(h_stSuperObject,StandardGame)) )
{
HIE_fn_vSuperObjectAddHead(p_stFatherSuperObject, h_stSuperObject);
}
else
{
HIE_fn_vSuperObjectAddTail(p_stFatherSuperObject, h_stSuperObject);
}
fn_vStandardGameSetIsActivable(p_stEngineObject->h_StandardGame,1);
/*
* Update Misc Flag
*/
/* ANNECY MT - 12/10/98 {*/
/* Oliv' - Portage v15 - THIS IS TOO LATE HERE. See AddAnAlwaysModel - so it's unnecessary now here*/
/* fn_vStandardGameSetAlways(p_stEngineObject->h_StandardGame,TRUE);*/
/* EndOfOliv'*/
/* END ANNECY MT }*/
/*
* Update Bounding Volumes for always
*/
h_stSuperObject->hBoundingVolume = fn_vGetBoundingVolumeOfFamily(fn_h3dDataGetFamily(p_stEngineObject->h_3dData));
/*
* Give name to always
*/
#ifdef __DEBUG_AI__
if (M_GetMSHandle(h_stSuperObject,Brain))
{
p_stMind = AI_M_stGetMindOfSuperObj(h_stSuperObject);
AI_M_SetPersoName (p_stMind, fn_szFindPersonalTypeNameOfPersonalType(M_ObjectGetPersonalType(h_AlwaysModelChild->p_stAlwaysObject)));
}
#endif /* __DEBUG_AI__*/
/*
* Active the object' : now it's useless to call the 'fn_vForceActiveAnObject' function after this
*/
M_ActivateObject(p_stEngineObject);
{
fn_v3dDataSetStartTime(p_stEngineObject->h_3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
fn_v3dDataSetTimePreviousFrame(p_stEngineObject->h_3dData,g_stEngineStructure.stEngineTimer.ulCurrentTimerCount);
}
/* reactive an object, so create its element3d array if necessary*/
if (fn_p_st3dDataGetCurrentFrame(p_stEngineObject->h_3dData)->p_stArrayOfElts3d == NULL)
{
tdstAnim3d * p_stCurrentAnim;
tdxHandleToState hState;
ENGassert(fn_h3dDataGetCurrentState(p_stEngineObject->h_3dData) != NULL);
if (fn_h3dDataGetCurrentState(p_stEngineObject->h_3dData))
{
hState = fn_h3dDataGetCurrentState(p_stEngineObject->h_3dData);
p_stCurrentAnim = fn_p_stGetAnimInState(hState);
if (p_stCurrentAnim)
{
/* ANNECY MT - 22/09/98 {*/
fn_vAllocArrayOfElts3d (p_stEngineObject -> h_3dData , p_stCurrentAnim -> ucMaxNumberOfElements);
/*MMG_fn_vAddMemoryInfo( MMG_C_lTypeFamily , MMG_C_lSubTypeAnimation , p_stEngineObject->h_3dData->h_Family);*/
/*fn_p_st3dDataGetCurrentFrame(p_stEngineObject->h_3dData)->p_stArrayOfElts3d = (tdstElement3d*)TMP_M_p_Malloc(sizeof(tdstElement3d) * p_stCurrentAnim->ucMaxNumberOfElements);*/
fn_p_st3dDataGetCurrentFrame(p_stEngineObject->h_3dData)->p_stAnim = NULL;
/*memset(fn_p_st3dDataGetCurrentFrame(p_stEngineObject->h_3dData)->p_stArrayOfElts3d,0,sizeof(tdstElement3d) * p_stCurrentAnim->ucMaxNumberOfElements);*/
/* END ANNECY MT }*/
}
}
/* reinit anim reference to force interpolation to re-create frame*/
fn_p_st3dDataGetCurrentFrame(p_stEngineObject->h_3dData)->p_stAnim = NULL;
}
/* END ANNECY MT }*/
#ifdef GAM_USE_SNA
SNA_M_vUpdateOccurrenceToLoad();
#endif /* GAM_USE_SNA */
return(h_stSuperObject);
}
}
M_GameWarningError(E_uwGameAllocateAlwaysUnknownModel);
Erm_M_ClearLastError(C_ucErmDefaultChannel);
return(NULL);
}
/*-----------------------------------------------------------------------------
* Description : Destroy an allocated always
*-----------------------------------------------------------------------------
* Input : Rank in dynamic array
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 08/10/96 Author : Francois
*-----------------------------------------------------------------------------
* Modification date : 16/08/97 Modification Author : Gizmo
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vKillAlwaysByPersonalType(tdObjectType otPersonalType)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
HIE_tdxHandleToSuperObject h_SuperObject;
HIE_tdxHandleToSuperObject h_Child,h_NextChild;
tdstEngineObject *p_stEngineObject;
unsigned long ulRank;
unsigned long i;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef D_WANT_OPTIMIZE_MEMORY
g_lNbAllocatedAlways--;
#endif /* D_WANT_OPTIMIZE_MEMORY */
ulRank = otPersonalType - C_AlwaysObjectType;
SAF_M_AssertWithMsg ( ulRank >= 0 && ulRank < g_stAlways.ulMaxNumberOfAlways , "l'objet detruit n'est pas un always mais est considéré comme tel!" ) ;
h_SuperObject = HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,ulRank);
/* If this always a text, clear all datas of this text for TEXT_Affiche function*/
TFMT_ucClearNumberOfCurrentTextAffiche(h_SuperObject);
/* stop sounf for that always*/
SND_fn_vKillObjectSound2((long)h_SuperObject,g_lSoundObjectTypeAnim);
/* ANNECY AV DEMO {*/
#ifndef U64
#ifndef RETAIL
DEMO_fn_vSaveAlwaysActivationDesactivation(h_SuperObject,NULL,FALSE); /*save Kill of always*/
#endif /* RETAIL */
#endif
/* END ANNECY AV }*/
/* fn_vRemoveAllAnimLightsFromSectorList(h_SuperObject);*/
/*XB980824*/
#ifndef D_THROW_MGT
if( M_GetMSHandle( h_SuperObject, MSMagnet) ) MGT_fn_vDeleteObjectFromMagnetList(h_SuperObject);
#endif /* D_THROW_MGT */
/*End XB*/
p_stEngineObject = (tdstEngineObject *)HIE_fn_hGetSuperObjectObject(h_SuperObject);
#ifndef U64
if (M_ObjectGetModelType(p_stEngineObject)==C_InvalidObjectType)
M_GameInformationError(E_uwGameKillAlwaysByRankInvalidObject);
#endif
/*
* reset generator
*/
g_stAlways.d_hAlwaysGenerator[ ulRank ] = NULL;
/*
* Free the always object place
*/
fn_vRemoveObjectInSectorList(h_SuperObject);
M_ObjectSetFamilyType(p_stEngineObject,C_InvalidObjectType);
#ifndef U64
M_ObjectSetModelType(p_stEngineObject,C_InvalidObjectType);
#endif
M_ObjectSetPersonalType(p_stEngineObject,C_AlwaysObjectType);
/*
* Extract the super-object from the hiérarchie and reput these engine children at the world hierarchie's level
*/
/* destroy all active channels and SO*/
PLA_fn_vDesInitAllChildOfCharacter(h_SuperObject,(struct tdstEngineObject_*)HIE_fn_hGetSuperObjectObject(h_SuperObject));
fn_vFreeMorphList(&(p_stEngineObject->h_3dData->hMorphChannelList));
/* Anti-bug: Free dynamics*/
if( p_stEngineObject->h_Dynam )
fn_v_DynamicFree( p_stEngineObject->h_Dynam );
/* isolate the always*/
HIE_fn_vPseudoIsolate(h_SuperObject);
/* if it is a platform, put all its eventual sons as child of the world*/
if (fn_ucStandardGameGetPlatFormType(M_GetMSHandle(h_SuperObject,StandardGame)))
{
HIE_M_ForEachMovingChildOf(h_SuperObject,h_Child,h_NextChild,i)
{
ENGassert(HIE_fn_ulGetSuperObjectType(h_Child) == HIE_C_ulActor);
if (HIE_fn_ulGetSuperObjectType(h_Child)==HIE_C_ulActor)
fn_vReputCharacterSuperObjectAtTheWorld(h_Child);
}
}
if (HIE_fn_SO_bIsSuperimposed (h_SuperObject))
{
HIE_fn_SO_vClearSuperimposedFlag (h_SuperObject);
}
memset(p_stEngineObject,0,sizeof(struct tdstEngineObject_));
}
/*-----------------------------------------------------------------------------
* Description : Destroy all allocated always
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 08/10/96 Author : Francois
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vKillAllAlways()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
tdstEngineObject *p_stEngineObject;
HIE_tdxHandleToSuperObject hSO;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
for (i=0;i<g_stAlways.ulMaxNumberOfAlways;i++)
{
hSO = HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i);
if ( HIE_fn_SO_bIsSuperimposed( hSO ) )
{
HIE_fn_SO_vClearSuperimposedFlag( hSO );
/* when the object is removed from the second viewport, it reappears in the main character's current sector*/
fn_vSectInfoSetCurrentSector(
M_GetMSHandle(hSO,SectInfo),
fn_h_SectInfoGetCurrentSector(M_GetMSHandle(MC_fn_hGetCharacterInMainCharacterNode( MC_fn_hGetFirstMainCharNode()),SectInfo))
);
fn_vInsertObjectInSectorList(fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hSO,SectInfo)),hSO);
}
p_stEngineObject=(tdstEngineObject *)HIE_fn_hGetSuperObjectObject( hSO );
if (p_stEngineObject->h_StandardGame!=NULL)
fn_vKillAlwaysByPersonalType(M_ObjectGetPersonalType(p_stEngineObject));
}
}
/*-----------------------------------------------------------------------------
* Description : return the number of free always
*-----------------------------------------------------------------------------
* Input : void
* Output : long
*-----------------------------------------------------------------------------
* Creation date : 28/01/98 Author : Francois
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
unsigned long fn_ulGetNumberOfFreeAlways(void)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
unsigned long ulReturn = 0;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
for (i=0;i<g_stAlways.ulMaxNumberOfAlways;i++)
{
if (((tdstEngineObject *)HIE_fn_hGetSuperObjectObject(HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i)))->h_3dData==NULL)
ulReturn++;
}
return(ulReturn);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
/*-----------------------------------------------------------------------------
* Description : return the number of live always that belong to a given actor
*-----------------------------------------------------------------------------
* Input : actor superobject
* Output : long
*-----------------------------------------------------------------------------
* Creation date : 27/07/98 Author : Benoit Germain
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
unsigned long fn_ulGetNumberOfAlwaysBelongingToMe(HIE_tdxHandleToSuperObject _hGenerator)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
unsigned long ulReturn = 0;
tdstEngineObject *hAlwaysObject;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
for (i = 0 ; i < g_stAlways.ulMaxNumberOfAlways ; i ++)
{
hAlwaysObject = HIE_fn_hGetSuperObjectObject(HIE_fn_hGetElementFromSuperObjectTab(g_stAlways.d_stAlwaysSuperObject,i));
if
(
(hAlwaysObject != NULL)
&& (hAlwaysObject->h_3dData != NULL)
&& (g_stAlways.d_hAlwaysGenerator[i] == _hGenerator)
)
{
ulReturn ++;
}
}
return ulReturn;
}
/*-----------------------------------------------------------------------------
* Description : Allocate maximum size for Brain MiniStructure
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 07/07/97 Author : Olivier Jourdan
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vInitMindForAlways()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
unsigned long i;
unsigned long ulSizeMax=0;
unsigned long ulTmpSize;
AI_tdxHandleToMind hMind;
ALW_tdxHandleToModelList h_AlwaysModelChild;
tdstEngineObject *p_stTempEngineObject;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
LST2_M_DynamicForEachElementOf(&(g_stAlways.ALW_h_LstAlwaysModel),h_AlwaysModelChild,i)
{
p_stTempEngineObject = h_AlwaysModelChild->p_stAlwaysObject;
if( p_stTempEngineObject->h_Brain )
{
hMind = M_pstGetMindOfBrain(p_stTempEngineObject->h_Brain);
if( hMind )
{
ulTmpSize = fn_ulGetSizeOfMindWithoutAIModel( hMind );
if( ulTmpSize > ulSizeMax )
ulSizeMax = ulTmpSize;
}
}
}
if ( ulSizeMax ) /*allocate a mind only if needed!!!*/
{
for (i = 0; i < g_stAlways.ulMaxNumberOfAlways; i ++ )
{
p_stTempEngineObject=&g_stAlways.d_stAlwaysEngineObjectInit[i];
if( p_stTempEngineObject->h_Brain )
{
MMG_fn_vAddMemoryInfo( MMG_C_lTypeAI , MMG_C_lSubTypeMind , NULL );
hMind = (AI_tdxHandleToMind)M_p_GameMallocInHLM(ulSizeMax);
memset(hMind,i+1,ulSizeMax);
M_SetMindOfBrain(p_stTempEngineObject->h_Brain,hMind);
}
}
}
}
/*-----------------------------------------------------------------------------
* Description : Kill all desactivate always
*-----------------------------------------------------------------------------
* Input : void
* Output : void
*-----------------------------------------------------------------------------
* Creation date : 07/07/97 Author : Olivier Jourdan
*-----------------------------------------------------------------------------
* Modification date : Modification Author :
* Modifications :
*---------------------------------------------------------------------------*/
void fn_vKillAllAlwaysInNonActiveSectors()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
tdstEngineObject *p_stAlwaysEngObj;
HIE_tdxHandleToSuperObject *p_hGenerator;
HIE_tdxHandleToSuperObject *p_hLastGenerator;
HIE_tdxHandleToSuperObject hAlwaysSuperObject;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Init and do a loop on all always
*/
hAlwaysSuperObject = g_stAlways.d_stAlwaysSuperObject;
p_hGenerator = g_stAlways.d_hAlwaysGenerator;
p_hLastGenerator = p_hGenerator + g_stAlways.ulMaxNumberOfAlways;
for( ; p_hGenerator < p_hLastGenerator; hAlwaysSuperObject++, p_hGenerator++ )
{
/*
* Get the always engine object
*/
p_stAlwaysEngObj = (tdstEngineObject *) HIE_fn_hGetSuperObjectObject( hAlwaysSuperObject );
/*
* Test if always is actually used
* always is not more used if it is activable and not more active or
* if it depends on it's generator and this one is desactivate.
*/
if(
( p_stAlwaysEngObj->h_StandardGame )
&&
(
/*(M_ObjectIsActivable(p_stAlwaysEngObj) && !M_ObjectIsActive(p_stAlwaysEngObj))
||*/
( (fn_eStandardGameGetInitFlagWhenOutOfZone( p_stAlwaysEngObj->h_StandardGame ) == OI_WhenGeneratorIsDesactivated)
&& !M_ObjectIsActive( (tdstEngineObject *) HIE_fn_hGetSuperObjectObject( *p_hGenerator ) )
)
||
( (fn_ulStandardGameGetCustomBits( p_stAlwaysEngObj->h_StandardGame ) & GAM_C_CustBitDestroyWhenAnimEnded)
&& PLA_fn_bTestIfEndOfAction( hAlwaysSuperObject )
)
)
)
{
/* Object is not in a active sector*/
fn_vKillEngineObjectOrAlwaysByPointer(p_stAlwaysEngObj);
}
if (*p_hGenerator == NULL)
{
HIE_M_hNextChild(hAlwaysSuperObject) = NULL;
}
}
}
/*-----------------------------------------------------------------------------
* Description : Say if an always is generated by an object
*-----------------------------------------------------------------------------
* Input : always and generator
* Output : 0 if False, 1 otherwise
*-----------------------------------------------------------------------------
* Creation date : 29/05/98 Author : Vincent Lhullier
*---------------------------------------------------------------------------*/
unsigned char fn_ucIsAlwaysGeneratedByMe( HIE_tdxHandleToSuperObject _hAlways, HIE_tdxHandleToSuperObject _hGenerator )
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
tdstEngineObject *p_stEngineObject;
unsigned long ulRank;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
if
(
(_hGenerator == NULL)
|| (_hAlways == NULL)
|| (M_GetMSHandle( _hAlways, StandardGame) == NULL)
|| (( p_stEngineObject = (tdstEngineObject *)HIE_fn_hGetSuperObjectObject( _hAlways ) ) == NULL)
)
return 0;
ulRank = M_ObjectGetPersonalType(p_stEngineObject) - C_AlwaysObjectType;
SAF_M_AssertWithMsg ( ulRank >= 0 && ulRank < g_stAlways.ulMaxNumberOfAlways , "the tested object is not an always!" ) ;
return (unsigned char) ( g_stAlways.d_hAlwaysGenerator[ ulRank ] == _hGenerator );
}
#ifndef U64
/*-----------------------------------------------------------------------------
* Description :
*-----------------------------------------------------------------------------
* Input :
* Output :
*-----------------------------------------------------------------------------
* Creation date : 30/04/99 Author : Marc TRABUCATO
*---------------------------------------------------------------------------*/
void fn_vClearUnusedAlwaysInDemoMode()
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
tdstEngineObject *p_stAlwaysEngObj;
HIE_tdxHandleToSuperObject *p_hGenerator;
HIE_tdxHandleToSuperObject *p_hLastGenerator;
HIE_tdxHandleToSuperObject hAlwaysSuperObject;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*
* Init and do a loop on all always
*/
hAlwaysSuperObject = g_stAlways.d_stAlwaysSuperObject;
p_hGenerator = g_stAlways.d_hAlwaysGenerator;
p_hLastGenerator = p_hGenerator + g_stAlways.ulMaxNumberOfAlways;
for( ; p_hGenerator < p_hLastGenerator; hAlwaysSuperObject++, p_hGenerator++ )
{
/*
* Get the always engine object
*/
p_stAlwaysEngObj = (tdstEngineObject *) HIE_fn_hGetSuperObjectObject( hAlwaysSuperObject );
if (*p_hGenerator == NULL)
{
HIE_M_hNextChild(hAlwaysSuperObject) = NULL;
}
}
}
#endif