⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chars.cpp

📁 这是一个服务端/客户端模式的小型网络游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "Core_Global.h"
#include "Frustum.h"

#include "MCL.h"
#include "MIL.h"
#include "MSL.h"

#include "Chars.h"
#include "Spell.h"

cCharacterController::cCharacterController()
{
	m_Graphics          = NULL;  // Clear cGraphics pointer
	m_Font              = NULL;  // Clear cFont pointer
	m_Frustum           = NULL;  // Clear frustum pointer
	
	m_MIL               = NULL;  // Clear MIL pointer
	m_MSL               = NULL;  // Clear MSL pointer
	
	m_CharacterParent   = NULL;  // Clear character list
	m_NumCharacters     = 0;
	
	m_DefinitionFile[0] = 0;     // Clear definition filename
	
	m_NumMeshes         = 0;     // Clear mesh data
	m_Meshes            = NULL;
	m_TexturePath[0]    = 0;
	
	m_NumAnimations     = 0;     // Clear animation data
	m_Animations        = NULL;
	
	m_SpellController   = NULL;  // Clear spell controller
	Latency			  = 0;
	// Create a critical section for updating data
	InitializeCriticalSection(&m_UpdateCS);
}

cCharacterController::~cCharacterController()
{
	Shutdown();
}

BOOL cCharacterController::Init(                              \
								cGraphics *Graphics,                \
								cFont *Font, char *DefinitionFile,  \
								sItem *MIL, sSpell *MSL,            \
								long NumCharacterMeshes,            \
								char **MeshNames,                   \
								char *MeshPath, char *TexturePath,  \
								long NumAnimations,                 \
								sCharAnimationInfo *Anims,          \
								cSpellController *SpellController)
{
	long i;
	
	Free();  // Free prior init
	
	// Get parent graphics object and error checking
	if((m_Graphics = Graphics) == NULL || MeshNames == NULL ||  \
		DefinitionFile == NULL)
		return FALSE;
	
	// Get font object pointer
	m_Font = Font;
	
	// Copy definition file name
	strcpy(m_DefinitionFile, DefinitionFile);
	
	// Store MIL and MSL pointer
	m_MIL = MIL;
	m_MSL = MSL;
	
	// Copy over mesh path (or set default)
	if(MeshPath != NULL)
		strcpy(m_MeshPath, MeshPath);
	else
		strcpy(m_MeshPath, ".\\");
	
	// Copy over texture path (or set default)
	if(TexturePath != NULL)
		strcpy(m_TexturePath, TexturePath);
	else
		strcpy(m_TexturePath, ".\\");
	
	// Get mesh names
	if((m_NumMeshes = NumCharacterMeshes)) {
		m_Meshes = new sCharacterMeshList[NumCharacterMeshes]();
		for(i=0;i<m_NumMeshes;i++)
			strcpy(m_Meshes[i].Filename, MeshNames[i]);
	}
	
	// Get animation data
	if((m_NumAnimations = NumAnimations)) {
		m_Animations = new sCharAnimationInfo[m_NumAnimations]();
		for(i=0;i<m_NumAnimations;i++) {
			memcpy(&m_Animations[i], &Anims[i],                     \
				sizeof(sCharAnimationInfo));
		}
	}
	
	// Store spell controller pointer
	m_SpellController = SpellController;
	
	return TRUE;
}

BOOL cCharacterController::Shutdown()
{
	Free();
	
	// Release mesh list
	delete [] m_Meshes;
	m_Meshes = NULL;
	m_NumMeshes = 0;
	
	// Release animation data
	m_NumAnimations = 0;
	delete [] m_Animations;
	m_Animations = NULL;
	
	// Clear graphics object
	m_Graphics = NULL;
	
	// Clear paths
	m_DefinitionFile[0] = 0;
	m_MeshPath[0] = 0;
	m_TexturePath[0] = 0;
	
	// Clear spell controller
	m_SpellController = NULL;
	// Remove critical section
	DeleteCriticalSection(&m_UpdateCS);
	return TRUE;
}

BOOL cCharacterController::Free()
{
	// Release character structures
	delete m_CharacterParent;
	m_CharacterParent = NULL;
	m_NumCharacters = 0;
	
	return TRUE;
}

BOOL cCharacterController::Add(                               \
							   long IDNum, long dpnidPlayer, long Definition,                     \
							   long Type, long AI,                              \
							   float XPos, float YPos, float ZPos,              \
							   float Direction, long Action, char *Name)
{
	sCharacter *CharPtr;
	FILE *fp;
	char Path[MAX_PATH];
	long i;
	
	// Error checking
	if(m_Graphics==NULL || m_Meshes==NULL || !m_DefinitionFile[0])
		return FALSE;
	
	// Allocate a new structure
	CharPtr = new sCharacter();
	
    // Start the critical section
	// Assign data
	CharPtr->Definition = Definition;
	CharPtr->ID         = IDNum;
	CharPtr->dpnidPlayer=	dpnidPlayer;
	CharPtr->Type       = Type;
	CharPtr->AI         = AI;
	CharPtr->XPos       = XPos;
	CharPtr->YPos       = YPos;
	CharPtr->ZPos       = ZPos;
	CharPtr->Direction  = Direction;
	CharPtr->Enabled    = TRUE;
	CharPtr->Time		  = timeGetTime();
	
	if(Action == CHAR_MOVE) CharPtr->Action = CHAR_MOVE;
	else if(Action == CHAR_DIE) SetAction(CharPtr, Action, 2000);
	else CharPtr->Action = CHAR_IDLE;

	// Create a critical section for updating data
	InitializeCriticalSection(&CharPtr->m_UpdateCS);
	
	// Set a random charge amount
	CharPtr->Charge = (float)(rand() % 101);

    sprintf(Path, "Save\\%s.dat", Name);
	if(!Load(CharPtr, Path)){
		// Load character definition
		if((fp=fopen(m_DefinitionFile, "rb"))==NULL) {
			delete CharPtr;
			return FALSE;
		}
		fseek(fp, sizeof(sCharacterDefinition)*Definition, SEEK_SET);
		fread(&CharPtr->Def, 1, sizeof(sCharacterDefinition), fp);
		fclose(fp);
		strcpy(CharPtr->Def.Name, Name);
		// Set character stats
		CharPtr->HealthPoints = CharPtr->Def.HealthPoints;
		CharPtr->ManaPoints   = CharPtr->Def.ManaPoints;
	}	
	
	
	// Load character ICS
	if(IDNum == 0 ) {
		CharPtr->CharICS = new cCharICS();
		sprintf(Path, "Save\\ICS%s.dat", CharPtr->Def.Name);
		if(!CharPtr->CharICS->Load(Path)){
			sprintf(Path, "..\\Data\\%s", CharPtr->Def.ItemFilename);
			CharPtr->CharICS->Load(Path);
		}
	}
	// Load mesh and animation if needed
	if(!m_Meshes[CharPtr->Def.MeshNum].Count) {
		
		m_Meshes[CharPtr->Def.MeshNum].Mesh.Load(m_Graphics,      \
			m_Meshes[CharPtr->Def.MeshNum].Filename,   \
			m_TexturePath);
		
		m_Meshes[CharPtr->Def.MeshNum].Animation.Load(            \
			m_Meshes[CharPtr->Def.MeshNum].Filename,   \
			&m_Meshes[CharPtr->Def.MeshNum].Mesh);
		
		// Set animation loops
		if(m_NumAnimations) {
			for(i=0;i<m_NumAnimations;i++)
				m_Meshes[CharPtr->Def.MeshNum].Animation.SetLoop(     \
				m_Animations[i].Loop,   \
				m_Animations[i].Name);
			
		}
	}
	
	// Configure graphics object
	CharPtr->Object.Create(m_Graphics,                          \
		&m_Meshes[CharPtr->Def.MeshNum].Mesh);
	m_Meshes[CharPtr->Def.MeshNum].Count++;
	
	// Load and configure weapon (if any)
	if(m_MIL != NULL && CharPtr->Def.Weapon != -1 &&            \
		m_MIL[CharPtr->Def.Weapon].MeshFilename[0]) {
		
		// Build the mesh path
		sprintf(Path, "%s%s", m_MeshPath,                         \
            m_MIL[CharPtr->Def.Weapon].MeshFilename);
		
		// Load the weapon mesh
		CharPtr->WeaponMesh.Load(m_Graphics, Path, m_TexturePath);
		
		// Create the weapon object
		CharPtr->WeaponObject.Create(m_Graphics,                  \
			&CharPtr->WeaponMesh);
		
		// Orient and attach the weapon
		CharPtr->WeaponObject.Move(0.0f, 0.0f, 0.0f);
		CharPtr->WeaponObject.Rotate(0.0f, 0.0f, 0.0f);
		CharPtr->WeaponObject.AttachToObject(&CharPtr->Object,    \
			"WeaponHand");
		
	}  

	// Link in to head of list
	if(m_CharacterParent != NULL)
		m_CharacterParent->Prev = CharPtr;
	CharPtr->Next = m_CharacterParent;
	m_CharacterParent = CharPtr;
	
	if(IDNum == 1 || IDNum == 3){
		sprintf(Path, "..\\Data\\c%ld.mls", IDNum);
		SetScript(IDNum, Path);
	}

	return TRUE;
}

BOOL cCharacterController::Remove(long IDNum)
{
	return Remove(GetCharacter(IDNum));
}

BOOL cCharacterController::Remove(sCharacter *Character)
{
	// Error checking
	if(Character == NULL)
		return FALSE;
	
	// Decrease mesh count and release if no more
	m_Meshes[Character->Def.MeshNum].Count--;
	if(!m_Meshes[Character->Def.MeshNum].Count) {
		m_Meshes[Character->Def.MeshNum].Mesh.Free();
		m_Meshes[Character->Def.MeshNum].Animation.Free();
	}
	
	// Remove from list and free resource
	if(Character->Prev != NULL)
		Character->Prev->Next = Character->Next;
	else
		m_CharacterParent = Character->Next;
	
	if(Character->Next != NULL)
		Character->Next->Prev = Character->Prev;
	
	if(Character->Prev == NULL && Character->Next == NULL)
		m_CharacterParent = NULL;
	
	Character->Prev = Character->Next = NULL;
	delete Character;
	
	return TRUE;
}

BOOL cCharacterController::Save(long IDNum, char *Filename)
{
	char FilenameBuf[MAX_PATH];
	sCharacter *CharPtr;
	FILE *fp;
	
	// Get pointer to character in list
	if((CharPtr = GetCharacter(IDNum)) == NULL)
		return FALSE;
	
	// Open file
	sprintf(FilenameBuf, "Save\\%s.dat", Filename);
	if((fp=fopen(FilenameBuf, "wb"))==NULL)
		if((fp=fopen(FilenameBuf, "wb+"))==NULL)
			return FALSE;
		
		// Output character data
		fwrite(&CharPtr->Def, 1, sizeof(sCharacterDefinition), fp);
		fwrite(&CharPtr->HealthPoints, 1, sizeof(long), fp);
		fwrite(&CharPtr->ManaPoints, 1, sizeof(long), fp);
		fwrite(&CharPtr->Enabled, 1, sizeof(BOOL), fp);
		fwrite(&CharPtr->XPos, 1, sizeof(float), fp);
		fwrite(&CharPtr->YPos, 1, sizeof(float), fp);
		fwrite(&CharPtr->ZPos, 1, sizeof(float), fp);
		fwrite(&CharPtr->Direction, 1, sizeof(float), fp);
		
		// Close file
		fclose(fp);
		
		// Save inventory
		if(CharPtr->CharICS != NULL) {
			sprintf(FilenameBuf, "Save\\ICS%s", Filename);
			CharPtr->CharICS->Save(FilenameBuf);
		}
		
		return TRUE;
}

BOOL cCharacterController::Load(sCharacter *CharPtr, char *Filename)
{
	char ICSFilename[MAX_PATH];
	FILE *fp;
	
	if(CharPtr == NULL) return FALSE;
	
	// Open file
	if((fp=fopen(Filename, "rb"))==NULL)
		return FALSE;
	
	// Output character data
	fread(&CharPtr->Def, 1, sizeof(sCharacterDefinition), fp);
	//fread(&CharPtr->Name, 1, 64, fp);
	fread(&CharPtr->HealthPoints, 1, sizeof(long), fp);
	fread(&CharPtr->ManaPoints, 1, sizeof(long), fp);
	fread(&CharPtr->Enabled, 1, sizeof(BOOL), fp);
	fread(&CharPtr->XPos, 1, sizeof(float), fp);
	fread(&CharPtr->YPos, 1, sizeof(float), fp);
	fread(&CharPtr->ZPos, 1, sizeof(float), fp);
	fread(&CharPtr->Direction, 1, sizeof(float), fp);
	
	// Close file
	fclose(fp);
	
	// Load inventory
	if(CharPtr->CharICS != NULL) {
		sprintf(ICSFilename, "Save\\ICS%s", Filename);
		CharPtr->CharICS->Load(ICSFilename);
	}
	
	return TRUE;
}

BOOL cCharacterController::Update()
{
	sCharacter *CharPtr, *NextChar;
	float XMove, YMove, ZMove;
	BOOL ToProcess, DeadChar;
	
	// Return success if no characters to update
	if((CharPtr = m_CharacterParent) == NULL)
		return TRUE;
	
	// Loop through all characters
	while(CharPtr != NULL) {
		
		if(!CharPtr->m_Messages.empty()){
			sMessage pm;
			sStateChangeProcMessage *scpm;
			sSpellChangeProcMessage *spcpm;
			sRoutineChangeProcMessage *rcpm;
			sAttackChangeProcMessage *acpm;
			sTimeMessage *tm;
			// Enter critical section
			EnterCriticalSection(&CharPtr->m_UpdateCS);
			pm = CharPtr->m_Messages.front();		
			// Leave critical section
			LeaveCriticalSection(&CharPtr->m_UpdateCS);
			if(pm.Header.Type == MSG_ROUTINE_CHANGE){
				rcpm = (sRoutineChangeProcMessage *)&pm;
				CharPtr->XPos      = rcpm->XPos;
				CharPtr->YPos      = rcpm->YPos;
				CharPtr->ZPos      = rcpm->ZPos;
				CharPtr->Direction = rcpm->Direction;
				// Enter critical section
				EnterCriticalSection(&CharPtr->m_UpdateCS);
				CharPtr->m_Messages.pop_front();
				// Leave critical section
				LeaveCriticalSection(&CharPtr->m_UpdateCS);
				CharPtr->Elapsed = timeGetTime() - CharPtr->Time;
			} 
			else if(CharPtr->ActionTimer<=0){
				tm = (sTimeMessage *)&pm;
				
				if(tm->Time > CharPtr->Time){
					// Get elapsed time from now and state time
					CharPtr->Elapsed = timeGetTime() - CharPtr->Time;
				}
				else {
					// Get elapsed time from now and state time
					CharPtr->Elapsed = timeGetTime() - tm->Time;
				}
				
				switch( pm.Header.Type){
				case MSG_STATE_CHANGE:
					scpm = (sStateChangeProcMessage *)&pm;
					
					if(scpm->Action == CHAR_HURT ){
						SetAction(CharPtr, scpm->Action);
					}
					else if(scpm->Action == CHAR_DIE){
						SetAction(CharPtr, scpm->Action, 2000);
						CharPtr->Attacker = GetCharacter(scpm->AttackerID);
					}
					else if(scpm->Action == CHAR_IDLE) CharPtr->Action    = scpm->Action;
					else if(scpm->Action == CHAR_MOVE){
						CharPtr->Action    = scpm->Action;
						CharPtr->Direction = scpm->Direction;
					}
					
					break;
				case MSG_ROUTINE_CHANGE: 
					break;
					
				case MSG_SPELL_CHANGE:
					spcpm = (sSpellChangeProcMessage *)&pm;
					
					CharPtr->SpellNum      = spcpm->SpellNum;
					CharPtr->SpellTarget      = spcpm->SpellTarget;
					CharPtr->TargetX = spcpm->TargetX;
					CharPtr->TargetY   = spcpm->TargetY;
					CharPtr->TargetZ   = spcpm->TargetZ;
					CharPtr->Charge = 100.0f;
					SetAction(CharPtr, CHAR_SPELL);
					
					break;
				case MSG_ATTACK_CHANGE:
					acpm =(sAttackChangeProcMessage *)&pm;
					CharPtr->Victim      = GetCharacter(acpm->VictimID);
					CharPtr->Charge = 100.0f;
					
					SetAction(CharPtr, CHAR_ATTACK);
					break;
				}
				// Enter critical section
				EnterCriticalSection(&CharPtr->m_UpdateCS);
				CharPtr->m_Messages.pop_front();
				// Leave critical section
				LeaveCriticalSection(&CharPtr->m_UpdateCS);
			}
			else {
				if(CharPtr->ActionTimer>=timeGetTime() - CharPtr->Time)
					CharPtr->Elapsed = CharPtr->ActionTimer;
				else CharPtr->Elapsed = timeGetTime() - CharPtr->Time;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -