Esempio n. 1
0
bool GameSession::init()
{
    Game::shared().getEventManager()->addEventHandler(EVENT_GAME_FULLSTATE, this);

    input = new GameSessionInput(this);
    input->init();

    if(!initShaders()) return false;
    if(!initVertices()) return false;

    Root::shared().addInputListener(input);
    Root::shared().addFrameListener(input);
    Root::shared().addFrameListener(this);

    // init factions
    localFaction = new Faction;
    localFaction->setColor(0);
    factions.push_back(localFaction);

    Faction* otherFaction = new Faction;
    otherFaction->setColor(1);
    factions.push_back(otherFaction);

    Scene* scene = Root::shared().makeDefaultScene();
    if(!scene)
        return false;

    Camera* cam = scene->getCamera();

    cam->setPosition(vec3(0.0f, 150.0f, 0.0f));
    cam->setCameraAngle(0.0f, -60.0f);
    cam->setZoom(300.0f);

    Object* obj;

    // init map
    vector<Arya::Material*> tileSet;
    tileSet.push_back(Arya::MaterialManager::shared().getMaterial("grass.tga"));
    tileSet.push_back(Arya::MaterialManager::shared().getMaterial("rock.tga"));
    tileSet.push_back(Arya::MaterialManager::shared().getMaterial("snow.tga"));
    tileSet.push_back(Arya::MaterialManager::shared().getMaterial("dirt.tga"));
	vector<Arya::Texture*> skyset;
	skyset.push_back(Arya::TextureManager::shared().getTexture("transparentClouds.png"));
	skyset.push_back(Arya::TextureManager::shared().getTexture("stars.jpg"));
    if(!scene->setMap("heightmap.raw", "watermap.raw", tileSet, skyset, Arya::TextureManager::shared().getTexture("splatmap.tga")))
        return false;

    for(int i = 0; i < 30; ++ i) 
    {
        Unit* unit = new Unit(0);
        float heightModel = Root::shared().getScene()->getMap()->getTerrain()->heightAtGroundPosition(20.0f * (i / 10), -50.0f+20.0f*(i % 10));
        obj = scene->createObject();
        obj->setModel(ModelManager::shared().getModel("ogros.aryamodel"));
        obj->setAnimation("stand");
        unit->setObject(obj);
        unit->setPosition(vec3(20 * (i / 10), heightModel, -50 + 20 * (i % 10)));

        localFaction->addUnit(unit);
    }

    for(int i = 0; i < 30; ++ i) 
    {
        Unit* unit = new Unit(0);
        float heightModel = Root::shared().getScene()->getMap()->getTerrain()->heightAtGroundPosition(-100.0f + 20.0f * (i / 10), -100.0f+20.0f*(i % 10));
        obj = scene->createObject();
        obj->setModel(ModelManager::shared().getModel("ogros.aryamodel"));
        obj->setAnimation("stand");
        unit->setObject(obj);
        unit->setPosition(vec3(-100.0 + 20 * (i / 10), heightModel, -100.0 + 20 * (i % 10)));

        otherFaction->addUnit(unit);
    }

    for(int i = 0; i < 10; ++ i) 
    {
        Unit* unit = new Unit(1);
        float heightModel = Root::shared().getScene()->getMap()->getTerrain()->heightAtGroundPosition(-200.0f + 20.0f * (i / 10), -50.0f+20.0f*(i % 10));
        obj = scene->createObject();
        obj->setModel(ModelManager::shared().getModel("hep.aryamodel"));
        obj->setAnimation("stand");
        unit->setObject(obj);
        unit->setPosition(vec3(-200.0f + 20 * (i / 10), heightModel, -50 + 20 * (i % 10)));

        localFaction->addUnit(unit);
    }

    selectionDecalHandle = 0;
    Texture* selectionTex = TextureManager::shared().getTexture("selection.png");
    if(selectionTex) selectionDecalHandle = selectionTex->handle;

    return true;
}
Esempio n. 2
0
void ClientGameSession::handleEvent(Packet& packet)
{
	int id = packet.getId();
	switch(id)
	{
		case EVENT_GAME_FULLSTATE:
			{
                int newGameTime;
                packet >> newGameTime;

                GAME_LOG_DEBUG("Full game state received. Old gametimer = " << gameTimer << ". New server gametime = " << newGameTime << ". Estimated delay = " << Game::shared().getNetworkDelay());

                //Round the delay to 10 ms so that the game timer is always a multiple of 10 ms
                gameTimer = newGameTime + ((int)(Game::shared().getNetworkDelay()*1000)/10)*10;

				int count;
				packet >> count;
				for(int i = 0; i < count; ++i)
				{
					int clientId;
					packet >> clientId;

					int factionId;
					packet >> factionId;

					Faction* faction = getFactionById(factionId);
					if(!faction)
					{
						faction = createFaction(factionId);
						factions.push_back(faction);
					}

					faction->deserialize(packet);
					faction->setClientId(clientId);

					if(clientId == Game::shared().getClientId())
						localFaction = faction;

					//If any of the units that we have was NOT sent in this list they must be deleted
					//So we keep a list of IDs that we have and check which ones are in the packet
					//This method might be a bit slow but this process only happens in rare situations
					//so we do not bother adding extra member variables to the unit class to accomplish this
					vector<int> allIDs;
					for(list<Unit*>::iterator it = factions[i]->getUnits().begin(); it != factions[i]->getUnits().end(); ++it)
						allIDs.push_back((*it)->getId());

					int unitCount;
					packet >> unitCount;
					for(int i = 0; i < unitCount; ++i)
					{
						int id;
						packet >> id;

						for(vector<int>::iterator iter = allIDs.begin(); iter != allIDs.end(); ++iter)
							if( *iter == id ){ allIDs.erase(iter); break; }

						Unit* unit = getUnitById(id);
						bool newUnit = false;
						if(!unit)
						{
							newUnit = true;
							unit = createUnit(id, 0);
						}
						unit->deserialize(packet);

						if(faction == localFaction) unit->setLocal(true);

						Object* obj = unit->getObject();
						if(!obj) obj = Root::shared().getScene()->createObject();

						obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
						obj->setAnimation("stand");

						unit->setObject(obj);

						float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);

						unit->setPosition(vec3(unit->getPosition().x,
									heightModel,
									unit->getPosition().z));

						if(newUnit) faction->addUnit(unit);
						if(unit->getType() == 2 && faction == localFaction)
						{
							input->setSpecPos(unit->getPosition());
						}

						unit->getInfo()->onSpawn(unit);
					}

					//now allIDs contains a list of units that were not in the packet so they must be deleted
					//note that we can not just delete them because of reference counts and so on.
					//we make them obsolte so that they are deleted next frame
					for(vector<int>::iterator iter = allIDs.begin(); iter != allIDs.end(); ++iter)
					{
						Unit* unit = getUnitById(*iter); //if unit == 0 then there are some serious issues ;)
						if(unit) unit->markForDelete();
					}

				}
				rebuildCellList();
			}
			break;

		case EVENT_CLIENT_CONNECTED:
			{
				int clientId;
				packet >> clientId;

				int factionId;
				packet >> factionId;

				Faction* faction = createFaction(clientId);
				faction->deserialize(packet);
				faction->setClientId(clientId);
				factions.push_back(faction);

				if(clientId == Game::shared().getClientId())
					localFaction = faction;

				int unitCount;
				packet >> unitCount;
				for(int i = 0; i < unitCount; ++i)
				{
					int id;
					packet >> id;
					Unit* unit = createUnit(id, 0);
					unit->deserialize(packet);

					if(faction == localFaction) unit->setLocal(true);

					Object* obj = Root::shared().getScene()->createObject();
					obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
					obj->setAnimation("stand");

					unit->setObject(obj);

					float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);

					unit->setPosition(vec3(unit->getPosition().x,
								heightModel,
								unit->getPosition().z));

					faction->addUnit(unit);
				}
			}
			break;

		case EVENT_CLIENT_DISCONNECTED:
			{
				int id;
				packet >> id;
				GAME_LOG_INFO("Client " << id << " disconnected.");
				for(vector<Faction*>::iterator iter = factions.begin(); iter != factions.end(); ++iter)
				{
					if( (*iter)->getClientId() == id )
					{
						GAME_LOG_INFO("Client " << id << " removed from game session. NOT removing faction!");
						//delete *iter;
						//iter = factions.erase(iter);
						break;
					}
				}
			}
			break;

		case EVENT_MOVE_UNIT: {
                                  int timeStamp;
                                  packet >> timeStamp;

								  int numUnits;
								  packet >> numUnits;

                                  GAME_LOG_DEBUG("Move packet for " << numUnits << " units. " << (gameTimer - timeStamp) << " ms delay. Sent at server-gametime " << timeStamp << ". Recieved at client-gametime " << gameTimer);

								  int unitId;
                                  int nodeCount;
                                  vec2 pos;
                                  float yaw;
                                  vec2 tempPos;
                                  vector<vec2> pathNodes;
								  for(int i = 0; i < numUnits; ++i)
                                  {
									  packet >> unitId;
                                      packet >> pos;
                                      packet >> yaw;
                                      packet >> nodeCount;
                                      pathNodes.clear();
                                      for(int i = 0; i < nodeCount; ++i){ packet >> tempPos; pathNodes.push_back(tempPos); }
									  Unit* unit = getUnitById(unitId);
                                      if(unit) unit->setUnitMovement(timeStamp, pos, yaw, pathNodes);
								  }
								  break;
							  }

		case EVENT_ATTACK_MOVE_UNIT:
							  {
                                  int timeStamp;
                                  packet >> timeStamp;

								  int numUnits;
								  packet >> numUnits;

								  int unitId, targetUnitId;
								  for(int i = 0; i < numUnits; ++i) {
									  packet >> unitId >> targetUnitId;
									  Unit* unit = getUnitById(unitId);
									  Unit* targetUnit = getUnitById(targetUnitId);
									  if(unit && targetUnit) unit->setTargetUnit(timeStamp, targetUnit);
								  }

								  break;
							  }

		case EVENT_UNIT_DIED:
							  {
								  int id;
								  packet >> id;
								  Unit* unit = getUnitById(id);
								  if(unit)
								  {
									  unit->makeDead();
									  unit->getInfo()->onDeath(unit);
								  }
							  }
							  break;

		case EVENT_UNIT_SPAWNED:
							  {
								  int factionId, unitId;
								  packet >> factionId >> unitId;
								  Faction* faction = getFactionById(factionId);
								  if(!faction)
								  {
									  GAME_LOG_WARNING("Unit spawn packet received for invalid faction!");
								  }
								  else
								  {
									  Unit* unit = getUnitById(unitId);
									  bool newUnit = false;
									  if(unit)
										  GAME_LOG_WARNING("Spawn packet for unit that already existed");
									  else
									  {
										  newUnit = true;
										  unit = createUnit(unitId, 0);
									  }
									  unit->deserialize(packet);
									  if(faction == localFaction) unit->setLocal(true);
									  if(newUnit) unit->setCellFromList(unitCells);

									  Object* obj = unit->getObject();
									  if(!obj) obj = Root::shared().getScene()->createObject();
									  obj->setModel(ModelManager::shared().getModel(unit->getInfo()->modelname + ".aryamodel"));
									  obj->setAnimation("stand");
									  unit->setObject(obj);

									  float heightModel = map->heightAtGroundPosition(unit->getPosition().x, unit->getPosition().z);
									  unit->setPosition(vec3(unit->getPosition().x, heightModel, unit->getPosition().z));

									  //This must happen after the object is set, because
									  //then it will set the correct tint color
									  if(newUnit) faction->addUnit(unit);

									  unit->getInfo()->onSpawn(unit);
								  }
							  }
							  break;

		case EVENT_PLAYER_DEFEAT:
							  {
								  int factionID;
								  packet >> factionID;
								  LOG_INFO("Player lost: " << factionID + 1);
								  Arya::SoundManager::shared().play("defeat.wav");
							  }
							  break;

		case EVENT_PLAYER_VICTORY:
							  {
								  int factionID;
								  packet >> factionID;
								  LOG_INFO("Game won by player: " << factionID + 1);
								  Arya::SoundManager::shared().play("victory.wav");
							  }
							  break;

		default:
							  GAME_LOG_INFO("ClientGameSession: unknown event received! (" << id << ")");
							  break;
	}
}