亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? spell.cpp

?? 3D游戲引擎 Programming Role-Playing Games with DirectX, 2nd Edition by Jim Adams
?? CPP
字號:
#include "Core_Global.h"
#include "Frustum.h"

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

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

cSpellController::cSpellController()
{
  m_Graphics       = NULL;  // Clear cGraphics pointer
  m_Frustum        = NULL;  // Clear frustum pointer

  m_Chars          = NULL;  // Clear character controller
  
  m_SpellParent    = NULL;

  m_NumMeshes      = 0;     // Clear mesh data
  m_Meshes         = NULL;
  m_TexturePath[0] = 0;
}

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

BOOL cSpellController::Init(cGraphics *Graphics,              \
          char *DefinitionFile,                               \
          long NumSpellMeshes, char **MeshNames,              \
          char *TexturePath,                                  \
          cCharacterController *Controller)
{
  FILE *fp;
  long i;

  Free();  // Free prior init

  // Get parent graphics object
  if((m_Graphics = Graphics) == NULL || MeshNames == NULL ||  \
     DefinitionFile == NULL)
    return FALSE;

  // Load the spells
  if((fp=fopen(DefinitionFile, "rb"))==NULL)
    return FALSE;
  for(i=0;i<NUM_SPELL_DEFINITIONS;i++)
    fread(&m_Spells[i], 1, sizeof(sSpell), fp);
  fclose(fp);

  m_Chars = Controller;  // Store controller pointer

  // Copy over texture name
  if(TexturePath != NULL)
    strcpy(m_TexturePath, TexturePath);

  // Get mesh names
  if((m_NumMeshes = NumSpellMeshes)) {
    m_Meshes = new sSpellMeshList[NumSpellMeshes]();
    for(i=0;i<m_NumMeshes;i++)
      strcpy(m_Meshes[i].Filename, MeshNames[i]);
  }

  return TRUE;
}

BOOL cSpellController::Shutdown()
{
  long i;

  Free();  // Free class data

  // Release spell meshes
  if(m_NumMeshes && m_Meshes != NULL) {
    for(i=0;i<m_NumMeshes;i++) {
      m_Meshes[i].Animation.Free();
      m_Meshes[i].Mesh.Free();
      m_Meshes[i].Count = 0;
    }
  }

  // Clear graphics object
  m_Graphics = NULL;

  // Release mesh list  
  delete [] m_Meshes;
  m_Meshes = NULL;
  m_NumMeshes = 0;

  return TRUE;
}

BOOL cSpellController::Free()
{
  // Release spell list
  delete m_SpellParent;
  m_SpellParent = NULL;

  return TRUE;
}

sSpell *cSpellController::GetSpell(long SpellNum)
{
  return &m_Spells[SpellNum];
}

BOOL cSpellController::Add(long SpellNum,                     \
             sCharacter *Caster, long TargetType,             \
             float SourceX, float SourceY, float SourceZ,     \
             float TargetX, float TargetY, float TargetZ)
{
  sSpellTracker *SpellPtr;

  // Error checking
  if(m_Graphics == NULL || m_Meshes == NULL)
    return FALSE;

  // Make sure character is allowed to cast spell
  if(Caster != NULL) {
    if(!(Caster->Def.MagicSpells[SpellNum/32] &               \
                                      (1 << (SpellNum & 31))))
      return FALSE;

    // Make sure caster has enough MP to cast and reduce MP
    if(Caster != NULL) {
      // Return if not enough mana
      if(Caster->ManaPoints < m_Spells[SpellNum].Cost)
        return FALSE;
    }
  }

  // Allocate a new structure and link in to head of list
  SpellPtr = new sSpellTracker();
  if(m_SpellParent != NULL)
    m_SpellParent->Prev = SpellPtr;
  SpellPtr->Next = m_SpellParent;
  m_SpellParent = SpellPtr;

  // Set structure data
  SpellPtr->SpellNum = SpellNum;
  SpellPtr->Caster   = Caster;
  SpellPtr->Type     = TargetType;
  SpellPtr->SourceX  = SourceX;
  SpellPtr->SourceY  = SourceY;
  SpellPtr->SourceZ  = SourceZ;
  SpellPtr->TargetX  = TargetX;
  SpellPtr->TargetY  = TargetY;
  SpellPtr->TargetZ  = TargetZ;

  // Setup the mesh and movement data
  SetAnimData(SpellPtr, 0);

  return TRUE;
}

BOOL cSpellController::Update(long Elapsed)
{
  sSpellTracker *SpellPtr, *NextSpell;
  long SpellNum, Anim;
  BOOL GotoNextAnim;
  float Speed;

  if((SpellPtr = m_SpellParent) == NULL)
    return FALSE;

  // Scan through all spells in use
  while(SpellPtr != NULL) {

    // Remember next spell in list
    NextSpell = SpellPtr->Next;

    // Get local data
    SpellNum = SpellPtr->SpellNum;
    Anim     = SpellPtr->CurrentAnimation;

    // Update/move/countdown spell object
    GotoNextAnim = FALSE;
    switch(m_Spells[SpellNum].MeshPos[Anim]) {
      case POSITION_NONE:
        // Go to next animation
        GotoNextAnim = TRUE;
        break;

      case POSITION_CASTER:
      case POSITION_TARGET:
      case POSITION_SCALE:
        SpellPtr->Time -= Elapsed;
        if(SpellPtr->Time <= 0)
          GotoNextAnim = TRUE;
        break;

      case POSITION_TOTARGET:
      case POSITION_TOCASTER:
        Speed = (float)Elapsed / 1000.0f * SpellPtr->Speed;

        // Decrease distance amount
        SpellPtr->Distance -= Speed;
        if(SpellPtr->Distance <= 0.0f)
          GotoNextAnim = TRUE;
        else {
          SpellPtr->XPos += (SpellPtr->XAdd * Speed);
          SpellPtr->YPos += (SpellPtr->YAdd * Speed);
          SpellPtr->ZPos += (SpellPtr->ZAdd * Speed);
        }
        break;
    }

    // Update to next animation
    if(GotoNextAnim == TRUE)
      SetAnimData(SpellPtr, Anim+1);
   
    // Go to next spell
    SpellPtr = NextSpell;
  }

  return TRUE;
}

BOOL cSpellController::SetAnimData(sSpellTracker *SpellPtr,   \
                                  long Num)
{
  float XDiff, YDiff, ZDiff, Dist, Length;
  float XAngle = 0.0f, YAngle = 0.0f;
  float Scale = 1.0f;
  long  i;
  long  SpellNum, MeshNum;
  float SourceX, SourceY, SourceZ;
  float TargetX, TargetY, TargetZ;

  // Process spell effect if no more animations left
  // while storing the current animation number.
  if((SpellPtr->CurrentAnimation = Num) >= 3) {
    if(m_Chars != NULL)
      m_Chars->Spell(SpellPtr->Caster, SpellPtr, m_Spells);

    // Remove any mesh references
    for(i=0;i<3;i++) {
      if(m_Spells[SpellPtr->SpellNum].MeshPos[i] !=           \
                                             POSITION_NONE) {
        MeshNum = m_Spells[SpellPtr->SpellNum].MeshNum[i];

        // Decrease count and remove if needed
        m_Meshes[MeshNum].Count--;
        if(!m_Meshes[MeshNum].Count) {
          m_Meshes[MeshNum].Mesh.Free();
          m_Meshes[MeshNum].Animation.Free();
        }
      }
    }

    // Remove spell from list
    if(SpellPtr->Prev != NULL)
      SpellPtr->Prev->Next = SpellPtr->Next;
    else
      m_SpellParent = SpellPtr->Next;
    if(SpellPtr->Next != NULL)
      SpellPtr->Next->Prev = SpellPtr->Prev;
    SpellPtr->Prev = SpellPtr->Next = NULL;
    delete SpellPtr;

    return TRUE;
  }

  // Setup local data
  SourceX  = SpellPtr->SourceX;
  SourceY  = SpellPtr->SourceY;
  SourceZ  = SpellPtr->SourceZ;
  TargetX  = SpellPtr->TargetX;
  TargetY  = SpellPtr->TargetY;
  TargetZ  = SpellPtr->TargetZ;
  SpellNum = SpellPtr->SpellNum;

  // Go to next animation if no mesh to use
  if(m_Spells[SpellNum].MeshPos[Num] == POSITION_NONE)
    return SetAnimData(SpellPtr,Num+1);

  // Get mesh # to use
  MeshNum = m_Spells[SpellNum].MeshNum[Num];

  // Load mesh and animation if needed
  if(!m_Meshes[MeshNum].Count) {
    m_Meshes[MeshNum].Mesh.Load(m_Graphics,                   \
                   m_Meshes[MeshNum].Filename,                \
                   m_TexturePath);
    m_Meshes[MeshNum].Animation.Load(                         \
                   m_Meshes[MeshNum].Filename,                \
                   &m_Meshes[MeshNum].Mesh);

    // Set animation loop
    m_Meshes[MeshNum].Animation.SetLoop(                      \
             m_Spells[SpellNum].MeshLoop[Num], "Anim");
  }

  // Configure graphics object
  SpellPtr->Object.Create(m_Graphics,&m_Meshes[MeshNum].Mesh);
  m_Meshes[MeshNum].Count++;

  // Setup mesh movements
  switch(m_Spells[SpellNum].MeshPos[Num]) {
    case POSITION_CASTER:
      SpellPtr->XPos = SourceX;
      SpellPtr->YPos = SourceY;
      SpellPtr->ZPos = SourceZ;
      SpellPtr->Time = (long)m_Spells[SpellNum].MeshSpeed[Num];

      if(SpellPtr->Caster != NULL)
        YAngle = SpellPtr->Caster->Direction;
      break;

    case POSITION_TOTARGET:
      // Store position and speed info
      SpellPtr->XPos  = SourceX;
      SpellPtr->YPos  = SourceY;
      SpellPtr->ZPos  = SourceZ;
      SpellPtr->Speed = m_Spells[SpellNum].MeshSpeed[Num];

      // Calculate movement
      XDiff = (float)fabs(TargetX - SourceX);
      YDiff = (float)fabs(TargetY - SourceY);
      ZDiff = (float)fabs(TargetZ - SourceZ);
      Dist  = (float)sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff);

      if((SpellPtr->Distance = Dist) != 0.0f) {
        SpellPtr->XAdd = (TargetX - SourceX) / Dist;
        SpellPtr->YAdd = (TargetY - SourceY) / Dist;
        SpellPtr->ZAdd = (TargetZ - SourceZ) / Dist;

        // Calculate angles
        XAngle = -(float)atan(SpellPtr->YAdd);
        YAngle =  (float)atan2(SpellPtr->XAdd, SpellPtr->ZAdd);
      }
      break;

    case POSITION_TARGET:
      SpellPtr->XPos = TargetX;
      SpellPtr->YPos = TargetY;
      SpellPtr->ZPos = TargetZ;
      SpellPtr->Time = (long)m_Spells[SpellNum].MeshSpeed[Num];

      // Calculate distance from source to target
      XDiff = (float)fabs(TargetX - SourceX);
      ZDiff = (float)fabs(TargetZ - SourceZ);
      Dist  = (float)sqrt(XDiff*XDiff+ZDiff*ZDiff);

      SpellPtr->XAdd = (TargetX - SourceX) / Dist;
      SpellPtr->ZAdd = (TargetZ - SourceZ) / Dist;

      // Calculate angle
      YAngle =  (float)atan2(SpellPtr->XAdd, SpellPtr->ZAdd);
      break;

    case POSITION_TOCASTER:
      // Store position and speed info
      SpellPtr->XPos  = TargetX;
      SpellPtr->YPos  = TargetY;
      SpellPtr->ZPos  = TargetZ;
      SpellPtr->Speed = m_Spells[SpellNum].MeshSpeed[Num];

      // Calculate movement
      XDiff = (float)fabs(SourceX - TargetX);
      YDiff = (float)fabs(SourceY - TargetY);
      ZDiff = (float)fabs(SourceZ - TargetZ);
      Dist  = (float)sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff);

      if((SpellPtr->Distance = Dist) != 0.0f) {
        SpellPtr->XAdd = (SourceX - TargetX) / Dist;
        SpellPtr->YAdd = (SourceY - TargetY) / Dist;
        SpellPtr->ZAdd = (SourceZ - TargetZ) / Dist;

        // Calculate angles
        XAngle = -(float)atan(SpellPtr->YAdd);
        YAngle =  (float)atan2(SpellPtr->XAdd, SpellPtr->ZAdd);
      }
      break;

    case POSITION_SCALE:
      // Store position and speed info
      SpellPtr->XPos  = SourceX;
      SpellPtr->YPos  = SourceY;
      SpellPtr->ZPos  = SourceZ;
      SpellPtr->Time = (long)m_Spells[SpellNum].MeshSpeed[Num];

      // Get distance from source to target and size of mesh
      XDiff = (float)fabs(TargetX - SourceX);
      YDiff = (float)fabs(TargetY - SourceY);
      ZDiff = (float)fabs(TargetZ - SourceZ);
      Dist  = (float)sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff);
      SpellPtr->Object.GetBounds(NULL,NULL,NULL,              \
                                 NULL,NULL,&Length,NULL);

      // Calculate scale
      Scale = Dist / Length;
      
      // Calculate angles
      SpellPtr->XAdd = (TargetX - SourceX) / Dist;
      SpellPtr->YAdd = (TargetY - SourceY) / Dist;
      SpellPtr->ZAdd = (TargetZ - SourceZ) / Dist;
      XAngle = -(float)atan(SpellPtr->YAdd);
      YAngle =  (float)atan2(SpellPtr->XAdd, SpellPtr->ZAdd);

      break;
  }

  // Rotate object to points towards target
  SpellPtr->Object.Rotate(XAngle, YAngle, 0.0f);

  // Scale object
  SpellPtr->Object.Scale(1.0f, 1.0f, Scale);

  // Set the animation
  SpellPtr->Object.SetAnimation(                              \
      &m_Meshes[MeshNum].Animation, "Anim", timeGetTime()/30);

  // Play the sound
  if(m_Spells[SpellNum].MeshSound[Num] != -1)
    SpellSound(m_Spells[SpellNum].MeshSound[Num]);

  return TRUE;
}

BOOL cSpellController::Render(cFrustum *Frustum,              \
                              float ZDistance)
{
  cFrustum    ViewFrustum;  // Local viewing frustum
  float       Radius;       // Bounding radius
  sSpellTracker *SpellPtr;
  DWORD       Time;

  // Error checking
  if(m_Graphics == NULL)
    return FALSE;

  // Return success if no character to draw
  if((SpellPtr = m_SpellParent) == NULL)
    return TRUE;

  // Construct the viewing frustum (if none passed)
  if((m_Frustum = Frustum) == NULL) {
    ViewFrustum.Construct(m_Graphics, ZDistance);
    m_Frustum = &ViewFrustum;
  }

  // Get time to update animations (30fps)
  Time = timeGetTime() / 30;

  // Loop through each spell and draw
  while(SpellPtr != NULL) {
    // Draw spell if in viewing frustum
    SpellPtr->Object.GetBounds(NULL,NULL,NULL,NULL,           \
                              NULL,NULL,&Radius);

    if(m_Frustum->CheckSphere(SpellPtr->XPos,                 \
                              SpellPtr->YPos,                 \
                              SpellPtr->ZPos,                 \
                              Radius) == TRUE) {

      // Position object
      SpellPtr->Object.Move(SpellPtr->XPos,                   \
                            SpellPtr->YPos,                   \
                            SpellPtr->ZPos);

      SpellPtr->Object.UpdateAnimation(Time, TRUE);
      SpellPtr->Object.Render();
    }

    // Go to next spell
    SpellPtr = SpellPtr->Next;
  }

  return TRUE;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色就色 综合激情| 国产精品麻豆视频| 国产精品国产三级国产aⅴ原创| 依依成人精品视频| 国产98色在线|日韩| 在线成人免费观看| 综合激情成人伊人| 国产成人啪午夜精品网站男同| 91福利精品第一导航| 国产精品网友自拍| 精品一区二区在线视频| 欧美日韩mp4| 亚洲精品国产无天堂网2021 | 亚洲免费av观看| 东方aⅴ免费观看久久av| 日韩欧美一区二区久久婷婷| 亚洲一二三四在线观看| 天堂久久久久va久久久久| 91在线视频免费观看| 中文字幕欧美激情一区| 国产乱码精品一区二区三区av| 日韩欧美色综合网站| 午夜欧美视频在线观看| 欧美日韩在线直播| 亚洲一区在线观看网站| 91福利精品视频| 亚洲一区二区三区四区在线免费观看| 不卡的av在线| 中文字幕一区二区三区精华液 | 成人影视亚洲图片在线| 久久久电影一区二区三区| 国产一区二区不卡老阿姨| 日韩女优av电影| 极品少妇xxxx精品少妇偷拍| 日韩欧美国产成人一区二区| 美女精品一区二区| 日韩欧美成人午夜| 韩国一区二区在线观看| 久久―日本道色综合久久| 国产呦精品一区二区三区网站| 久久蜜臀精品av| 粉嫩嫩av羞羞动漫久久久| 国产精品视频麻豆| 色又黄又爽网站www久久| 一区二区成人在线| 欧美浪妇xxxx高跟鞋交| 美女任你摸久久| 中文字幕欧美三区| 欧美无乱码久久久免费午夜一区| 午夜影院久久久| 精品av综合导航| aa级大片欧美| 日韩精品亚洲专区| 欧美r级电影在线观看| 丁香网亚洲国际| 亚洲国产日产av| 欧美成人一区二区三区在线观看| 国产999精品久久久久久| 亚洲精品大片www| 欧美成人在线直播| 一本色道久久综合亚洲91| 日韩av中文字幕一区二区三区| 久久久久久日产精品| 91片在线免费观看| 精品一区二区免费在线观看| 国产精品久久久久三级| 欧美一区午夜视频在线观看| 成人永久免费视频| 日日摸夜夜添夜夜添国产精品| 2021国产精品久久精品| 色综合久久久久| 精品一区二区三区在线播放视频 | 欧美私人免费视频| 国精产品一区一区三区mba视频| 日韩美女久久久| 日韩亚洲欧美高清| 91片在线免费观看| 国产综合色在线视频区| 亚洲一级二级在线| 国产精品九色蝌蚪自拍| 欧美不卡在线视频| 欧美日韩免费视频| 99热在这里有精品免费| 裸体歌舞表演一区二区| 亚洲免费观看高清完整版在线观看| 精品久久人人做人人爽| 欧美三区免费完整视频在线观看| 国产成人一级电影| 麻豆精品一区二区| 天堂一区二区在线免费观看| 亚洲三级视频在线观看| 久久久久久电影| 精品捆绑美女sm三区| 欧美精品第一页| 91久久免费观看| 成人av片在线观看| 国产成人精品亚洲午夜麻豆| 美脚の诱脚舐め脚责91| 视频一区在线视频| 亚洲国产视频a| 一区二区视频在线看| 成人免费在线视频| 国产精品毛片久久久久久| 久久精子c满五个校花| 精品黑人一区二区三区久久| 欧美一级高清片| 6080国产精品一区二区| 欧美日韩在线播放一区| 色综合色狠狠天天综合色| 99re热视频这里只精品| 97久久超碰国产精品电影| 99综合电影在线视频| 成人福利视频在线| av成人免费在线观看| 99re6这里只有精品视频在线观看| 国产91综合一区在线观看| 国产精品一区一区| www.亚洲色图.com| 97超碰欧美中文字幕| 色综合天天狠狠| 欧美日韩在线观看一区二区| 666欧美在线视频| 精品国产在天天线2019| 国产亚洲欧美日韩日本| 国产精品久久久爽爽爽麻豆色哟哟| 国产精品无人区| 亚洲精品高清在线| 日日夜夜免费精品| 国产精品影视在线观看| 成人精品视频一区| 在线看一区二区| 欧美精品九九99久久| 精品久久久久久久久久久院品网 | 亚洲成人av免费| 黑人巨大精品欧美一区| 丁香五精品蜜臀久久久久99网站 | 91网站在线播放| 精品视频1区2区3区| 欧美成人官网二区| 国产精品久久久久天堂| 亚洲一级片在线观看| 久久99久久精品欧美| 成人av网址在线| 51精品视频一区二区三区| 国产人久久人人人人爽| 亚洲精品免费在线| 蓝色福利精品导航| 97精品久久久久中文字幕 | 亚洲欧美日本韩国| 午夜伦理一区二区| 国产福利91精品一区二区三区| 99久久免费精品| 日韩精品中文字幕一区二区三区| 精品成人免费观看| 亚洲国产cao| 成人午夜伦理影院| 69堂成人精品免费视频| 中文字幕一区不卡| 麻豆精品国产91久久久久久| 不卡的电影网站| 欧美mv和日韩mv的网站| 亚洲精品国产成人久久av盗摄| 久久精品国产99久久6| 91视频xxxx| 国产情人综合久久777777| 亚洲国产精品一区二区尤物区| 国产成人精品一区二区三区四区 | 日本欧美一区二区| av亚洲精华国产精华精华| 欧美大胆人体bbbb| 亚洲成人av在线电影| 91蝌蚪porny| 国产欧美一区二区精品性色超碰| 偷拍自拍另类欧美| 94-欧美-setu| 久久九九国产精品| 精品影视av免费| 777欧美精品| 亚洲地区一二三色| 成人av在线播放网址| 国产午夜三级一区二区三| 日韩va亚洲va欧美va久久| 日本福利一区二区| 国产精品久久久一本精品 | 在线观看国产精品网站| 欧美国产1区2区| 国产乱子伦视频一区二区三区| 欧美久久久久久久久| 一区二区三区四区蜜桃 | 亚洲精品久久久蜜桃| 91在线观看地址| 国产精品视频一二三区 | 国产精品一区二区免费不卡| 3atv在线一区二区三区| 亚洲图片一区二区| 欧美性色欧美a在线播放| 一区二区三区小说| 欧美亚洲一区二区三区四区| 亚洲免费毛片网站| 欧美性受极品xxxx喷水|