Well, I was hopping this was a common problem :/ Did not really want to post the code, but I hope it helps:
#include "MainClientState.h"
#include "MainMenuState.h"
#include "OurGameMessages.h"
#include <iostream>
using namespace std;
MainClientState::MainClientState()
{
mainThemeChannleID = 0;
}
MainClientState::~MainClientState()
{
}
void MainClientState::Init(void)
{
gameMgr = GameManager::getInstance();
game = Game::getInstance();
gMgr = GraphicManager::getInstance();
iMgr = InputManager::getInstance();
dbMgr = DataBaseManager::getInstance();
netMgr = NetworkManager::getInstance();
sMgr = SoundManager::getInstance();
netObjectList.clear();
userName = game->getUserName();
isNetActive = false; // we are not active on the network. We don't send or receive any updates yet
netUpdateTimer = 0.1; // there was some sorta data cloge that kept one client from letting the other clients send anything. We try to fight this by only net updating 10 times a sec
hasMoved = false; // we need these so we don't have to send updates unless they have moved or turned
hasTurned = false;
justStopped = false;
gMgr->setBackgroundColor(255, 125, 125, 125);
// draw the chat box area
creatChatBox();
// remove later, this is so we can see the mouse position and delta position
mouseStaticID = gMgr->createStaticText(0, 0, 600, 100);
// for testing the cube moving. Remove latre
moveForward = 0;
moveSide = 0;
maxXAngle = 70;
minXAngle = -25;
speed = 100;
cameraFarOut = 70;
// we replace our old code with GameManager code
// we create a game object for our main character
myID = gameMgr->createGameObject();
// we add components to our game object
gameMgr->addGameComponent(myID, ComponentType::NAME_COMP);
gameMgr->addGameComponent(myID, ComponentType::MOVEMENT_COMP);
gameMgr->addGameComponent(myID, ComponentType::BODY_VIEW_COMP);
gameMgr->addGameComponent(myID, ComponentType::HP_COMP);
gameMgr->addGameComponent(myID, ComponentType::MP_COMP);
gameMgr->addGameComponent(myID, ComponentType::AP_COMP);
gameMgr->addGameComponent(myID, ComponentType::LOCK_ON_COMP);
// now for our camera
cameraID = gameMgr->createGameObject();
//// fill in the model data list: 0 = Sydney, 1 = Ninja, 2 = Faerie, 3 = Dwarf
modelDataList[0] = new modelData(dbMgr->getDataAsString("sydney_model"), dbMgr->getDataAsString("sydney_texture"), dbMgr->getDataAsUInt("sydney_stand_animation_start"), dbMgr->getDataAsUInt("sydney_stand_animation_end"), dbMgr->getDataAsUInt("sydney_run_animation_start"), dbMgr->getDataAsUInt("sydney_run_animation_end"), dbMgr->getDataAsUInt("sydney_attack_animation_start"), dbMgr->getDataAsUInt("sydney_attack_animation_end"));
modelDataList[1] = new modelData(dbMgr->getDataAsString("ninja_model"), dbMgr->getDataAsString("ninja_texture"), dbMgr->getDataAsUInt("ninja_stand_animation_start"), dbMgr->getDataAsUInt("ninja_stand_animation_end"), dbMgr->getDataAsUInt("ninja_run_animation_start"), dbMgr->getDataAsUInt("ninja_run_animation_end"), dbMgr->getDataAsUInt("ninja_attack_animation_start"), dbMgr->getDataAsUInt("ninja_attack_animation_end"));
modelDataList[2] = new modelData(dbMgr->getDataAsString("faerie_model"), dbMgr->getDataAsString("faerie_texture"), dbMgr->getDataAsUInt("faerie_stand_animation_start"), dbMgr->getDataAsUInt("faerie_stand_animation_end"), dbMgr->getDataAsUInt("faerie_run_animation_start"), dbMgr->getDataAsUInt("faerie_run_animation_end"), dbMgr->getDataAsUInt("faerie_attack_animation_start"), dbMgr->getDataAsUInt("faerie_attack_animation_end"));
modelDataList[3] = new modelData(dbMgr->getDataAsString("dwarf_model"), dbMgr->getDataAsString("dwarf_texture"), dbMgr->getDataAsUInt("dwarf_stand_animation_start"), dbMgr->getDataAsUInt("dwarf_stand_animation_end"), dbMgr->getDataAsUInt("dwarf_run_animation_start"), dbMgr->getDataAsUInt("dwarf_run_animation_end"), dbMgr->getDataAsUInt("dwarf_attack_animation_start"), dbMgr->getDataAsUInt("dwarf_attack_animation_end"));
unsigned int testObjectID;
unsigned int testObjectNameID;
unsigned int r;
unsigned int g;
unsigned int b;
game->getCubeColor(r, g, b);
gameMgr->setRed(myID, r);
gameMgr->setGreen(myID, g);
gameMgr->setBlue(myID, b);
//testObjectID = gMgr->createTestBox(r, g, b);
//testObjectNameID = gMgr->create3DText((char*)dbMgr->getDataAsString("test_font").c_str(), (char*)userName.c_str());
//gMgr->setNodePosition(testObjectNameID, 0, 10, 0);
//gMgr->setNodeParent(testObjectID, testObjectNameID);
//gameMgr->addResourceID(myID, "bodyID", testObjectID);
//gameMgr->addResourceID(myID, "nameID", testObjectNameID);
//testObjectID = gMgr->createAnimatedMesh((char*)modelDataList[1]->model.c_str());
//gMgr->setNodeTexture(testObjectID, 0, (char*)modelDataList[1]->texture.c_str());
//gMgr->setNodeScale(testObjectID, 200, 200, 200);
//gMgr->setAnimationFrameSpeed(testObjectID, 0.2);
//gMgr->setAnimationFrameLoop(testObjectID, modelDataList[1]->anime_stand_start, modelDataList[1]->anime_stand_end);
//gMgr->setNodePosition(testObjectID, 700, -20, 3000);
//gMgr->setNodeRotation(testObjectID, 0, -90, 0);
testObjectID = gMgr->createAnimatedMesh((char*)modelDataList[1]->model.c_str());
gMgr->setNodeTexture(testObjectID, 0, (char*)modelDataList[1]->texture.c_str());
gMgr->setAnimationFrameLoop(testObjectID, modelDataList[1]->anime_stand_start, modelDataList[1]->anime_stand_end);
gMgr->setAnimationFrameSpeed(testObjectID, 1);
gMgr->setNodePosition(testObjectID, 0, -20, 0);
//gMgr->setNodeRotation(testObjectID, 0, -90, 0);
gMgr->setNodeScale(testObjectID, 3.5, 3.5, 3.5);
testObjectNameID = gMgr->create3DText((char*)dbMgr->getDataAsString("test_font").c_str(), (char*)userName.c_str());
gMgr->setNodePosition(testObjectNameID, 0, 10, 0);
gMgr->setNodeParent(testObjectID, testObjectNameID);
gameMgr->setName(myID, game->getUserName());
gameMgr->addResourceID(myID, "bodyID", testObjectID);
gameMgr->addResourceID(myID, "nameID", testObjectNameID);
// we set our HP
gameMgr->setMaxHP(myID, 100); // no need to set MinHP. it zero be default
gameMgr->setHP(myID, 100);
// 1 = stop, 2 = walking/running
gameMgr->setState(myID, 1);
//// some static cubes so you can tell we are moving
//unsigned int staticCube = 0;
//staticCube = gMgr->createTestBox(255, 255, 255);
//gMgr->setNodePosition(staticCube, 40, 0, 0);
//staticCube = gMgr->createTestBox(255, 255, 255);
//gMgr->setNodePosition(staticCube, -40, 0, 0);
//staticCube = gMgr->createTestBox(255, 255, 255);
//gMgr->setNodePosition(staticCube, 0, 0, 40);
//staticCube = gMgr->createTestBox(255, 255, 255);
//gMgr->setNodePosition(staticCube, 0, 0, -40);
// load from irr file
WeirdMap = gMgr->loadmap("Map1.irr", 0);
gMgr->CreateDefaultSkyBox();
//// we send a request to the server to create our character, we only pass the color
//RakNet::BitStream bs;
//bs.Write((unsigned char)ID_REQUEST_USER_CREATE);
//bs.Write(r);
//bs.Write(g);
//bs.Write(b);
//// now we send the bitstream
//netMgr->sendBitStream(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
////// fill in the model data list: 0 = Sydney, 1 = Ninja, 2 = Faerie, 3 = Dwarf
//modelDataList[0] = new modelData(dbMgr->getDataAsString("sydney_model"), dbMgr->getDataAsString("sydney_texture"), dbMgr->getDataAsUInt("sydney_stand_animation_start"), dbMgr->getDataAsUInt("sydney_stand_animation_end"), dbMgr->getDataAsUInt("sydney_run_animation_start"), dbMgr->getDataAsUInt("sydney_run_animation_end"), dbMgr->getDataAsUInt("sydney_attack_animation_start"), dbMgr->getDataAsUInt("sydney_attack_animation_end"));
//modelDataList[1] = new modelData(dbMgr->getDataAsString("ninja_model"), dbMgr->getDataAsString("ninja_texture"), dbMgr->getDataAsUInt("ninja_stand_animation_start"), dbMgr->getDataAsUInt("ninja_stand_animation_end"), dbMgr->getDataAsUInt("ninja_run_animation_start"), dbMgr->getDataAsUInt("ninja_run_animation_end"), dbMgr->getDataAsUInt("ninja_attack_animation_start"), dbMgr->getDataAsUInt("ninja_attack_animation_end"));
//modelDataList[2] = new modelData(dbMgr->getDataAsString("faerie_model"), dbMgr->getDataAsString("faerie_texture"), dbMgr->getDataAsUInt("faerie_stand_animation_start"), dbMgr->getDataAsUInt("faerie_stand_animation_end"), dbMgr->getDataAsUInt("faerie_run_animation_start"), dbMgr->getDataAsUInt("faerie_run_animation_end"), dbMgr->getDataAsUInt("faerie_attack_animation_start"), dbMgr->getDataAsUInt("faerie_attack_animation_end"));
//modelDataList[3] = new modelData(dbMgr->getDataAsString("dwarf_model"), dbMgr->getDataAsString("dwarf_texture"), dbMgr->getDataAsUInt("dwarf_stand_animation_start"), dbMgr->getDataAsUInt("dwarf_stand_animation_end"), dbMgr->getDataAsUInt("dwarf_run_animation_start"), dbMgr->getDataAsUInt("dwarf_run_animation_end"), dbMgr->getDataAsUInt("dwarf_attack_animation_start"), dbMgr->getDataAsUInt("dwarf_attack_animation_end"));
// let try seting up the ninjas
golem1ID = gMgr->createAnimatedMesh((char*)modelDataList[1]->model.c_str());
gMgr->setNodeTexture(golem1ID, 0, (char*)modelDataList[1]->texture.c_str());
gMgr->setNodeScale(golem1ID, 200, 200, 200);
gMgr->setAnimationFrameSpeed(golem1ID, 0.2);
gMgr->setAnimationFrameLoop(golem1ID, modelDataList[1]->anime_attack_start, modelDataList[1]->anime_attack_end);
gMgr->setNodePosition(golem1ID, 700, -20, 3000);
gMgr->setNodeRotation(golem1ID, 0, -90, 0);
// I don't want both golems to start the animation from the same frame. I'm going to let the second golem to start from the middel of the animation
int secondFramStart = modelDataList[1]->anime_attack_start + (modelDataList[1]->anime_attack_end - modelDataList[1]->anime_attack_start) / 2;
golem2ID = gMgr->createAnimatedMesh((char*)modelDataList[1]->model.c_str());
gMgr->setNodeTexture(golem2ID, 0, (char*)modelDataList[1]->texture.c_str());
gMgr->setNodeScale(golem2ID, 200, 200, 200);
gMgr->setAnimationFrameSpeed(golem2ID, 0.2);
gMgr->setAnimationFrameLoop(golem2ID, modelDataList[1]->anime_attack_start, modelDataList[1]->anime_attack_end);
gMgr->setAnimationCurrentFrame(golem2ID, secondFramStart);
gMgr->setNodePosition(golem2ID, -700, -20, 3000);
gMgr->setNodeRotation(golem2ID, 0, 90, 0);
arenaZLimit = 2000;
inArena = false;
soundFadeSpeed = 0.3;
soundVolume = 1;
cout << "main check" << endl;
isLockOnDown = false;
}
void MainClientState::DeInit(void)
{
modelDataList.clear();
netObjectList.clear();
//dbMgr->clearData();
netMgr->shutDown();
gMgr->clearGUI();
gMgr->clearSceneManager();
sMgr->playSound(mainThemeChannleID, dbMgr->getDataAsInt("main_theme_id"));
sMgr->setVolum(mainThemeChannleID, 1);
gameMgr->clearAllGameObjects();
gameMgr->clearAllGameComponents();
}
void MainClientState::Pause(CStateEngine *engine)
{
}
void MainClientState::Resume(CStateEngine *engine)
{
}
void MainClientState::HandleEvents(CStateEngine *engine)
{
// ESC to go back to main menu
if(iMgr->getKeyState(KEY_ESCAPE))
engine->RequestChangeState(new MainMenuState());
// we check for some GUI events
unsigned int numberOfButtonsClicked = iMgr->getNumberOfElementsForThisEvent(irr::gui::EGET_BUTTON_CLICKED);
if(numberOfButtonsClicked > 0) // then there were button that were clicked
{
for(int i = 0; i < numberOfButtonsClicked; i++)
{
if(iMgr->getElementFromEventByIndex(irr::gui::EGET_BUTTON_CLICKED, i) == chatSubmitButtonID)
{
moveChatToHistory();
}
}
}
// check if the hit enter in the chat edit box
unsigned int numberOfEntersHit = iMgr->getNumberOfElementsForThisEvent(irr::gui::EGET_EDITBOX_ENTER);
if(numberOfEntersHit > 0)
{
for(int i = 0; i < numberOfEntersHit; i++)
{
if(iMgr->getElementFromEventByIndex(irr::gui::EGET_EDITBOX_ENTER, i) == chatEditBoxID)
moveChatToHistory();
}
}
// when done, clear the gui event list so we can check for more next frame
iMgr->clearGUIEventList();
// we handle network messages here
// also check if disconnect for any reason, we go back to the main menu
while(netMgr->getNewPacket2())
{
unsigned char idn;
unsigned int netID;
float nx, ny , nz, nyAngle;
bool nhasMoved, nhasTurned, njustStopped;
std::string name;
unsigned int modelID;
unsigned int r, g, b;
unsigned int numberOfUsers;
RakNet::Time timeStamp;
netMgr->fillBitStreamFromPacket();
idn = netMgr->readUCharFromBitStream();
core::stringw fullText;
core::stringw oldText;
// we check first if its starts with a time stamp
if(idn == ID_TIMESTAMP)
{
timeStamp = netMgr->readTimeStampFromBitStream();
// the next one is the message identifier
idn = netMgr->readUCharFromBitStream();
}
switch(idn)
{
case ID_REMOTE_DISCONNECTION_NOTIFICATION:
cout << "Another client has disconnected." << endl;
break;
case ID_REMOTE_CONNECTION_LOST:
cout << "Another client has lost the connection." << endl;
break;
case ID_REMOTE_NEW_INCOMING_CONNECTION:
cout << "Another client has connected." << endl;
break;
case ID_CONNECTION_REQUEST_ACCEPTED:
cout << "Our connection request has been accepted." << endl;
break;
case ID_NEW_INCOMING_CONNECTION:
cout << "A connection is incoming." << endl;
break;
case ID_NO_FREE_INCOMING_CONNECTIONS:
cout << "The server is full." << endl;
break;
case ID_DISCONNECTION_NOTIFICATION: // we go back to the main menu
cout << "A client has disconnected." << endl;
engine->RequestChangeState(new MainMenuState());
break;
case ID_CONNECTION_LOST: // we go back to the main menu
cout << "A client lost the connection." << endl;
engine->RequestChangeState(new MainMenuState());
break;
case ID_SEND_CHAT:
{
// we display this in the history edit box
std::string sendMessage = netMgr->readStringFromBitStream();
// we put our name at the beining
fullText = core::stringw(sendMessage.c_str());
// and add to the old history box
oldText = core::stringw(gMgr->getGUIText(chatHistoryEditBoxID));
oldText += L"\n";
oldText += fullText;
// then we put the text in the histroy box
gMgr->setGUIText(chatHistoryEditBoxID, oldText.c_str());
}
break;
case ID_ADD_CURRENT_USERS:
///////////
// 9th step
///////////
cout << "Step 9" << endl;
// we were givig a lst of all active usres
// we add them
// then we send the confirmation that everything is fine
// we add the netID for our character now (fix this)
netID = netMgr->readUIntFromBitStream();
gameMgr->addResourceID(myID, "netID", netID);
// we get the number of users sent
numberOfUsers = netMgr->readUIntFromBitStream();
// now we go one by one, if any
for(int i = 0; i < numberOfUsers; i++)
{
netID = netMgr->readUIntFromBitStream();
nx = netMgr->readFloatFromBitStream();
ny = netMgr->readFloatFromBitStream();
nz = netMgr->readFloatFromBitStream();
nyAngle = netMgr->readFloatFromBitStream();
name = netMgr->readStringFromBitStream();
modelID = netMgr->readUIntFromBitStream();
r = netMgr->readUIntFromBitStream();
g = netMgr->readUIntFromBitStream();
b = netMgr->readUIntFromBitStream();
// now create characters/cubes
addNewUser(netID, nx, ny, nz, nyAngle, (char*)name.c_str(), modelID, r, g, b);
}
// we are done. Send confirm
netMgr->clearBitSteram();
netMgr->writeUCharToBitStream((unsigned char)ID_CONFIRM_CURRENT_USERS);
netMgr->writeUIntToBitStream(gameMgr->getResourceID(myID, "netID"));
netMgr->sendBitStreamToAll(HIGH_PRIORITY, RELIABLE_ORDERED, 0);
cout << "Go to step 10" << endl;
break;
case ID_REQUST_ADD_NEW_USER :
///////////
// 11th step
///////////
cout << "Step 11" << endl;
// we get a message that a new user was added
// we added him here
// then we send a confirm that we added him
// get the values
netID = netMgr->readUIntFromBitStream();
nx = netMgr->readFloatFromBitStream();
ny = netMgr->readFloatFromBitStream();
nz = netMgr->readFloatFromBitStream();
nyAngle = netMgr->readFloatFromBitStream();
name = netMgr->readStringFromBitStream();
modelID = netMgr->readUIntFromBitStream();
r = netMgr->readUIntFromBitStream();
g = netMgr->readUIntFromBitStream();
b = netMgr->readUIntFromBitStream();
// now create characters/cubes
addNewUser(netID, nx, ny, nz, nyAngle, (char*)name.c_str(), modelID, r, g, b);
// we are done. Send confirm, our ID, and the ID of the new guy
netMgr->clearBitSteram();
netMgr->writeUCharToBitStream((unsigned char)ID_CONFIRM_NEW_USER);
netMgr->writeUIntToBitStream(gameMgr->getResourceID(myID, "netID"));
netMgr->writeUIntToBitStream(netID);
netMgr->sendBitStreamToAll(HIGH_PRIORITY, RELIABLE_ORDERED, 0);
cout << "Go to step 12" << endl;
break;
case ID_YOU_ARE_ACTIVE:
///////////
// 13th step
///////////
cout << "Step 13" << endl;
// we have been activated. We can now start receving and sending updates
isNetActive = true;
cout << "We are active" << endl;
break;
case ID_UPDATE:
// we recevie someone else's update, we put it here
netID = netMgr->readUIntFromBitStream();
nhasMoved = netMgr->readBoolFromBitStream();
if(nhasMoved)
{
nx = netMgr->readFloatFromBitStream();
ny = netMgr->readFloatFromBitStream();
nz = netMgr->readFloatFromBitStream();
njustStopped = netMgr->readBoolFromBitStream();
}
nhasTurned = netMgr->readBoolFromBitStream();
if(nhasTurned)
{
nyAngle = netMgr->readFloatFromBitStream();
}
{
unsigned int objID;
unsigned int cubeID;
if(netObjectList.find(netID) != netObjectList.end())
{
objID = netObjectList[netID];
cubeID = gameMgr->getResourceID(objID, "bodyID");
if(nhasMoved)
{
//gameMgr->setPosition(objID, nx, ny, nz);
//gMgr->setNodePosition(cubeID, nx, ny, nz);
// we set our finial goal
// then we fill in the direction
// then we set the state if we are moving or stopping
float startX, startY, startZ;
gameMgr->getPosition(objID, startX, startY, startZ);
float dirX = nx - startX;
float dirY = ny - startY;
float dirZ = nz - startZ;
gMgr->normalizeVector(dirX, dirY, dirZ);
// we set the end point
gameMgr->setMoveToX(objID, nx);
gameMgr->setMoveToY(objID, ny);
gameMgr->setMoveToZ(objID, nz);
// we set the direction to move too
gameMgr->setMoveTowardX(objID, dirX);
gameMgr->setMoveTowardY(objID, dirY);
gameMgr->setMoveTowardZ(objID, dirZ);
// setting the animation
// we check which state we are in
// if we weren't moving, then we set the animation to run/walk
if(gameMgr->getState(objID) == 1) // we are in stop/stand state
{
unsigned int modelNumber = gameMgr->getBodyViewID(objID);
gMgr->setAnimationFrameLoop(cubeID, modelDataList[modelNumber]->anime_run_start, modelDataList[modelNumber]->anime_run_end);
gMgr->setAnimationFrameSpeed(cubeID, 10);
}
// now we set we either moving or heading to a stop
if(!njustStopped) // we are not stopping
{
gameMgr->setState(objID, 2); // moving
}
else // we are stopping
{
gameMgr->setState(objID, 4); // stopping
}
}
if(nhasTurned)
{
unsigned int nxAngle = 0;
unsigned int nzAngle = 0;
gameMgr->setRotation(objID, nxAngle, nyAngle, nzAngle);
gMgr->setNodeRotation(cubeID, nxAngle, nyAngle, nzAngle);
}
}
}
break;
case ID_REMOVE_USER:
netID = netMgr->readUIntFromBitStream();
removeUser(netID);
break;
case ID_ACCEPT_LOCK_ON:
{
// the server sent the target's info (HP and MaxHP)
netID = netMgr->readUIntFromBitStream();
unsigned int objID = netObjectList[netID];
int maxHP = netMgr->readIntFromBitStream();
int HP = netMgr->readIntFromBitStream();
// we set the target for our character
gameMgr->setTarget(myID, objID);
// now we set the info
gameMgr->setMaxHP(objID, maxHP);
gameMgr->setHP(objID, HP);
}
break;
default:
cout << "Message with identifier " << idn << "has arrived." << endl;
break;
}
netMgr->DestroyPacket2();
}
// we check if the lock down button (1) was pressesd
if(iMgr->getKeyState(irr::KEY_KEY_1) && !isLockOnDown)
{
// we check first if we already have a target, and if its not already selected
unsigned int targetID = findNearestObject();
if(gameMgr->getTarget(myID) != targetID && targetID != 0)
{
sendLockOnTarget(targetID);
}
isLockOnDown = true; // to make sure we don't press the button till we release it first
}
if(!iMgr->getKeyState(irr::KEY_KEY_1) && isLockOnDown)
{
isLockOnDown = false;
}
// we check if want to unlock a target. button (2)
if(iMgr->getKeyState(irr::KEY_KEY_2) && gameMgr->getTarget(myID) != 0) // we check first if have a target to begine with
{
gameMgr->setTarget(myID, 0);
sendLockOnTarget(0);
}
// get key movement and set speed
moveSide = 0;
moveForward = 0;
if(iMgr->getKeyState(irr::KEY_RIGHT))
moveSide -= 1;
if(iMgr->getKeyState(irr::KEY_LEFT))
moveSide += 1;
if(iMgr->getKeyState(irr::KEY_UP))
moveForward += 1;
if(iMgr->getKeyState(irr::KEY_DOWN))
moveForward -= 1;
// we check if the mosue right click is down
isRightClickDown = true;
// TODO fix this, the right button doesn't resoponse
if(iMgr->getKeyState(irr::KEY_RBUTTON))
isRightClickDown = true;
}
void MainClientState::Update(CStateEngine *engine)
{
// you have to tick this first in Irrlicht to get the new time and to start the drawing for this frame
gMgr->tick();
// we get the delta time so we can move objects in the correct speed
float deltaTime = gMgr->getNewDeltaTime();
// now we get some stored data to use here.
float x, y, z;
float xAngle, yAngle, zAngle;
gameMgr->getPosition(myID, x, y, z);
gameMgr->getRotation(myID, xAngle, yAngle, zAngle);
// we check the mouse delta position, and rotate the direction
int mouseX = 0, mouseY = 0;
gMgr->getDeltaMousePosition(mouseX, mouseY);
// we only look around when the mouse right button is down
if(isRightClickDown)
{
if(mouseX != 0) // we rotate right and left
{
yAngle += mouseX; // we add senstivy to slow or speed head movment
// we fix the angel to stay between 0 and 360
if(yAngle > 360)
yAngle -= 360;
if(yAngle < 0)
yAngle += 360;
// we have turned
hasTurned = true;
}
if(mouseY != 0) // we roatate up and down
{
xAngle += mouseY; // we add senstivy to slow or speed head movment
// we check the limits
if(xAngle > maxXAngle)
xAngle = maxXAngle;
if(xAngle < minXAngle)
xAngle = minXAngle;
// we have turned
hasTurned = true;
}
}
// we get the direction we are looking at using the yAngle and xAngel;
float lookX = xAngle, lookY = yAngle, lookZ = 0;
gMgr->rotationToDirection(lookX, lookY, lookZ);
// we normlize
gMgr->normalizeVector(lookX, lookY, lookZ);
// we get the forward direction
float fx = lookX, fy = 0, fz = lookZ;
// we normilize that too
gMgr->normalizeVector(fx, fy, fz);
// we get the side direction, by crossing the forward direcitn with the up(0, 1, 0) direciton
float sx = fx, sy = fy, sz = fz;
gMgr->crossProductVector(sx, sy, sz, 0, 1, 0);
// and don't forget to normlize
gMgr->normalizeVector(sx, sy, sz);
// no we get the real driection, by checking what button has been pressed, then adding that to real direction
float realX = 0, realY = 0, realZ = 0;
// check the forward direction first
if(moveForward != 0)
{
realX += fx * moveForward;
realY += fy * moveForward;
realZ += fz * moveForward;
// we have moved
hasMoved = true;
//justStopped = false; // if we are moving, then we haven't just stoped <img src='http://public.gamedev.net/public/style_emoticons/<#EMO_DIR#>/tongue.gif' class='bbc_emoticon' alt=':P' />
oldHasMoved = true;
}
// then the side direction
if(moveSide != 0)
{
realX += sx * moveSide;
realY += sy * moveSide;
realZ += sz * moveSide;
// we have moved
hasMoved = true;
//justStopped = false; // if we are moving, then we haven't just stoped <img src='http://public.gamedev.net/public/style_emoticons/<#EMO_DIR#>/tongue.gif' class='bbc_emoticon' alt=':P' />
oldHasMoved = true;
}
// now we normilize
gMgr->normalizeVector(realX, realY, realZ);
// we check if we have stopped moving
// even if we stop, we still send one more update that we have just stopped
if(!hasMoved && oldHasMoved)
{
justStopped = true;
oldHasMoved = false;
}
// move the object
x += realX * deltaTime * speed;
z += realZ * deltaTime * speed;
unsigned int bodyID = gameMgr->getResourceID(myID, "bodyID");
gMgr->setNodePosition(bodyID, x, -7, z);
gMgr->setNodeRotation(bodyID, 0, yAngle, 0);
// now we set the whole thing back in the game object
gameMgr->setPosition(myID, x, y, z);
gameMgr->setRotation(myID, xAngle, yAngle, zAngle);
// we check and set animation
switch(gameMgr->getState(myID))
{
case 1: // this is the stopping state
// we check if we are moving, then we change to running animation
if(hasMoved)
{
gameMgr->setState(myID, 2);
gMgr->setAnimationFrameLoop(gameMgr->getResourceID(myID, "bodyID"), modelDataList[1]->anime_run_start, modelDataList[1]->anime_run_end);
gMgr->setAnimationFrameSpeed(gameMgr->getResourceID(myID, "bodyID"), 10);
}
break;
case 2: // this is the moving state
// we check if we are not stopping, then we change to stand animation
if(!hasMoved)
{
gameMgr->setState(myID, 1);
gMgr->setAnimationFrameLoop(gameMgr->getResourceID(myID, "bodyID"), modelDataList[1]->anime_stand_start, modelDataList[1]->anime_stand_end);
gMgr->setAnimationFrameSpeed(gameMgr->getResourceID(myID, "bodyID"), 1);
}
break;
}
// set the camera
// we muliply the look vector by the cameraFarOut, then we move the camera back
float cameraX = x + lookX * cameraFarOut * -1, cameraY = 0 + lookY * cameraFarOut * -1, cameraZ = z + lookZ * cameraFarOut * -1;
gMgr->setCameraPosition(cameraX, cameraY, cameraZ);
gMgr->setCameraLookAt(x, 0, z);
gameMgr->setPosition(cameraID, cameraX, cameraY, cameraZ);
// remove later, set the mouse position and delta position
int mX = 0, mY = 0, dX = mouseX, dY = mouseX;
gMgr->getMousePosition(mX, mY);
// we check here if we are in or out of the golem area, then fade the music accordinglly
if(inArena) // if we are in the golem area
{
if(z < arenaZLimit - 300) // did we go back to house limit, we add some space in case we have just entered the golem area before
{
inArena = false; // we in the house area
// we start fading out the battel theme
fadeState = 3;
}
}
else // if are in the house area
{
if(z > arenaZLimit) // did we pass the golem limit
{
inArena = true; // we in the golem area
// we start fading out the main theme
fadeState = 1;
}
}
// now we check the fading
switch(fadeState) // if 0 then no fading is needed
{
case 1: // fade out main
// we lower the volue
soundVolume -= soundFadeSpeed * deltaTime;
// check if we pass the 0
if(soundVolume < 0) // we change the to battel sound, and change sound state to fade in battel sound
{
soundVolume = 0;
sMgr->playSound(mainThemeChannleID, dbMgr->getDataAsInt("battel_theme_id"));
sMgr->setVolum(mainThemeChannleID, soundVolume);
fadeState = 2; // we go to fade in battel sound
}
else // still not there, we set the volume
{
sMgr->setVolum(mainThemeChannleID, soundVolume);
}
break;
case 2: // fade in battel
// we increase the volue
soundVolume += soundFadeSpeed * deltaTime;
// check if we pass the 1
if(soundVolume > 1) // we reached the limit, switch to no fade now
{
soundVolume = 1;
sMgr->setVolum(mainThemeChannleID, soundVolume);
fadeState = 0;
}
else // still not there, we set the volume
{
sMgr->setVolum(mainThemeChannleID, soundVolume);
}
break;
case 3: // fade out battel
// we lower the volue
soundVolume -= soundFadeSpeed * deltaTime;
// check if we pass the 0
if(soundVolume < 0) // we change the to main sound, and change sound state to fade in battel sound
{
soundVolume = 0;
sMgr->playSound(mainThemeChannleID, dbMgr->getDataAsInt("main_theme_id"));
sMgr->setVolum(mainThemeChannleID, soundVolume);
fadeState = 4; // we go to fade in main sound
}
else // still not there, we set the volume
{
sMgr->setVolum(mainThemeChannleID, soundVolume);
}
break;
case 4: // fade in main
// we increase the volue
soundVolume += soundFadeSpeed * deltaTime;
// check if we pass the 1
if(soundVolume > 1) // we reached the limit, switch to no fade now
{
soundVolume = 1;
sMgr->setVolum(mainThemeChannleID, soundVolume);
fadeState = 0;
}
else // still not there, we set the volume
{
sMgr->setVolum(mainThemeChannleID, soundVolume);
}
break;
}
//core::stringw mouseText = L"x: ";
//mouseText += mX;
//mouseText += L" y: ";
//mouseText += mY;
//mouseText += L" dx: ";
//mouseText += dX;
//mouseText += L" dy: ";
//mouseText += dY;
//mouseText += L"\n angleY: ";
//mouseText += yAngle;
//mouseText += L" angleX: ";
//mouseText += xAngle;
//mouseText += L"\nlookX: ";
//mouseText += lookX;
//mouseText += L" lookY: ";
//mouseText += lookY;
//mouseText += L" lookZ: ";
//mouseText += lookZ;
//mouseText += L"\nfx: ";
//mouseText += fx;
//mouseText += L" fy: ";
//mouseText += fy;
//mouseText += L" fz: ";
//mouseText += fz;
//mouseText += L"\nsx: ";
//mouseText += sx;
//mouseText += L" sy: ";
//mouseText += sy;
//mouseText += L" sz: ";
//mouseText += sz;
//mouseText += L"\nrealX: ";
//mouseText += realX;
//mouseText += L" realY: ";
//mouseText += realY;
//mouseText += L" realZ: ";
//mouseText += realZ;
//mouseText += L"\nX: ";
//mouseText += x;
//mouseText += L" Y: ";
//mouseText += 0.0;
//mouseText += L" Z: ";
//mouseText += z;
// we view our HP
core::stringw mouseText = L"";
mouseText += gameMgr->getName(myID).c_str();
mouseText += L"\nHP: ";
mouseText += gameMgr->getHP(myID);
mouseText += L"/";
mouseText += gameMgr->getMaxHP(myID);
mouseText += L"\n\n";
// if we are lock on to someone, we show the HP too
unsigned int targetID = gameMgr->getTarget(myID);
if(targetID)
{
mouseText += gameMgr->getName(targetID).c_str();
mouseText += L"\nHP: ";
mouseText += gameMgr->getHP(targetID);
mouseText += L"/";
mouseText += gameMgr->getMaxHP(targetID);
mouseText += L"\n\n";
}
gMgr->setGUIText(mouseStaticID, mouseText.c_str());
///////////////
// we move whatever network object we have
///////////////
int netList = netObjectList.size();
for(int i = 0; i < netList; i++)
{
unsigned int currentObj = netObjectList[i];
gameMgr->getPosition(currentObj, x, y, z);
switch(gameMgr->getState(currentObj))
{
case 1: // we are completely stopped
// do nothing
break;
case 2: // we are moving
{
// set the data
float x, y, z;
float dirX, dirY, dirZ;
float endX, endY, endZ;
gameMgr->getPosition(currentObj, x, y, z);
dirX = gameMgr->getMoveTowardX(currentObj);
dirY = gameMgr->getMoveTowardY(currentObj);
dirZ = gameMgr->getMoveTowardZ(currentObj);
endX = gameMgr->getMoveToX(currentObj);
endY = gameMgr->getMoveToY(currentObj);
endZ = gameMgr->getMoveToZ(currentObj);
// we move forward
x += deltaTime * dirX * speed;
y += deltaTime * dirY * speed;
z += deltaTime * dirZ * speed;
// we set the game object
gameMgr->setPosition(currentObj, x, -7, z);
gMgr->setNodePosition(gameMgr->getResourceID(currentObj, "bodyID"), x, -7, z);
// check if we pass the end point
// we only need to check one point. if we are there, then all points have been reached
if(dirX != 0)
{
if((dirX > 0 && x > endX) || (dirX < 0 && x < endX)) // have we passed the end point
{
gameMgr->setState(currentObj, 3); // we set our object to keep moivng forward
}
}
else if(dirY != 0)
{
if((dirY > 0 && y > endY) || (dirY < 0 && y < endY)) // have we passed the end point
{
gameMgr->setState(currentObj, 3); // we set our object to keep moivng forward
}
}
else if(dirZ != 0)
{
if((dirZ > 0 && z > endZ) || (dirZ < 0 && z < endZ)) // have we passed the end point
{
gameMgr->setState(currentObj, 3); // we set our object to keep moivng forward
}
}
}
break;
case 3: // we didn't get an update to stop, so we keep moving
{
// we keep moivng, no need to check for reaching the end point
// set the data
float x, y, z;
float dirX, dirY, dirZ;
float endX, endY, endZ;
gameMgr->getPosition(currentObj, x, y, z);
dirX = gameMgr->getMoveTowardX(currentObj);
dirY = gameMgr->getMoveTowardY(currentObj);
dirZ = gameMgr->getMoveTowardZ(currentObj);
endX = gameMgr->getMoveToX(currentObj);
endY = gameMgr->getMoveToY(currentObj);
endZ = gameMgr->getMoveToZ(currentObj);
// we move forward
x += deltaTime * dirX * speed;
y += deltaTime * dirY * speed;
z += deltaTime * dirZ * speed;
// we set the game object
gameMgr->setPosition(currentObj, x, -7, z);
gMgr->setNodePosition(gameMgr->getResourceID(currentObj, "bodyID"), x, -7, z);
}
break;
case 4: // stopping
{
// set the data
float x, y, z;
float dirX, dirY, dirZ;
float endX, endY, endZ;
gameMgr->getPosition(currentObj, x, y, z);
dirX = gameMgr->getMoveTowardX(currentObj);
dirY = gameMgr->getMoveTowardY(currentObj);
dirZ = gameMgr->getMoveTowardZ(currentObj);
endX = gameMgr->getMoveToX(currentObj);
endY = gameMgr->getMoveToY(currentObj);
endZ = gameMgr->getMoveToZ(currentObj);
// we move forward
x += deltaTime * dirX * speed;
y += deltaTime * dirY * speed;
z += deltaTime * dirZ * speed;
// check if we pass the end point
// we only need to check one point. if we are there, then all points have been reached
if(dirX != 0)
{
if((dirX > 0 && x > endX) || (dirX < 0 && x < endX)) // have we passed the end point
{
x = endX;
y = endY;
z = endZ;
gameMgr->setState(currentObj, 1); // we stop
}
}
else if(dirY != 0)
{
if((dirY > 0 && y > endY) || (dirY < 0 && y < endY)) // have we passed the end point
{
x = endX;
y = endY;
z = endZ;
gameMgr->setState(currentObj, 1); // we stop
}
}
else if(dirZ != 0)
{
if((dirZ > 0 && z > endZ) || (dirZ < 0 && z < endZ)) // have we passed the end point
{
x = endX;
y = endY;
z = endZ;
gameMgr->setState(currentObj, 1); // we stop
}
}
// we set the game object
gameMgr->setPosition(currentObj, x, -7, z);
gMgr->setNodePosition(gameMgr->getResourceID(currentObj, "bodyID"), x, -7, z);
// we set the animation to stop, if we stoped
if(gameMgr->getState(currentObj) == 1)
{
unsigned int modelNumber = gameMgr->getBodyViewID(currentObj);
gMgr->setAnimationFrameLoop(gameMgr->getResourceID(currentObj, "bodyID"), modelDataList[modelNumber]->anime_stand_start, modelDataList[modelNumber]->anime_stand_end);
gMgr->setAnimationFrameSpeed(gameMgr->getResourceID(currentObj, "bodyID"), 1);
}
}
break;
default:
break;
}
}
// network stuff
// we send the update from here
// only start this when we are net active, it means we got a registerd character in the server
// also check if have moved or turned. If not, then there is no need to send update
netUpdateTimer -= deltaTime;
if(isNetActive && netUpdateTimer < 0 && (hasMoved || hasTurned || justStopped))
{
netUpdateTimer = 0.1;
// we send the character update here
netMgr->clearBitSteram();
float y = 0;
// first the time stamp
netMgr->writeUCharToBitStream((unsigned char)ID_TIMESTAMP);
netMgr->writeSystemTimeStampToBitStream();
// we put our update identifer
netMgr->writeUCharToBitStream((unsigned char)ID_UPDATE);
// now our ID
//netMgr->writeUIntToBitStream(myNetID);
netMgr->writeUIntToBitStream(gameMgr->getResourceID(myID, "netID"));
// we put the rest of the data
// first we check if moved
netMgr->writeBoolToBitStream(hasMoved || justStopped);
if(hasMoved || justStopped)
{
gameMgr->getPosition(myID, x, y, z);
netMgr->writeFloatToBitStream(x);
netMgr->writeFloatToBitStream(y);
netMgr->writeFloatToBitStream(z);
netMgr->writeBoolToBitStream(justStopped);
}
// now we check for turning
netMgr->writeBoolToBitStream(hasTurned);
if(hasTurned)
{
gameMgr->getRotation(myID, xAngle, yAngle, zAngle);
netMgr->writeFloatToBitStream(yAngle);
}
// now we send
netMgr->sendBitStreamToAll(HIGH_PRIORITY, RELIABLE_ORDERED, 0);
if(!hasMoved && justStopped)
{
justStopped = false;
}
hasMoved = false;
hasTurned = false;
}
}
void MainClientState::Draw(CStateEngine *engine)
{
gMgr->drawAll();
}
void MainClientState::creatChatBox(void)
{
gMgr = GraphicManager::getInstance();
// draw the chat box area
// first we get our group x and y. If we move this we move the whole menu
// the chat box (for now) should cover the lower left area of the screen.
float screenWidth = game->getScreenWidth();
float screenHeight = game->getScreenHeight();
float groupX = 0;
float groupY = screenHeight * 0.60;
float groupW = screenWidth * 0.40;
float groupH = screenHeight * 0.40;
// history area should be 90% the height of the chat area
float historyH = 0.90;
// the chat edit box is 80% of the area width, leaving the rest for the submit button
float editW = 0.80;
// draw the history edit box
chatHistoryEditBoxID = gMgr->createEditBox(groupX, groupY, groupX + groupW, groupY + (groupH * historyH));
gMgr->setEditBoxTextAlignment(chatHistoryEditBoxID, irr::gui::EGUI_ALIGNMENT::EGUIA_UPPERLEFT, irr::gui::EGUI_ALIGNMENT::EGUIA_LOWERRIGHT);
gMgr->setEditBoxAutoScroll(chatHistoryEditBoxID, true);
gMgr->setEditBoxWordWrap(chatHistoryEditBoxID, true);
gMgr->setEditBoxMultiLine(chatHistoryEditBoxID, true);
// draw the edit box
chatEditBoxID = gMgr->createEditBox(groupX, groupY + (groupH * historyH), groupX + (groupW * editW), groupY + groupH);
// draw the sumbit button
chatSubmitButtonID = gMgr->createButton(groupX + (groupW * editW), groupY + (groupH * historyH), groupX + groupW, groupY + groupH);
gMgr->setGUIText(chatSubmitButtonID, L"SEND");
}
void MainClientState::moveChatToHistory(void)
{
// frist we check if we have any text in the chat edit box
core::stringw chatText(gMgr->getGUIText(chatEditBoxID));
if(chatText == "")
return; // we have no text, we leave
// we have text, first:
// we clear the chat edit box
gMgr->setGUIText(chatEditBoxID, L"");
// we put our name at the beining
core::stringw fullText = core::stringw(game->getUserName());
fullText += ": ";
fullText += chatText;
// and add to the old history box
core::stringw oldText(gMgr->getGUIText(chatHistoryEditBoxID));
oldText += L"\n";
// oldText += core::stringw(game->getUserName());
// oldText += ": ";
oldText += fullText;
// then we put the text in the histroy box
gMgr->setGUIText(chatHistoryEditBoxID, oldText.c_str());
// now we send this chat to the server
netMgr->clearBitSteram();
netMgr->writeUCharToBitStream((unsigned char)ID_SEND_CHAT);
netMgr->writeStringToBitStream((char*)core::stringc(fullText).c_str());
// now we send the bitstream
netMgr->sendBitStreamToAll(HIGH_PRIORITY, RELIABLE_ORDERED, 0);
}
void MainClientState::addNewUser(unsigned int netID, float x, float y, float z, float yAngle, char *name, unsigned int modelNumber, unsigned int r, unsigned int g, unsigned int b)
{
float xAngle = 0;
float zAngle = 0;
unsigned int objectID = gameMgr->createGameObject();
gameMgr->addGameComponent(objectID, ComponentType::NAME_COMP);
gameMgr->addGameComponent(objectID, ComponentType::BODY_VIEW_COMP);
gameMgr->addGameComponent(objectID, ComponentType::MOVE_TO_COMP);
gameMgr->addGameComponent(objectID, ComponentType::MOVE_TOWARD_COMP);
gameMgr->addGameComponent(objectID, ComponentType::ROTATE_TO_COMP);
gameMgr->addGameComponent(objectID, ComponentType::HP_COMP);
netObjectList[netID] = objectID;
//netObjectList.insert(std::pair<unsigned int, unsigned int>(netID, objectID));
gameMgr->setPosition(objectID, x, y, z);
gameMgr->setRotation(objectID, xAngle, yAngle, zAngle);
gameMgr->setName(objectID, name);
gameMgr->setBodyViewID(objectID, modelNumber);
gameMgr->setRed(objectID, r);
gameMgr->setGreen(objectID, g);
gameMgr->setBlue(objectID, b);
//unsigned int cubeID = gMgr->createTestBox(r, g, b);
//gameMgr->addResourceID(objectID, "bodyID", cubeID);
//unsigned int nameID = gMgr->create3DText(0, name);
//gameMgr->addResourceID(objectID, "nameID", nameID);
//gameMgr->setName(objectID, name);
//gMgr->setNodePosition(cubeID, x, y, z);
//gMgr->setNodeRotation(cubeID, 0, yAngle, 0);
//gMgr->setNodePosition(nameID, 0, 10, 0);
//gMgr->setNodeParent(cubeID, nameID);
unsigned int modelID = gMgr->createAnimatedMesh((char*)modelDataList[modelNumber]->model.c_str());
gMgr->setNodeTexture(modelID, 0, (char*)modelDataList[modelNumber]->texture.c_str());
gameMgr->addResourceID(objectID, "bodyID", modelID);
unsigned int nameID = gMgr->create3DText((char*)dbMgr->getDataAsString("test_font").c_str(), (char*)userName.c_str());
gameMgr->addResourceID(objectID, "nameID", nameID);
gMgr->setAnimationFrameLoop(modelID, modelDataList[modelNumber]->anime_stand_start, modelDataList[modelNumber]->anime_stand_end);
gMgr->setAnimationFrameSpeed(modelID, 1);
gMgr->setNodePosition(modelID, x, -7, z);
gMgr->setNodeScale(modelID, 3.5, 3.5, 3.5);
gMgr->setNodePosition(nameID, 0, 10, 0);
gMgr->setNodeParent(modelID, nameID);
gameMgr->addResourceID(objectID, "netID", netID);
// at the end we set the the state for this network object
// 1 = completely stopped
// 2 = moving
// 3 = keep moving. When we reach the end and we didnt get an update, we keep moving in the same direction
// 4 = stopping
gameMgr->setState(objectID, 1);
}
void MainClientState::removeUser(unsigned int netID)
{
// remove the cube first
//if(transformList.find(netID) != transformList.end())
if(netObjectList.find(netID) != netObjectList.end())
{
unsigned int objID = netObjectList[netID];
//unsigned int cubeID = cubeList[netID];
unsigned int cubeID = gameMgr->getResourceID(objID, "bodyID");
gMgr->removeNode(cubeID);
//// now we remove the rest of the info
//cubeList.erase(netID);
//transformList.erase(netID);
netObjectList.erase(netID);
}
}
unsigned int MainClientState::findNearestObject(void)
{
unsigned int targetID = 0;
float distance = 1000000; // we will use this to store the closest player to us
// first we check if we actually have anyone to lock on too
if(!netObjectList.empty())
{
float x, y, z;
float ourX, ourY, ourZ;
gameMgr->getPosition(myID, ourX, ourY, ourZ);
std::map<unsigned int, unsigned int>::iterator itr;
for(itr = netObjectList.begin(); itr != netObjectList.end(); itr++)
{
unsigned int nextID = itr->second;
if(nextID != 0)
{
gameMgr->getPosition(nextID, x, y, z);
float newLength = gMgr->vectorLength(x - ourX, y - ourY, z - ourZ);
if(newLength < distance)
{
targetID = nextID;
distance = newLength;
}
}
}
}
return targetID;
}
void MainClientState::sendLockOnTarget(unsigned int objectID)
{
netMgr->clearBitSteram();
netMgr->writeUCharToBitStream((unsigned char) ID_REQUEST_LOCK_ON);
// we put our net ID
netMgr->writeUIntToBitStream(gameMgr->getResourceID(myID, "netID"));
// now we put our target net ID
netMgr->writeUIntToBitStream(gameMgr->getResourceID(objectID, "netID"));
// now we send
netMgr->sendBitStreamToAll(HIGH_PRIORITY, RELIABLE_ORDERED, 0);
}
As you can see its a mess. Still working on it.
The method addNewUser() [forth method from the bottom] is where the netObjectList map get filled.
The addNewUser() is only called in the switch case ID_ADD_CURRENT_USERS and ID_REQUST_ADD_NEW_USER inside the HandleEvents() method.
Please try as much as possible to withstand the mess.
Oh, and the code I posted is was just an example. I add it in when I start getting wrong results. It was a big surprise when I saw the result.
Hope someone can figure this out.