📄 chars.cpp
字号:
}
} else {
CharPtr->Elapsed = timeGetTime() - CharPtr->Time;
}
// 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 -= CharPtr->Elapsed;
if(CharPtr->ActionTimer < 0)
CharPtr->ActionTimer = 0;
}
// Update text message timer
if(CharPtr->MessageTimer > 0)
CharPtr->MessageTimer -= CharPtr->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;
// Mark that processing can continue later on
ToProcess = TRUE;
// Mark character as still alive
DeadChar = FALSE;
// Process non-idle, non-walk actions
if(CharPtr->Action != CHAR_IDLE && \
CharPtr->Action != CHAR_MOVE && \
!CharPtr->ActionTimer) {
switch(CharPtr->Action) {
case CHAR_ATTACK:
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:
if(ToProcess == TRUE)
Item(CharPtr, CharPtr, \
CharPtr->ItemNum, CharPtr->CharItem);
break;
case CHAR_DIE:
Death(CharPtr->Attacker, CharPtr);
DeadChar = TRUE; // Mark character as dead
ToProcess = FALSE; // Don't allow updates
break;
}
}
// Clear movement
XMove = YMove = ZMove = 0.0f;
// Only continue if allowed (in case character died)
if(ToProcess == TRUE) {
// Only allow updates if lock/timer not in use
if(CharPtr->Enabled == TRUE && \
!CharPtr->ActionTimer && \
CharPtr->Locked == FALSE) {
// Reset action
if(CharPtr->Action != CHAR_MOVE)
CharPtr->Action = CHAR_IDLE;
// Get movement
if(CharPtr->Type == CHAR_PC){
PCUpdate(CharPtr, CharPtr->Elapsed, &XMove, &YMove, &ZMove);
}
else
CharUpdate(CharPtr, CharPtr->Elapsed, &XMove,&YMove,&ZMove);
// Check for validity of movement (clear if invalid)
if(CheckMove(CharPtr,&XMove,&YMove,&ZMove)==FALSE) {
XMove = YMove = ZMove = 0.0f;
if(CharPtr->Type == CHAR_PC)
CharPtr->Action = CHAR_IDLE;
}
}
// Process movement of character
ProcessUpdate(CharPtr, XMove, YMove, ZMove);
// Increase action charge of character
CharPtr->Charge += ((float)CharPtr->Elapsed / 1000.0f * \
GetCharge(CharPtr));
if(CharPtr->Charge > 100.0f)
CharPtr->Charge = 100.0f;
}
}
CharPtr->Time = timeGetTime();
// Go to next character
CharPtr = NextChar;
}
return TRUE;
}
BOOL cCharacterController::Render( \
cFrustum *Frustum, \
float ZDistance)
{
cFrustum ViewFrustum; // Local viewing frustum
float Radius; // Bounding radius
sCharacter *CharPtr;
DWORD Time;
// Variables for printing messages
BOOL GotMatrices = FALSE;
D3DXMATRIX matWorld, matView, matProj;
D3DXVECTOR3 vecPos;
D3DVIEWPORT8 vpScreen;
float MaxY;
// Error checking
if(m_Graphics == NULL)
return FALSE;
// Return success if no character to draw
if((CharPtr = m_CharacterParent) == NULL)
return TRUE;
// Construct the viewing frustum (if none passed)
if((m_Frustum = Frustum) == NULL) {
ViewFrustum.Construct(m_Graphics, ZDistance);
m_Frustum = &ViewFrustum;
}
// Loop through each character and draw
while(CharPtr != NULL) {
// Update animation based on elapsed time passed
CharPtr->LastAnimTime += (CharPtr->Elapsed/30);
Time = CharPtr->LastAnimTime;
CharPtr->Object.GetBounds(NULL,NULL,NULL, \
NULL,&MaxY,NULL,&Radius);
// Draw character if in viewing frustum
if(m_Frustum->CheckSphere(CharPtr->Object.GetXPos(), \
CharPtr->Object.GetYPos(), \
CharPtr->Object.GetZPos(), \
Radius) == TRUE) {
CharPtr->Object.UpdateAnimation(Time, TRUE);
CharPtr->Object.Render();
// Draw character's weapon
if(CharPtr->Def.Weapon != -1)
CharPtr->WeaponObject.Render();
// Get the matrices and viewport if not done already
if(GotMatrices == FALSE) {
GotMatrices = TRUE;
// Get the world, projection, and view transformations
D3DXMatrixIdentity(&matWorld);
m_Graphics->GetDeviceCOM()->GetTransform( \
D3DTS_VIEW, &matView);
m_Graphics->GetDeviceCOM()->GetTransform( \
D3DTS_PROJECTION, &matProj);
// Get viewport
m_Graphics->GetDeviceCOM()->GetViewport(&vpScreen);
}
// Project coordinates to screen
D3DXVec3Project(&vecPos, \
&D3DXVECTOR3(CharPtr->XPos, \
CharPtr->YPos + MaxY, \
CharPtr->ZPos), \
&vpScreen, &matProj, &matView, &matWorld);
// Print message
m_Font->Print(CharPtr->Def.Name, \
(long)vecPos.x, (long)vecPos.y);
// Draw message if needed
if(CharPtr->MessageTimer > 0) {
// Project coordinates to screen
D3DXVec3Project(&vecPos, \
&D3DXVECTOR3(CharPtr->XPos, \
CharPtr->YPos+(MaxY*0.5f), \
CharPtr->ZPos), \
&vpScreen, &matProj, &matView, &matWorld);
// Print message
m_Font->Print(CharPtr->Message, \
(long)vecPos.x, (long)vecPos.y, \
0, 0, CharPtr->MessageColor);
}
}
// go to next character
CharPtr = CharPtr->Next;
}
return TRUE;
}
float cCharacterController::GetXZRadius(sCharacter *Character)
{
float MinX, MaxX, MinZ, MaxZ;
float x, z;
// Error checking
if(Character == NULL)
return 0.0f;
Character->Object.GetBounds(&MinX, NULL, &MinZ, \
&MaxX, NULL, &MaxZ, NULL);
x = (float)max(fabs(MinX), fabs(MaxX));
z = (float)max(fabs(MinZ), fabs(MaxZ));
return max(x, z);
}
///////////////////////////////////////////////////////////
// Set/Get Functions
///////////////////////////////////////////////////////////
sCharacter *cCharacterController::GetParentCharacter()
{
return m_CharacterParent;
}
sCharacter *cCharacterController::GetCharacter(long IDNum)
{
sCharacter *CharPtr;
// Scan through all characters
if((CharPtr = m_CharacterParent) != NULL) {
while(CharPtr != NULL) {
// Return character
if(IDNum == CharPtr->ID)
return CharPtr;
// Go to next character
CharPtr = CharPtr->Next;
}
}
return NULL;
}
float cCharacterController::GetSpeed(sCharacter *Character)
{
float Speed;
// Error checking
if(Character == NULL)
return 0.0f;
// Calculate adjusted speed
Speed = Character->Def.Speed;
// Bounds check value
if(Speed < 1.0f)
Speed = 1.0f;
return Speed;
}
long cCharacterController::GetAttack(sCharacter *Character)
{
long Attack;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted attack
Attack = Character->Def.Attack;
// Adjust attack based on item value (in %(Value/100)+1)
if(Character->Def.Weapon != -1 && m_MIL != NULL) {
Attack = (long)((float)Attack * \
(((float)m_MIL[Character->Def.Weapon].Value / \
100.0f) + 1.0f));
}
return Attack;
}
long cCharacterController::GetDefense(sCharacter *Character)
{
long Defense;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted defense
Defense = Character->Def.Defense;
if(Character->Def.Armor != -1 && m_MIL != NULL)
Defense = (long)((float)Defense * \
(((float)m_MIL[Character->Def.Armor].Value / \
100.0f) + 1.0f));
if(Character->Def.Shield != -1 && m_MIL != NULL)
Defense = (long)((float)Defense * \
(((float)m_MIL[Character->Def.Shield].Value / \
100.0f) + 1.0f));
// Bounds check value
if(Defense < 0)
Defense = 0;
return Defense;
}
long cCharacterController::GetAgility(sCharacter *Character)
{
long Agility;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted agility
Agility = Character->Def.Agility;
return Agility;
}
long cCharacterController::GetResistance(sCharacter *Character)
{
long Resistance;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted resistance
Resistance = Character->Def.Resistance;
return Resistance;
}
long cCharacterController::GetMental(sCharacter *Character)
{
long Mental;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted mental
Mental = Character->Def.Mental;
return Mental;
}
long cCharacterController::GetToHit(sCharacter *Character)
{
long ToHit;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted to hit
ToHit = Character->Def.ToHit;
return ToHit;
}
float cCharacterController::GetCharge(sCharacter *Character)
{
float Charge;
// Error checking
if(Character == NULL)
return 0;
// Calculate adjusted charge
Charge = Character->Def.ChargeRate;
return Charge;
}
cCharICS *cCharacterController::GetICS(long IDNum)
{
sCharacter *CharPtr;
if((CharPtr = GetCharacter(IDNum)) == NULL)
return NULL;
return CharPtr->CharICS;
}
BOOL cCharacterController::SetLock(long IDNum, BOOL State)
{
sCharacter *CharPtr;
// Get pointer to character
if((CharPtr = GetCharacter(IDNum)) == NULL)
return FALSE;
// Set new value
CharPtr->Locked = State;
return TRUE;
}
BOOL cCharacterController::SetActionTimer(long IDNum, long Timer)
{
sCharacter *CharPtr;
// Get pointer to character
if((CharPtr = GetCharacter(IDNum)) == NULL)
return FALSE;
// Set new value
CharPtr->ActionTimer = Timer;
return TRUE;
}
BOOL cCharacterController::SetAction(sCharacter *Character, \
long Action, \
long AddTime)
{
long MeshNum;
// Error checking
if(Character == NULL)
return FALSE;
// Make sure attack, spell, and item has supporting charge
if(Action == CHAR_ATTACK || Action == CHAR_SPELL ||
Action == CHAR_ITEM) {
if(Character->Charge < 100.0f)
return FALSE;
}
// Set action
Character->Action = Action;
// Play sound effect
ActionSound(Character);
// Get mesh number
MeshNum = Character->Def.MeshNum;
// Set action time (or set to 1 is addtime = -1)
if(AddTime == -1)
Character->ActionTimer = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -