[Game][Arrows] Split Arrows into ArrowData and ArrowItem (#6918)

* [Game][Arrows] Split Arrows into ArrowData and ArrowItem

Took 13 minutes

Took 5 seconds

Took 1 minute

Took 26 seconds

* Address comments.

Took 17 minutes

Took 9 seconds


Took 1 minute

* Change check.

Took 3 minutes

* Pass by const reference.

Took 10 minutes

* Remove extra method

Took 2 minutes

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-05-21 20:31:14 +02:00 committed by GitHub
parent bddf9bd818
commit 491d1c9187
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 337 additions and 327 deletions

View file

@ -2,9 +2,11 @@
#include "../../game_graphics/zones/view_zone.h"
#include "../../interface/widgets/tabs/tab_game.h"
#include "../board/arrow_data.h"
#include "../board/arrow_item.h"
#include "../board/card_item.h"
#include "../board/card_list.h"
#include "libcockatrice/utility/color.h"
#include "player_actions.h"
#include "player_logic.h"
@ -90,25 +92,43 @@ void PlayerEventHandler::eventRollDie(const Event_RollDie &event)
void PlayerEventHandler::eventCreateArrow(const Event_CreateArrow &event)
{
ArrowItem *arrow = player->addArrow(event.arrow_info());
if (!arrow) {
return;
const ArrowData data = ArrowData::fromProto(event.arrow_info());
// Resolve names for logging
const auto &playerList = player->getGame()->getPlayerManager()->getPlayers();
PlayerLogic *startPlayer = playerList.value(data.startPlayerId);
PlayerLogic *targetPlayer = playerList.value(data.targetPlayerId);
QString startCardName, targetCardName;
if (startPlayer) {
auto *zone = startPlayer->getZones().value(data.startZone);
if (zone) {
if (auto *card = zone->getCard(data.startCardId)) {
startCardName = card->getName();
}
}
}
if (!data.isPlayerTargeted() && targetPlayer) {
auto *zone = targetPlayer->getZones().value(data.targetZone);
if (zone) {
if (auto *card = zone->getCard(data.targetCardId)) {
targetCardName = card->getName();
}
}
}
auto *startCard = static_cast<CardItem *>(arrow->getStartItem());
auto *targetCard = qgraphicsitem_cast<CardItem *>(arrow->getTargetItem());
if (targetCard) {
emit logCreateArrow(player, startCard->getOwner(), startCard->getName(), targetCard->getOwner(),
targetCard->getName(), false);
} else {
emit logCreateArrow(player, startCard->getOwner(), startCard->getName(), arrow->getTargetItem()->getOwner(),
QString(), true);
emit player->arrowCreateRequested(data);
const bool validForLogging = !startCardName.isEmpty() && (data.isPlayerTargeted() || !targetCardName.isEmpty());
if (startPlayer && targetPlayer && validForLogging) {
emit logCreateArrow(player, startPlayer, startCardName, targetPlayer, targetCardName, data.isPlayerTargeted());
}
}
void PlayerEventHandler::eventDeleteArrow(const Event_DeleteArrow &event)
{
player->delArrow(event.arrow_id());
emit player->arrowDeleteRequested(event.arrow_id());
}
void PlayerEventHandler::eventCreateToken(const Event_CreateToken &event)
@ -352,28 +372,7 @@ void PlayerEventHandler::eventMoveCard(const Event_MoveCard &event, const GameEv
targetZone->addCard(card, true, x, y);
// Look at all arrows from and to the card.
// If the card was moved to another zone, delete the arrows, otherwise update them.
QMapIterator<int, PlayerLogic *> playerIterator(player->getGame()->getPlayerManager()->getPlayers());
while (playerIterator.hasNext()) {
PlayerLogic *p = playerIterator.next().value();
QList<ArrowItem *> arrowsToDelete;
QMapIterator<int, ArrowItem *> arrowIterator(p->getArrows());
while (arrowIterator.hasNext()) {
ArrowItem *arrow = arrowIterator.next().value();
if ((arrow->getStartItem() == card) || (arrow->getTargetItem() == card)) {
if (startZone == targetZone) {
arrow->updatePath();
} else {
arrowsToDelete.append(arrow);
}
}
}
for (auto &i : arrowsToDelete) {
i->delArrow();
}
}
emit cardZoneChanged(card, startZone == targetZone);
player->getPlayerMenu()->updateCardMenu(card);
if (player->getPlayerActions()->isMovingCardsUntil() && startZoneString == ZoneNames::DECK &&

View file

@ -82,6 +82,7 @@ signals:
bool isLentToAnotherPlayer = false);
void logAlwaysRevealTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
void logAlwaysLookAtTopCard(PlayerLogic *player, CardZoneLogic *zone, bool reveal);
void cardZoneChanged(CardItem *card, bool sameZone);
public:
PlayerEventHandler(PlayerLogic *player);

View file

@ -74,7 +74,7 @@ PlayerLogic::~PlayerLogic()
void PlayerLogic::clear()
{
clearArrows();
emit arrowsCleared();
QMapIterator<QString, CardZoneLogic *> i(zones);
while (i.hasNext()) {
@ -115,7 +115,7 @@ void PlayerLogic::processPlayerInfo(const ServerInfo_Player &info)
/* HandZone */
ZoneNames::HAND};
clearCounters();
clearArrows();
emit arrowsCleared();
QMutableMapIterator<QString, CardZoneLogic *> zoneIt(zones);
while (zoneIt.hasNext()) {
@ -231,7 +231,7 @@ void PlayerLogic::processCardAttachment(const ServerInfo_Player &info)
const int arrowListSize = info.arrow_list_size();
for (int i = 0; i < arrowListSize; ++i) {
addArrow(info.arrow_list(i));
emit arrowCreateRequested(ArrowData::fromProto(info.arrow_list(i)));
}
}
@ -340,75 +340,6 @@ void PlayerLogic::incrementAllCardCounters()
}
}
ArrowItem *PlayerLogic::addArrow(const ServerInfo_Arrow &arrow)
{
const QMap<int, PlayerLogic *> &playerList = game->getPlayerManager()->getPlayers();
PlayerLogic *startPlayer = playerList.value(arrow.start_player_id(), 0);
PlayerLogic *targetPlayer = playerList.value(arrow.target_player_id(), 0);
if (!startPlayer || !targetPlayer) {
return nullptr;
}
CardZoneLogic *startZone = startPlayer->getZones().value(QString::fromStdString(arrow.start_zone()), 0);
CardZoneLogic *targetZone = nullptr;
if (arrow.has_target_zone()) {
targetZone = targetPlayer->getZones().value(QString::fromStdString(arrow.target_zone()), 0);
}
if (!startZone || (!targetZone && arrow.has_target_zone())) {
return nullptr;
}
CardItem *startCard = startZone->getCard(arrow.start_card_id());
CardItem *targetCard = nullptr;
if (targetZone) {
targetCard = targetZone->getCard(arrow.target_card_id());
}
if (!startCard || (!targetCard && arrow.has_target_card_id())) {
return nullptr;
}
if (targetCard) {
return addArrow(arrow.id(), startCard, targetCard, convertColorToQColor(arrow.arrow_color()));
} else {
return addArrow(arrow.id(), startCard, targetPlayer->getGraphicsItem()->getPlayerTarget(),
convertColorToQColor(arrow.arrow_color()));
}
}
ArrowItem *PlayerLogic::addArrow(int arrowId, CardItem *startCard, ArrowTarget *targetItem, const QColor &color)
{
auto *arrow = new ArrowItem(this, arrowId, startCard, targetItem, color);
arrows.insert(arrowId, arrow);
getGameScene()->addItem(arrow);
return arrow;
}
void PlayerLogic::delArrow(int arrowId)
{
ArrowItem *arr = arrows.value(arrowId, 0);
if (!arr) {
return;
}
arr->delArrow();
}
void PlayerLogic::removeArrow(ArrowItem *arrow)
{
if (arrow->getId() != -1) {
arrows.remove(arrow->getId());
}
}
void PlayerLogic::clearArrows()
{
QMapIterator<int, ArrowItem *> arrowIterator(arrows);
while (arrowIterator.hasNext()) {
arrowIterator.next().value()->delArrow();
}
arrows.clear();
}
bool PlayerLogic::clearCardsToDelete()
{
if (cardsToDelete.isEmpty()) {

View file

@ -8,6 +8,7 @@
#define PLAYER_H
#include "../../interface/widgets/menus/tearoff_menu.h"
#include "../board/arrow_data.h"
#include "../interface/deck_loader/loaded_deck.h"
#include "../zones/hand_zone_logic.h"
#include "../zones/pile_zone_logic.h"
@ -77,6 +78,9 @@ signals:
void clearCustomZonesMenu();
void addViewCustomZoneActionToCustomZoneMenu(QString zoneName);
void resetTopCardMenuActions();
void arrowCreateRequested(ArrowData data);
void arrowDeleteRequested(int arrowId);
void arrowsCleared(); // fires on clear() and processPlayerInfo
public slots:
void setActive(bool _active);
@ -205,17 +209,6 @@ public:
*/
CounterState *getLifeCounter() const;
ArrowItem *addArrow(const ServerInfo_Arrow &arrow);
ArrowItem *addArrow(int arrowId, CardItem *startCard, ArrowTarget *targetItem, const QColor &color);
void delArrow(int arrowId);
void removeArrow(ArrowItem *arrow);
void clearArrows();
const QMap<int, ArrowItem *> &getArrows() const
{
return arrows;
}
void setConceded(bool _conceded);
bool getConceded() const
{
@ -252,12 +245,9 @@ private:
int zoneId;
QMap<QString, CardZoneLogic *> zones;
QMap<int, CounterState *> counters;
QMap<int, ArrowItem *> arrows;
bool dialogSemaphore;
QList<CardItem *> cardsToDelete;
// void eventConnectionStateChanged(const Event_ConnectionStateChanged &event);
};
class AnnotationDialog : public QInputDialog