Mercurial > LightClone
view LightClone/Source/Bot.cpp @ 3:6f227dd9a94f
Re-add code that was lost during the transfer
author | koryspansel |
---|---|
date | Wed, 07 Sep 2011 13:47:48 -0700 |
parents | 7e3a0ae9c016 |
children | d52a7042fa1a |
line wrap: on
line source
/* * Bot */ #include "Bot.h" #include "Clock.h" #include <d3d9.h> #include <d3dx9.h> /* * DirectionAngle */ const float DirectionAngle[] = {-1.0f * D3DX_PI / 2.0f, -4.0f * D3DX_PI / 2.0f, -3.0f * D3DX_PI / 2.0f, -2.0f * D3DX_PI / 2.0f}; /* * DirectionStepX */ const int32 DirectionStepX[] = {0, 1, 0, -1}; /* * DirectionStepY */ const int32 DirectionStepY[] = {1, 0, -1, 0}; /* * Bot */ Bot::Bot() { pEnvironment = 0; nState = BotState_Idle; kSize = D3DXVECTOR3(0.55f, 1.00f, 0.55f); } /* * Initialize */ void Bot::Initialize(Environment* pInstance) { pEnvironment = pInstance; nState = BotState_Idle; nColor = D3DCOLOR_XRGB(0, 255, 0); kMachine.RemoveAllFunctions(); } /* * Reset */ void Bot::Reset() { nState = BotState_Idle; nColor = D3DCOLOR_XRGB(0, 255, 0); kMachine.Reset(); } /* * GetWorldPosition */ const D3DXVECTOR3 Bot::GetWorldPosition() const { const D3DXVECTOR3& kScale = pEnvironment->GetScale(); D3DXVECTOR3 kWorldPosition; kWorldPosition.x = kScale.x * kPosition.X; kWorldPosition.y = kScale.y * pEnvironment->GetAltitude(kPosition.X, kPosition.Y); kWorldPosition.z = kScale.z * kPosition.Y; if(nState == BotState_Animate) { if(kSequencer.nSequence == BotSequence_Forward) { kWorldPosition.x = kScale.x * ((int32)kPosition.X + kSequencer.fTimer * ((int32)kSequencer.kPosition.X - (int32)kPosition.X)); kWorldPosition.z = kScale.z * ((int32)kPosition.Y + kSequencer.fTimer * ((int32)kSequencer.kPosition.Y - (int32)kPosition.Y)); } else if(kSequencer.nSequence == BotSequence_Jump) { const uint32 nHeightA = pEnvironment->GetAltitude(kPosition.X, kPosition.Y); const uint32 nHeightB = pEnvironment->GetAltitude(kSequencer.kPosition.X, kSequencer.kPosition.Y); const float fDistanceX = kScale.x; const float fDistanceY = kScale.y * ((float)nHeightB - (float)nHeightA); const float fHeight = nHeightB > nHeightA ? 2.0f * kScale.y : kScale.y; const float fB = (fHeight - 0.25f * fDistanceY) / (-0.25f * fDistanceX + 0.5f * fDistanceX); const float fA = (fDistanceY - fB * fDistanceX) / (fDistanceX * fDistanceX); const float fX = kSequencer.fTimer * fDistanceX; kWorldPosition.x = kScale.x * ((int32)kPosition.X + kSequencer.fTimer * ((int32)kSequencer.kPosition.X - (int32)kPosition.X)); kWorldPosition.y = nHeightA * kScale.y + fX * (fA * fX + fB); kWorldPosition.z = kScale.z * ((int32)kPosition.Y + kSequencer.fTimer * ((int32)kSequencer.kPosition.Y - (int32)kPosition.Y)); } } return kWorldPosition; } /* * GetWorldOrientation */ const D3DXVECTOR3 Bot::GetWorldOrientation() const { D3DXVECTOR3 kWorldOrientation; kWorldOrientation.x = 0.0f; kWorldOrientation.y = DirectionAngle[kDirection]; kWorldOrientation.z = 0.0f; if(nState == BotState_Animate) { if(kSequencer.nSequence == BotSequence_RotateCW || kSequencer.nSequence == BotSequence_RotateCCW) { kWorldOrientation.y = InterpolateDirection(kDirection, kSequencer.kDirection, kSequencer.fTimer); } } return kWorldOrientation; } /* * AddFunction */ void Bot::AddFunction(uint32 nFunction, uint32 nSize) { kMachine.AddFunction((uint8)nFunction, (uint8)nSize * 2); } /* * Upload */ ErrorCode Bot::Upload(Code* pCode, uint32 nCount) { ErrorCode eCode = Error_Success; for(uint32 i = 0; i < nCount && eCode == Error_Success; ++i) { uint32 nSize = kMachine.GetFunctionSize(i); uint8* pData = kMachine.GetFunctionMemory(i); eCode = Compile(pCode + i, pData, nSize); } nState = BotState_Evaluate; return eCode; } /* * Compile */ ErrorCode Bot::Compile(Code* pInstance, uint8* pData, uint32 nSize) { const uint32 nLength = pInstance->GetLength(); for(uint32 i = 0; i < nLength; ++i) { const uint32 nAction = pInstance->GetSlot(i); if(Action_Forward <= nAction && nAction <= Action_Light) { if(nSize < 2) return Error_Fail; *pData++ = Instruction_Action; *pData++ = nAction; nSize -= 2; } else if(Action_FunctionA <= nAction && nAction <= Action_FunctionB) { if(nSize < 2) return Error_Fail; *pData++ = Instruction_Call; *pData++ = nAction - Action_FunctionA + 1; nSize -= 2; } } return Error_Success; } /* * Update */ bool Bot::Update(float fElapsed) { if(nState == BotState_Evaluate) { bool bHandled = false; kClock.Reset(); while(!bHandled && kClock.GetElapsed(false) < fElapsed) { uint32 nAction = kMachine.Step(); if(Action_Forward <= nAction && nAction <= Action_Light) { if(nAction == Action_Forward) { if(pEnvironment->IsMovementValid(nAction, kPosition.X, kPosition.Y, kDirection)) { kSequencer.kPosition.X = (int32)kPosition.X + DirectionStepX[kDirection]; kSequencer.kPosition.Y = (int32)kPosition.Y + DirectionStepY[kDirection]; kSequencer.nSequence = BotSequence_Forward; kSequencer.fTimer = 0.0f; kSequencer.fSpeed = 1.5f; nState = BotState_Animate; } } else if(nAction == Action_RotateCW) { kSequencer.kDirection = (kDirection + 1) % Direction_Count; kSequencer.nSequence = BotSequence_RotateCW; kSequencer.fTimer = 0.0f; kSequencer.fSpeed = 1.5f; nState = BotState_Animate; } else if(nAction == Action_RotateCCW) { nState = BotState_Animate; kSequencer.kDirection = (kDirection - 1 + Direction_Count) % Direction_Count; kSequencer.nSequence = BotSequence_RotateCCW; kSequencer.fTimer = 0.0f; kSequencer.fSpeed = 1.5f; } else if(nAction == Action_Jump) { if(pEnvironment->IsMovementValid(nAction, kPosition.X, kPosition.Y, kDirection)) { kSequencer.kPosition.X = (int32)kPosition.X + DirectionStepX[kDirection]; kSequencer.kPosition.Y = (int32)kPosition.Y + DirectionStepY[kDirection]; } else { kSequencer.kPosition.X = kPosition.X; kSequencer.kPosition.Y = kPosition.Y; } nState = BotState_Animate; kSequencer.nSequence = BotSequence_Jump; kSequencer.fTimer = 0.0f; kSequencer.fSpeed = 1.5f; } else if(nAction == Action_Light) { nState = BotState_Animate; nColor = D3DCOLOR_XRGB(0, 0, 255); kSequencer.nSequence = BotSequence_Light; kSequencer.fTimer = 0.0f; kSequencer.fSpeed = 3.0f; } bHandled = true; } } } else if(nState == BotState_Animate) { kSequencer.fTimer += kSequencer.fSpeed * fElapsed; if(kSequencer.fTimer >= 1.0f) { if(kSequencer.nSequence == BotSequence_Forward) { nState = BotState_Pause; kPosition = kSequencer.kPosition; kSequencer.fTimer = 0.4f; } else if(kSequencer.nSequence == BotSequence_RotateCW) { nState = BotState_Pause; kDirection = kSequencer.kDirection; kSequencer.fTimer = 0.4f; } else if(kSequencer.nSequence == BotSequence_RotateCCW) { nState = BotState_Pause; kDirection = kSequencer.kDirection; kSequencer.fTimer = 0.4f; } else if(kSequencer.nSequence == BotSequence_Jump) { nState = BotState_Pause; kPosition = kSequencer.kPosition; kSequencer.fTimer = 0.4f; } else if(kSequencer.nSequence == BotSequence_Light) { pEnvironment->NotifyAction(kPosition.X, kPosition.Y); nState = BotState_Pause; nColor = D3DCOLOR_XRGB(0, 255, 0); kSequencer.fTimer = 0.4f; } } } else if(nState == BotState_Pause) { kSequencer.fTimer -= fElapsed; if(kSequencer.fTimer <= 0.0f) { nState = BotState_Evaluate; return true; } } return false; }