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

📄 chars.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#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
}

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();
  m_Graphics = NULL;

  return TRUE;
}

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

  // 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 paths
  m_DefinitionFile[0] = 0;
  m_MeshPath[0] = 0;
  m_TexturePath[0] = 0;

  // Clear spell controller
  m_SpellController = NULL;

  return TRUE;
}

BOOL cCharacterController::Add(                               \
             long IDNum, long Definition,                     \
             long Type, long AI,                              \
             float XPos, float YPos, float ZPos,              \
             float Direction)
{
  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();

  // Assign data
  CharPtr->Definition = Definition;
  CharPtr->ID         = IDNum;
  CharPtr->Type       = Type;
  CharPtr->AI         = AI;
  CharPtr->XPos       = XPos;
  CharPtr->YPos       = YPos;
  CharPtr->ZPos       = ZPos;
  CharPtr->Direction  = Direction;
  CharPtr->Enabled    = TRUE;

  // Set a random charge amount
  CharPtr->Charge = (float)(rand() % 101);

  // 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);

  // Load character ICS
  if(CharPtr->Def.ItemFilename[0]) {
    CharPtr->CharICS = new cCharICS();
    CharPtr->CharICS->Load(CharPtr->Def.ItemFilename);
  }

  // Set character stats
  CharPtr->HealthPoints = CharPtr->Def.HealthPoints;
  CharPtr->ManaPoints   = CharPtr->Def.ManaPoints;

  // 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;

  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 ICSFilename[MAX_PATH];
  sCharacter *CharPtr;
  FILE *fp;

  // Get pointer to character in list
  if((CharPtr = GetCharacter(IDNum)) == NULL)
    return FALSE;

  // Open file
  if((fp=fopen(Filename, "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->Ailments, 1, sizeof(long), 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(ICSFilename, "ICS%s", Filename);
    CharPtr->CharICS->Save(ICSFilename);
  }

  return TRUE;
}

BOOL cCharacterController::Load(long IDNum, char *Filename)
{
  char ICSFilename[MAX_PATH];
  sCharacter *CharPtr;
  FILE *fp;

  // Get pointer to character in list
  if((CharPtr = GetCharacter(IDNum)) == NULL)
    return FALSE;

  // Open file
  if((fp=fopen(Filename, "rb"))==NULL)
    return FALSE;

  // Read in character data
  fread(&CharPtr->Def, 1, sizeof(sCharacterDefinition), fp);
  fread(&CharPtr->HealthPoints, 1, sizeof(long), fp);
  fread(&CharPtr->ManaPoints, 1, sizeof(long), fp);
  fread(&CharPtr->Ailments, 1, sizeof(long), 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, "ICS%s", Filename);
    CharPtr->CharICS->Load(ICSFilename);
  }

  return TRUE;
}

BOOL cCharacterController::Update(long Elapsed)
{
  sCharacter *CharPtr, *NextChar;
  float XMove, YMove, ZMove;
  static long EffectCounter = 0;
  BOOL ToProcess, DeadChar;

  // Return success if no characters to update
  if((CharPtr = m_CharacterParent) == NULL)
    return TRUE;

  // Update effect counter
  EffectCounter += Elapsed;

  // Loop through all characters
  while(CharPtr != NULL) {

    // Remember next character
    NextChar = CharPtr->Next;

    // Only update if enabled, not asleep or paralyzed
    if(CharPtr->Enabled == TRUE) {

      // Update action timer if in use
      if(CharPtr->ActionTimer != 0) {
        CharPtr->ActionTimer -= Elapsed;
        if(CharPtr->ActionTimer < 0)
          CharPtr->ActionTimer = 0;
      }

      // Update text message timer
      if(CharPtr->MessageTimer > 0)
        CharPtr->MessageTimer -= Elapsed;

      // Reset charge counter if attacking, spell, or item
      if(CharPtr->Action == CHAR_ATTACK ||                    \
         CharPtr->Action == CHAR_SPELL  ||                    \
         CharPtr->Action == CHAR_ITEM)
        CharPtr->Charge = 0.0f;

      // Kill character if no health left
      if(CharPtr->HealthPoints <= 0 &&                        \
         CharPtr->Action != CHAR_DIE) {
        SetAction(CharPtr, CHAR_DIE, 2000);
      }

      // Mark that processing can continue later on
      ToProcess = TRUE;

      // Mark character as still alive
      DeadChar = FALSE;

      // Don't allow an update if asleep or paralyzed
      if((CharPtr->Ailments & AILMENT_SLEEP) ||               \
         (CharPtr->Ailments & AILMENT_PARALYZE))
        ToProcess = FALSE;
       
      // Process non-idle, non-walk actions
      if(CharPtr->Action != CHAR_IDLE &&                      \
         CharPtr->Action != CHAR_MOVE &&                      \
         !CharPtr->ActionTimer) {
         
        switch(CharPtr->Action) {
          case CHAR_ATTACK:
            // Process attack
            if(ToProcess == TRUE)
              Attack(CharPtr, CharPtr->Victim);
            break;

          case CHAR_SPELL:
            // Manually cast a spell
            if(m_SpellController != NULL && m_MSL != NULL &&  \
               ToProcess == TRUE) {
              m_SpellController->Add(CharPtr->SpellNum,       \
                           CharPtr, CharPtr->SpellTarget,     \
                           CharPtr->XPos,                     \
                           CharPtr->YPos,                     \
                           CharPtr->ZPos,                     \
                           CharPtr->TargetX,                  \
                           CharPtr->TargetY,                  \
                           CharPtr->TargetZ);
            }
            break;

          case CHAR_ITEM:

⌨️ 快捷键说明

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