예제 #1
0
void GameSessionInput::selectUnit()
{
    if(!leftShiftPressed)
        unselectAll();

    vec3 clickPos = Root::shared().getDepthResult();
    vec2 clickPos2(clickPos.x, clickPos.z);

    Faction* lf = session->getLocalFaction();
    if(!lf) return;

    Unit* best_unit = 0;
    float best_distance = 100.0;

    float dist;

    for(list<Unit*>::iterator it = lf->getUnits().begin();
            it != lf->getUnits().end(); ++it)
    {
        dist = glm::distance((*it)->getPosition2(), clickPos2);
        if(dist < 2.0 * (*it)->getInfo()->radius
                && dist < best_distance) {
            best_distance = dist; 
            best_unit = (*it);
        }
    }

    if(best_unit)
    {
        SoundManager::shared().play(best_unit->getInfo()->selectionSound);
        best_unit->setSelected(true);
		if(leftControlPressed) best_unit->getDebugText();
    }
}
예제 #2
0
void GameSessionInput::selectUnits(float x_min, float x_max, float y_min, float y_max)
{
    if(!leftShiftPressed)
        unselectAll();

    Faction* lf = session->getLocalFaction();

    bool firstUnitSelected = false;
    if(!lf) return;
    for(list<Unit*>::iterator it = lf->getUnits().begin();
            it != lf->getUnits().end(); ++it)
    {
        vec2 onScreen = (*it)->getScreenPosition();

        if((onScreen.x > x_min && onScreen.x < x_max) && (onScreen.y > y_min && onScreen.y < y_max))
	   	{
            (*it)->setSelected(true);
            if(!firstUnitSelected) 
			{
				SoundManager::shared().play((*it)->getInfo()->selectionSound);
			}
            firstUnitSelected = true;
			if(leftControlPressed) (*it)->getDebugText();
        }
    }
}
예제 #3
0
void GameSessionClient::updateGameLogic(int elapsedTime)
{
    if(!localFaction) return;
    gameTimer += elapsedTime;

    //First purge units that have to be deleted
    for(auto fIter : getFactionMap())
    {
        Faction* faction = fIter.second;
        for(auto it = faction->getUnits().begin(); it != faction->getUnits().end(); )
        {
            if ((*it)->readyToDelete()) {
                delete *it;
                it = faction->getUnits().erase(it);
            } else {
                ++it;
            }
        }
    }

    //Update all units
    //mat4 vpMatrix = Arya::Locator::getRoot().getGraphics()->getCamera()->getVPMatrix();
    for(auto unitIter : getUnitMap())
    {
        Unit* unit = unitIter.second;
        //vec4 onScreen(unit->getEntity()->getPosition(), 1.0);
        //onScreen = vpMatrix * onScreen;
        //onScreen.x /= onScreen.w;
        //onScreen.y /= onScreen.w;
        //unit->setScreenPosition(vec2(onScreen.x, onScreen.y));
        unit->update(gameTimer);
    }
    for(auto unit : localFaction->getUnits())
        unit->checkForEnemies();
}
예제 #4
0
void GameSessionInput::selectAll()
{
    Faction* lf = session->getLocalFaction();
    if(!lf) return;
    for(list<Unit*>::iterator it = lf->getUnits().begin();
            it != lf->getUnits().end(); ++it)
        (*it)->setSelected(true);
}
예제 #5
0
void GameSessionInput::moveSelectedUnits()
{
    vec3 clickPos = Root::shared().getDepthResult();
    vec2 clickPos2(clickPos.x, clickPos.z);

    Faction* lf = session->getLocalFaction();
    if(!lf) return;

    // did we click on an enemy unit
    Unit* best_unit = 0;
    float best_distance = 100.0;
    //Faction* from_faction = 0;

    float dist;
    for(unsigned int j = 0; j < session->getFactions().size(); ++j) {
        if(session->getFactions()[j] == lf) continue;

        for(list<Unit*>::iterator it = session->getFactions()[j]->getUnits().begin();
                it != session->getFactions()[j]->getUnits().end(); ++it)
        {
            dist = glm::distance((*it)->getPosition2(), clickPos2);
            if(dist < (*it)->getInfo()->radius && dist < best_distance)
            {
                best_distance = dist; 
                best_unit = (*it);
            }
        }
    }

    vec2 centerPos(0,0); //average position of selected units
    vector<int> unitIds;
    vector<vec2> unitPositions;
    for(list<Unit*>::iterator it = lf->getUnits().begin(); it != lf->getUnits().end(); ++it)
        if((*it)->isSelected())
        {
            centerPos += (*it)->getPosition2();
            unitPositions.push_back((*it)->getPosition2());
            unitIds.push_back((*it)->getId());
        }

    int numSelected = unitIds.size();

    if(!numSelected) return;

    centerPos /= (float)numSelected;

    //FOR NOW: we only use pathfinding for normal walking, not for attacking
	if(best_unit)
	{
		Event& ev = Game::shared().getEventManager()->createEvent(EVENT_ATTACK_MOVE_UNIT_REQUEST);
		ev << numSelected;
		for(unsigned int i = 0; i < unitIds.size(); ++i)
			ev << unitIds[i] << best_unit->getId();

		ev.send();
	}
    else
    {
        //Movement from centerPos to clickPos
        vec2 target(clickPos.x, clickPos.z);

        //Find a path
        std::vector<vec2> pathNodes;
        //session->findPath(centerPos,target,pathNodes);
        if(pathNodes.empty()) pathNodes.push_back(target);

        //Now calculate the position of each unit relative to each other
        vector<vec2> relativePositions(unitIds.size());

        vec2 direction = glm::normalize(target - centerPos);
		vec2 perpendicular(-direction.y, direction.x); //right hand rule

		float spread = 20.0f;
		int perRow = (int)(glm::sqrt((float)numSelected) + 0.99);

		direction *= spread;
		perpendicular *= spread;

        vector<bool> unitTaken(unitIds.size(),false);
		for(int i = 0; i < numSelected; ++i)
		{
			//This loops over the target spots in such a way that it first loops the points that are furthest away.
			//When the units are coming from the BOTTOM the order is like this:
			//1 2 3
			//4 5 6
			//7 8 9
			vec2 targetSpot = target + float(perRow/2 - i/perRow)*direction + float(i%perRow - perRow/2)*perpendicular;
			//Select closest unit
			int bestIndex = -1;
			float bestDistance = 0;
			for(int j = 0; j < numSelected; ++j)
			{
                if(unitTaken[j]) continue;
				float dist = glm::distance(unitPositions[j],targetSpot);
				if(bestIndex == -1 || dist < bestDistance)
				{
					bestIndex = j;
					bestDistance = dist;
				}
			}
            relativePositions[bestIndex] = targetSpot - target;
            unitTaken[bestIndex] = true;
		}

        //Relative positions to center have been calculated. Now send the packet
        Event& ev = Game::shared().getEventManager()->createEvent(EVENT_MOVE_UNIT_REQUEST);
        ev << numSelected;
        for(int i = 0; i < numSelected; ++i)
        {
            ev << unitIds[i];
            ev << (int)pathNodes.size();
            for(unsigned int j = 0; j < pathNodes.size(); ++j)
            {
                ev << pathNodes[j] + relativePositions[i];
            }
        }
		ev.send();
	}
}
예제 #6
0
void Server::handlePacket(ServerClientHandler* clienthandler, Packet& packet)
{
    clientIterator iter = clientList.find(clienthandler);
    if(iter == clientList.end())
    {
        LOG_WARNING("Received packet from unkown client!");
        return;
    }
    ServerClient* client = iter->second;

    switch(packet.getId()){
        case EVENT_JOIN_GAME:
            {
                client->setClientId(clientIdFactory++); Packet* pak = createPacket(EVENT_CLIENT_ID); *pak << client->getClientId(); clienthandler->sendPacket(pak); 
                //Create faction 
                client->createFaction();
                client->createStartUnits();

                int joinedCount = 0;
                for(clientIterator iter = clientList.begin(); iter != clientList.end(); ++iter)
                {
                    if( iter->second->getClientId() != -1 ) ++joinedCount;
                }

                LOG_INFO("Clients joined: " << joinedCount);
                if(joinedCount >= 1)
                {
                    pak = createPacket(EVENT_GAME_READY);
                    //Send to all clients
                    sendToAllClients(pak);

                    pak = createPacket(EVENT_GAME_FULLSTATE);

                    //------------------------------------
                    // Package structure:
                    // + joinedCount
                    //   - clientID
                    //   - Serialized faction
                    //      + UnitCount
                    //      - Serialized unit 
                    //------------------------------------

                    *pak << joinedCount; //player count

                    //for each player:
                    for(clientIterator iter = clientList.begin(); iter != clientList.end(); ++iter)
                    {
                        if(iter->second->getClientId() == -1) continue;

                        *pak << iter->second->getClientId();

                        Faction* faction = iter->second->getFaction();
                        faction->serialize(*pak);

                        int unitCount = (int)faction->getUnits().size();

                        *pak << unitCount;
                        for(std::list<Unit*>::iterator iter = faction->getUnits().begin(); iter != faction->getUnits().end(); ++iter)
                            (*iter)->serialize(*pak);
                    }

                    sendToAllClients(pak);
                }
                break;
            }

        default:
            LOG_INFO("Unknown package received..");
            break;
    }

    return;
}