From ce20694e0db010b5d65bdd2ee81a410efbf99e3d Mon Sep 17 00:00:00 2001 From: manuel Date: Mon, 2 May 2011 15:50:23 +0200 Subject: w000h00 --- pacman-c++/server.cpp | 166 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 153 insertions(+), 13 deletions(-) (limited to 'pacman-c++/server.cpp') diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index ef271f0..2b43bb9 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp @@ -44,7 +44,7 @@ bool Server::run() void Server::tick() { - qDebug() << "[Tick] Doing server update"; + //qDebug() << "[Tick] Doing server update"; if (m_finishRound) stopGame(true); if (!m_running) @@ -78,6 +78,7 @@ void Server::tick() Transmission::map_t Server::calculateUpdates() { + QMap > movements; Transmission::map_t map = Util::createEmptyMap(); QMutableMapIterator i(m_actorMovements); @@ -105,12 +106,9 @@ invalid_direction: if (newMapPosition.y() >= visualMap[newMapPosition.x()].size()) newMapPosition.setY(visualMap[newMapPosition.x()].size() - 1); - // - // TODO: support actors eating each other - GameEntity *oldItem = visualMap[mapPosition.x()][mapPosition.y()]; - /* check if there's an item at new location of actor */ GameEntity *item = visualMap[newMapPosition.x()][newMapPosition.y()]; + GameEntity *oldItem = visualMap[mapPosition.x()][mapPosition.y()]; if (item != NULL && oldItem != item) { qDebug() << "[Calc] Found item at new actor location"; @@ -128,14 +126,13 @@ invalid_direction: map[newMapPosition.x()][newMapPosition.y()] = Transmission::empty | actor->color(); else if (survive == GameEntity::DestroyedActor) { + map[newMapPosition.x()][newMapPosition.y()] = Transmission::death | actor->color(); m_actors[item->color()]->addRoundPoints(actor->getRoundPoints()); actor->finishRound(true); - map[newMapPosition.x()][newMapPosition.y()] = Transmission::death | actor->color(); setFinishRound(); } } } - // /* movement didn't work - e.g. was blocked */ if (mapPosition == newMapPosition) @@ -156,19 +153,108 @@ invalid_direction: } } - map[newMapPosition.x()][newMapPosition.y()] |= Transmission::pacman | - color | Util::actorMovementToTransmission(direction); + /* store movement for collision */ + movements.insert(color, QPair(mapPosition, newMapPosition)); + + /* set direction (used for collision detection) */ + actor->setDirection(direction); /* DEBUG: uncomments to disable auto-movement */ //direction = Actor::None; + /* actor is not moving anymore: remove from list */ if (direction == Actor::None) - { - /* set actor to non-moving */ - m_actorMovements[color] = Actor::None; i.remove(); + } + + /* check for actor collision */ + QList blocked; + foreach(Color::Color color, movements.keys()) + { + Actor *actor = m_actors[color]; + QPoint oldpos = movements[color].first; + QPoint newpos = movements[color].second; + QPoint scenepos = actor->pos().toPoint(); + + /* first move actor to new position */ + actor->move(actor->direction()); + + /* next check for collisions */ + Actor *orderer = NULL; + Actor *meal = NULL; + foreach(Actor *other, m_actors) + { + if (actor == other) + continue; + if (!actor->collidesWithItem(other)) + continue; + /* both move in the same direction */ + if (actor->direction() == other->direction()) + continue; + + if (other->canEat(actor, m_eatingorder)) + { + qDebug() << "[Collision] Actor" << actor->color() << "got EATEN by" << other->color(); + orderer = other; + meal = actor; + break; + } + else if (actor->canEat(other, m_eatingorder)) + { + qDebug() << "[Collision] Actor" << actor->color() << "EATS" << other->color(); + orderer = actor; + meal = other; + blocked.append(other); + break; + } + else + { + qDebug() << "[Collision] Actor" << actor->color() << "got BLOCKED by" << other->color(); + blocked.append(actor); + /* no break here */ + } + } + + /* update map depending on collision */ + if (orderer != NULL && meal != NULL) + { + map[newpos.x()][newpos.y()] |= Transmission::pacman | Transmission::death + | orderer->color() | meal->color(); + orderer->addRoundPoints(meal->getRoundPoints()); + meal->finishRound(true); + setFinishRound(); + } + else if (blocked.contains(actor)) + { + /* move actor back early cause he won't move */ + actor->setPos(scenepos); + map[oldpos.x()][oldpos.y()] |= Transmission::pacman | color; + } + else + { + map[newpos.x()][newpos.y()] |= Transmission::pacman | color; } } + + /* move all actors back to their origin position */ + foreach(Color::Color color, movements.keys()) + m_actors[color]->setPos(mapPositionToCoord(movements[color].first)); + + foreach(Color::Color col, m_eatingorder.toSet()) + { + QList found; + for (unsigned int x = 0; x < Constants::map_size.width; ++x) + { + for (unsigned int y = 0; y < Constants::map_size.height; ++y) + { + if ((map[x][y] & Transmission::color_mask) & col) + found.append(QPoint(x, y)); + } + } + if (found.count() > 1) + qDebug() << "found" << found << "fields with color=" << col; + } + return map; } @@ -519,6 +605,60 @@ void Server::initRoundMap() Util::placeActors(map, m_maxplayers, Color::order); Util::fillPoints(map); +#if 0 // actor eating actor tests + m_actorMovements.clear(); +#if 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][1] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][3] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][4] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][5] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); +#elif 0 + //works + map[0][0] = Color::order[1] | Transmission::pacman; + map[0][5] = Color::order[0] | Transmission::pacman; + m_actorMovements.insert(Color::order[1], Actor::Down); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][5] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); + m_actorMovements.insert(Color::order[1], Actor::Up); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][6] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); + m_actorMovements.insert(Color::order[1], Actor::Up); +#elif 0 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][7] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); + m_actorMovements.insert(Color::order[1], Actor::Up); +#elif 1 + //works + map[0][0] = Color::order[0] | Transmission::pacman; + map[0][1] = Color::order[1] | Transmission::pacman; + m_actorMovements.insert(Color::order[0], Actor::Down); + m_actorMovements.insert(Color::order[1], Actor::Down); +#endif +#endif + /* save positions of blocks for later usage */ m_blocks.clear(); for (unsigned int x = 0; x < Constants::map_size.width; ++x) @@ -696,7 +836,7 @@ bool Server::parseCommandline() { bool ok; unsigned int rounds = QString(opt.getValue("rounds")).toUInt(&ok); - if (!ok || rounds == 0) + if (!ok) { qCritical() << "Invalid number of rounds: " << opt.getValue("rounds") << endl; return false; -- cgit v1.2.3