Esempio n. 1
0
void StackZone::reorganizeCards()
{
	if (!cards.isEmpty()) {
		QList<ArrowItem *> arrowsToUpdate;
		
		const int cardCount = cards.size();
		qreal totalWidth = boundingRect().width();
		qreal totalHeight = boundingRect().height();
		qreal cardWidth = cards.at(0)->boundingRect().width();
		qreal cardHeight = cards.at(0)->boundingRect().height();
		qreal xspace = 5;
		qreal x1 = xspace;
		qreal x2 = totalWidth - xspace - cardWidth;
	
		for (int i = 0; i < cardCount; i++) {
			CardItem *c = cards.at(i);
			qreal x = i % 2 ? x2 : x1;
			// If the total height of the cards is smaller than the available height,
			// the cards do not need to overlap and are displayed in the center of the area.
			if (cardHeight * cardCount > totalHeight)
				c->setPos(x, ((qreal) i) * (totalHeight - cardHeight) / (cardCount - 1));
			else
				c->setPos(x, ((qreal) i) * cardHeight + (totalHeight - cardCount * cardHeight) / 2);
			c->setRealZValue(i);
			
			arrowsToUpdate.append(c->getArrowsFrom());
			arrowsToUpdate.append(c->getArrowsTo());
		}
		QSetIterator<ArrowItem *> arrowIterator(QSet<ArrowItem *>::fromList(arrowsToUpdate));
		while (arrowIterator.hasNext())
			arrowIterator.next()->updatePath();
	}
	update();
}
ResponseCode Server_ProtocolHandler::cmdCreateArrow(Command_CreateArrow *cmd, CommandContainer *cont, Server_Game *game, Server_Player *player)
{
	if (player->getSpectator())
		return RespFunctionNotAllowed;
	
	if (!game->getGameStarted())
		return RespGameNotStarted;
		
	Server_Player *startPlayer = game->getPlayer(cmd->getStartPlayerId());
	Server_Player *targetPlayer = game->getPlayer(cmd->getTargetPlayerId());
	if (!startPlayer || !targetPlayer)
		return RespNameNotFound;
	Server_CardZone *startZone = startPlayer->getZones().value(cmd->getStartZone());
	bool playerTarget = cmd->getTargetZone().isEmpty();
	Server_CardZone *targetZone = 0;
	if (!playerTarget)
		targetZone = targetPlayer->getZones().value(cmd->getTargetZone());
	if (!startZone || (!targetZone && !playerTarget))
		return RespNameNotFound;
	if (startZone->getType() != PublicZone)
		return RespContextError;
	Server_Card *startCard = startZone->getCard(cmd->getStartCardId(), false);
	if (!startCard)
		return RespNameNotFound;
	Server_Card *targetCard = 0;
	if (!playerTarget) {
		if (targetZone->getType() != PublicZone)
			return RespContextError;
		targetCard = targetZone->getCard(cmd->getTargetCardId(), false);
	}
	
	Server_ArrowTarget *targetItem;
	if (playerTarget)
		targetItem = targetPlayer;
	else
		targetItem = targetCard;
	if (!targetItem)
		return RespNameNotFound;

	QMapIterator<int, Server_Arrow *> arrowIterator(player->getArrows());
	while (arrowIterator.hasNext()) {
		Server_Arrow *temp = arrowIterator.next().value();
		if ((temp->getStartCard() == startCard) && (temp->getTargetItem() == targetItem))
			return RespContextError;
	}
	
	Server_Arrow *arrow = new Server_Arrow(player->newArrowId(), startCard, targetItem, cmd->getColor());
	player->addArrow(arrow);
	game->sendGameEvent(new Event_CreateArrows(player->getPlayerId(), QList<ServerInfo_Arrow *>() << new ServerInfo_Arrow(
		arrow->getId(),
		startPlayer->getPlayerId(),
		startZone->getName(),
		startCard->getId(),
		targetPlayer->getPlayerId(),
		cmd->getTargetZone(),
		cmd->getTargetCardId(),
		cmd->getColor()
	)));
	return RespOk;
}
Esempio n. 3
0
void TableZone::reorganizeCards()
{
    QList<ArrowItem *> arrowsToUpdate;
    
    // Calculate card stack widths so mapping functions work properly
    computeCardStackWidths();

    for (int i = 0; i < cards.size(); ++i) {
        QPoint gridPoint = cards[i]->getGridPos();
        if (gridPoint.x() == -1)
            continue;
        
        QPointF mapPoint = mapFromGrid(gridPoint);
        qreal x = mapPoint.x();
        qreal y = mapPoint.y();
        
        int numberAttachedCards = cards[i]->getAttachedCards().size();
        qreal actualX = x + numberAttachedCards * STACKED_CARD_OFFSET_X;
        qreal actualY = y;
        if (numberAttachedCards)
            actualY += 15;
        
        cards[i]->setPos(actualX, actualY);
        cards[i]->setRealZValue((actualY + CARD_HEIGHT) * 100000 + (actualX + 1) * 100);
        
        QListIterator<CardItem *> attachedCardIterator(cards[i]->getAttachedCards());
        int j = 0;
        while (attachedCardIterator.hasNext()) {
            ++j;
            CardItem *attachedCard = attachedCardIterator.next();
            qreal childX = actualX - j * STACKED_CARD_OFFSET_X;
            qreal childY = y + 5;
            attachedCard->setPos(childX, childY);
            attachedCard->setRealZValue((childY + CARD_HEIGHT) * 100000 + (childX + 1) * 100);

            arrowsToUpdate.append(attachedCard->getArrowsFrom());
            arrowsToUpdate.append(attachedCard->getArrowsTo());
        }
        
        arrowsToUpdate.append(cards[i]->getArrowsFrom());
        arrowsToUpdate.append(cards[i]->getArrowsTo());
    }

    QSetIterator<ArrowItem *> arrowIterator(QSet<ArrowItem *>::fromList(arrowsToUpdate));
    while (arrowIterator.hasNext())
        arrowIterator.next()->updatePath();
    
    resizeToContents();
    update();
}
Esempio n. 4
0
void Server_Player::clearZones()
{
	QMapIterator<QString, Server_CardZone *> zoneIterator(zones);
	while (zoneIterator.hasNext())
		delete zoneIterator.next().value();
	zones.clear();

	QMapIterator<int, Server_Counter *> counterIterator(counters);
	while (counterIterator.hasNext())
		delete counterIterator.next().value();
	counters.clear();
	
	QMapIterator<int, Server_Arrow *> arrowIterator(arrows);
	while (arrowIterator.hasNext())
		delete arrowIterator.next().value();
	arrows.clear();
}
Esempio n. 5
0
ResponseCode Server_Player::moveCard(CommandContainer *cont, Server_CardZone *startzone, const QList<int> &_cardIds, Server_CardZone *targetzone, int x, int y, bool faceDown, bool tapped)
{
	// Disallow controller change to other zones than the table.
	if (((targetzone->getType() != PublicZone) || !targetzone->hasCoords()) && (startzone->getPlayer() != targetzone->getPlayer()))
		return RespContextError;
	
	if (!targetzone->hasCoords() && (x == -1))
		x = targetzone->cards.size();
	
	QList<QPair<Server_Card *, int> > cardsToMove;
	for (int i = 0; i < _cardIds.size(); ++i) {
		int position;
		Server_Card *card = startzone->getCard(_cardIds[i], false, &position);
		if (!card)
			return RespNameNotFound;
		if (!card->getAttachedCards().isEmpty() && !targetzone->isColumnEmpty(x, y))
			return RespContextError;
		cardsToMove.append(QPair<Server_Card *, int>(card, position));
	}
	
	MoveCardCompareFunctor cmp(startzone == targetzone ? -1 : x);
	qSort(cardsToMove.begin(), cardsToMove.end(), cmp);
	
	bool secondHalf = false;
	int xIndex = -1;
	for (int cardIndex = 0; cardIndex < cardsToMove.size(); ++cardIndex) {
		Server_Card *card = cardsToMove[cardIndex].first;
		int originalPosition = cardsToMove[cardIndex].second;
		int position = startzone->removeCard(card);
		if ((startzone == targetzone) && !startzone->hasCoords()) {
			if (!secondHalf && (originalPosition < x)) {
				xIndex = -1;
				secondHalf = true;
			} else if (secondHalf)
				--xIndex;
			else
				++xIndex;
		} else
			++xIndex;
		int newX = x + xIndex;
		
		// Attachment relationships can be retained when moving a card onto the opponent's table
		if (startzone->getName() != targetzone->getName()) {
			// Delete all attachment relationships
			if (card->getParentCard())
				card->setParentCard(0);
			
			// Make a copy of the list because the original one gets modified during the loop
			QList<Server_Card *> attachedCards = card->getAttachedCards();
			for (int i = 0; i < attachedCards.size(); ++i)
				attachedCards[i]->getZone()->getPlayer()->unattachCard(cont, attachedCards[i]);
		}
		
		if (startzone != targetzone) {
			// Delete all arrows from and to the card
			const QList<Server_Player *> &players = game->getPlayers().values();
			for (int i = 0; i < players.size(); ++i) {
				QList<int> arrowsToDelete;
				QMapIterator<int, Server_Arrow *> arrowIterator(players[i]->getArrows());
				while (arrowIterator.hasNext()) {
					Server_Arrow *arrow = arrowIterator.next().value();
					if ((arrow->getStartCard() == card) || (arrow->getTargetItem() == card))
						arrowsToDelete.append(arrow->getId());
				}
				for (int j = 0; j < arrowsToDelete.size(); ++j)
					players[i]->deleteArrow(arrowsToDelete[j]);
			}
		}
		
		if (card->getDestroyOnZoneChange() && (startzone != targetzone)) {
			cont->enqueueGameEventPrivate(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId());
			cont->enqueueGameEventPublic(new Event_DestroyCard(getPlayerId(), startzone->getName(), card->getId()), game->getGameId());
			card->deleteLater();
		} else {
			if (!targetzone->hasCoords()) {
				y = 0;
				card->resetState();
			} else
				newX = targetzone->getFreeGridColumn(newX, y, card->getName());
		
			targetzone->insertCard(card, newX, y);
		
			bool targetBeingLookedAt = (targetzone->getType() != HiddenZone) || (targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1);
			bool sourceBeingLookedAt = (startzone->getType() != HiddenZone) || (startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1);
		
			bool targetHiddenToPlayer = faceDown || !targetBeingLookedAt;
			bool targetHiddenToOthers = faceDown || (targetzone->getType() != PublicZone);
			bool sourceHiddenToPlayer = card->getFaceDown() || !sourceBeingLookedAt;
			bool sourceHiddenToOthers = card->getFaceDown() || (startzone->getType() != PublicZone);
		
			QString privateCardName, publicCardName;
			if (!(sourceHiddenToPlayer && targetHiddenToPlayer))
				privateCardName = card->getName();
			if (!(sourceHiddenToOthers && targetHiddenToOthers))
				publicCardName = card->getName();
		
			int oldCardId = card->getId();
			if (faceDown)
				card->setId(newCardId());
			card->setFaceDown(faceDown);
		
			// The player does not get to see which card he moved if it moves between two parts of hidden zones which
			// are not being looked at.
			int privateNewCardId = card->getId();
			int privateOldCardId = oldCardId;
			if (!targetBeingLookedAt && !sourceBeingLookedAt) {
				privateOldCardId = -1;
				privateNewCardId = -1;
				privateCardName = QString();
			}
			int privatePosition = -1;
			if (startzone->getType() == HiddenZone)
				privatePosition = position;
			cont->enqueueGameEventPrivate(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, privateNewCardId, faceDown), game->getGameId());
			cont->enqueueGameEventOmniscient(new Event_MoveCard(getPlayerId(), privateOldCardId, privateCardName, startzone->getName(), privatePosition, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, privateNewCardId, faceDown), game->getGameId());
			
			// Other players do not get to see the start and/or target position of the card if the respective
			// part of the zone is being looked at. The information is not needed anyway because in hidden zones,
			// all cards are equal.
			if (
				((startzone->getType() == HiddenZone) && ((startzone->getCardsBeingLookedAt() > position) || (startzone->getCardsBeingLookedAt() == -1)))
				|| (startzone->getType() == PublicZone)
			)
				position = -1;
			if ((targetzone->getType() == HiddenZone) && ((targetzone->getCardsBeingLookedAt() > newX) || (targetzone->getCardsBeingLookedAt() == -1)))
				newX = -1;
		
			if ((startzone->getType() == PublicZone) || (targetzone->getType() == PublicZone))
				cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), oldCardId, publicCardName, startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, card->getId(), faceDown), game->getGameId());
			else
				cont->enqueueGameEventPublic(new Event_MoveCard(getPlayerId(), -1, QString(), startzone->getName(), position, targetzone->getPlayer()->getPlayerId(), targetzone->getName(), newX, y, -1, false), game->getGameId());
			
			if (tapped)
				setCardAttrHelper(cont, targetzone->getName(), card->getId(), "tapped", "1");
		}
	}
	if (startzone->hasCoords())
		startzone->fixFreeSpaces(cont);
	
	return RespOk;
}
Esempio n. 6
0
void TableZone::reorganizeCards()
{
    QList<ArrowItem *> arrowsToUpdate;
    
    // Calculate table grid distortion so that the mapping functions work properly
    QMap<int, int> gridPointStackCount;
    for (int i = 0; i < cards.size(); ++i) {
        const QPoint &gridPoint = cards[i]->getGridPos();
        if (gridPoint.x() == -1)
            continue;
        
        const int key = gridPoint.x() / 3 + gridPoint.y() * 1000;
        gridPointStackCount.insert(key, gridPointStackCount.value(key, 0) + 1);
    }
    gridPointWidth.clear();
    for (int i = 0; i < cards.size(); ++i) {
        const QPoint &gridPoint = cards[i]->getGridPos();
        if (gridPoint.x() == -1)
            continue;
        
        const int key = gridPoint.x() / 3 + gridPoint.y() * 1000;
        const int stackCount = gridPointStackCount.value(key, 0);
        if (stackCount == 1)
            gridPointWidth.insert(key, CARD_WIDTH * (1 + cards[i]->getAttachedCards().size() / 3.0));
        else
            gridPointWidth.insert(key, CARD_WIDTH * (1 + (stackCount - 1) / 3.0));
    }
    
    for (int i = 0; i < cards.size(); ++i) {
        QPoint gridPoint = cards[i]->getGridPos();
        if (gridPoint.x() == -1)
            continue;
        
        QPointF mapPoint = mapFromGrid(gridPoint);
        qreal x = mapPoint.x();
        qreal y = mapPoint.y();
        
        int numberAttachedCards = cards[i]->getAttachedCards().size();
        qreal actualX = x + numberAttachedCards * CARD_WIDTH / 3.0;
        qreal actualY = y;
        if (numberAttachedCards)
            actualY += 15;
        
        cards[i]->setPos(actualX, actualY);
        cards[i]->setRealZValue((actualY + CARD_HEIGHT) * 100000 + (actualX + 1) * 100);
        
        QListIterator<CardItem *> attachedCardIterator(cards[i]->getAttachedCards());
        int j = 0;
        while (attachedCardIterator.hasNext()) {
            ++j;
            CardItem *attachedCard = attachedCardIterator.next();
            qreal childX = actualX - j * CARD_WIDTH / 3.0;
            qreal childY = y + 5;
            attachedCard->setPos(childX, childY);
            attachedCard->setRealZValue((childY + CARD_HEIGHT) * 100000 + (childX + 1) * 100);

            arrowsToUpdate.append(attachedCard->getArrowsFrom());
            arrowsToUpdate.append(attachedCard->getArrowsTo());
        }
        
        arrowsToUpdate.append(cards[i]->getArrowsFrom());
        arrowsToUpdate.append(cards[i]->getArrowsTo());
    }

    QSetIterator<ArrowItem *> arrowIterator(QSet<ArrowItem *>::fromList(arrowsToUpdate));
    while (arrowIterator.hasNext())
        arrowIterator.next()->updatePath();
    
    resizeToContents();
    update();
}