Code Search for Developers
 
 
  

mapclient.cpp from FreePop at Krugle


Show mapclient.cpp syntax highlighted

/***************************************************************************
                          map.cpp  -  description
                             -------------------
    begin                : Wed Aug 14 2002
    copyright            : (C) 2002 by Brendon Higgins
    email                : freepop-devel@lists.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <client.h>
#include <corner.h>
#include <mapclient.h>
#include <maptilepos.h>
#include <worldpos.h>

#include <ClanLib/core.h>

MapClient::MapClient(int w, int h, CL_NetSession* s):
    Map(w, h), origWidth(w), origHeight(h),
    raiseSlot(s->sig_netpacket_receive(NET_RAISE)
            .connect(this, &MapClient::onRaiseTileCorner)),
    lowerSlot(s->sig_netpacket_receive(NET_LOWER)
            .connect(this, &MapClient::onLowerTileCorner)) {
    tiles.resize(width * height);
    recalcOffsets();
}

MapClient::MapClient(CL_InputSource* i, CL_NetSession* s):
    Map(*i), origWidth(width), origHeight(height),
    raiseSlot(s->sig_netpacket_receive(NET_RAISE)
            .connect(this, &MapClient::onRaiseTileCorner)),
    lowerSlot(s->sig_netpacket_receive(NET_LOWER)
            .connect(this, &MapClient::onLowerTileCorner)) {
    tiles.resize(width * height);
    for (TileList::iterator it = tiles.begin(); it != tiles.end(); ++it) {
        it->extract(*i);
    }
    recalcOffsets();
}

MapClient::~MapClient() {
}

const MapTileClient* MapClient::getTile(const MapPos& p) const {
    return getTileLocal(localOrient(p));
}

MapTileClient* MapClient::getTile(const MapPos& p) {
    return getTileLocal(localOrient(p));
}

const MapTileClient* MapClient::getTile(const WorldPos& p) const {
    return getTile(p.getMap());
}

MapTileClient* MapClient::getTile(const WorldPos& p) {
    return getTile(p.getMap());
}

void MapClient::raiseTileCornerInt(const MapPos& p, const Corner& c) {
    Map::raiseTileCornerInt(p, c);
    getTileLocal(p)->calcOffset(p);
}

void MapClient::lowerTileCornerInt(const MapPos& p, const Corner& c) {
    Map::lowerTileCornerInt(p, c);
    getTileLocal(p)->calcOffset(p);
}

void MapClient::onRaiseTileCorner(CL_NetPacket& p, CL_NetComputer &computer) {
    MapPos pos = MapPos::extract(p.input);
    Corner co = Corner::extract(p.input);
    Map::raiseTileCorner(localOrient(pos), localOrient(co));
    sigTileMoved()(pos);
}

void MapClient::onLowerTileCorner(CL_NetPacket& p, CL_NetComputer &computer) {
    MapPos pos = MapPos::extract(p.input);
    Corner co = Corner::extract(p.input);
    Map::lowerTileCorner(localOrient(pos), localOrient(co));
    sigTileMoved()(pos);
}

void MapClient::displayRotateClock() {
    // Actually rotate the whole map
    TileList newTiles;
    newTiles.resize(width * height);
    MapPos pp;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            pp.set(x, y);
            pp.rotate(Rotation::CLOCKWISE, width, height);
            newTiles[pp.getX() + pp.getY() * height] =
                    tiles[x + y * width] * Rotation::CLOCKWISE;
            newTiles[pp.getX() + pp.getY() * height].calcOffset(pp);
        }
    }
    tiles.swap(newTiles);
    std::swap(width, height);
    displayRot.decAnti();
}

void MapClient::displayRotateAnti() {
    // Actually rotate the whole map
    TileList newTiles;
    newTiles.resize(width * height);
    MapPos pp;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            pp.set(x, y);
            pp.rotate(Rotation::ANTICLOCKWISE, width, height);
            newTiles[pp.getX() + pp.getY() * height] =
                    tiles[x + y * width] * Rotation::ANTICLOCKWISE;
            newTiles[pp.getX() + pp.getY() * height].calcOffset(pp);
        }
    }
    tiles.swap(newTiles);
    std::swap(width, height);
    displayRot.incAnti();
}

const Rotation& MapClient::getDisplayRotation() const {
    return displayRot;
}

void MapClient::recalcOffsets() {
    int x = 0;
    int y = 0;
    for (TileList::iterator it = tiles.begin(); it != tiles.end(); ++it) {
        it->calcOffset(MapPos(x, y));
        ++x;
        if (x == width) {
            x = 0;
            ++y;
        }
    }
}
   
void MapClient::draw() const {
    for (TileList::const_iterator i = tiles.begin(); i != tiles.end(); ++i) {
        i->draw();
    }
}

CL_Signal_v1<const MapPos&>& MapClient::sigTileMoved() {
    return mSigTileMoved;
}

CL_Rect MapClient::calcScreenRange() const {
    int x1 = -MapTileClient::picWidth() * height / 2;
    int x2 = MapTileClient::picWidth() * width / 2;
    int y1 = -MapTileClient::picHeight() *
        getTileLocal(MapPos(0, 0))->getZ() / 2;
    int y2 = MapTileClient::picHeight() * (width + height -
        getTileLocal(MapPos(width - 1, height - 1))->getZ()) / 2;
    return CL_Rect(x1, y1, x2, y2);
}

CL_Point MapClient::findPosFlatLocal(const WorldPos& p) const {
    return CL_Point(
            int(MapTileClient::picWidth() * (p.getX() - p.getY()) / 2),
            int(MapTileClient::picHeight() * (p.getX() + p.getY()) / 2));
}

boost::optional<WorldPos> MapClient::findPosLocal(const CL_Point& p) const {
    /* TODO What you should do is guess the lowest tile,
    then iterate SOUTH checking possible tiles until the right
    one is found (or end of map, in which case there IS NO pos). */
    // Very crude brute force. Better techniques exist....
    MapTilePos mtp;
    MapPos mp;
    // go backwards to get the tiles nearer the screen
    for (int y = height - 1; y >= 0; --y) {
        for (int x = width - 1; x >= 0; --x) {
            mp.set(x, y);
            mtp = getTileLocal(mp)->findPos(p);
            if (mtp.isValid()) {
                return mp + mtp;
            }
        }
    }
    return boost::optional<WorldPos>();
}

boost::optional<WorldPos> MapClient::findPos(const CL_Point& p) const {
    boost::optional<WorldPos> op = findPosLocal(p);
    if (op) {
        return serverOrient(*op);
    }
    return boost::optional<WorldPos>();
}

WorldPos MapClient::findPosFlatLocal(const CL_Point& p) const {
    const float xow = float(p.x) / MapTileClient::picWidth();
    const float yoh = float(p.y) / MapTileClient::picHeight();
    return WorldPos(xow + yoh + 0.5f, yoh - xow + 0.5f);
}

CL_Point MapClient::findPos(const WorldPos& p) const {
    return findPosLocal(localOrient(p));
}

CL_Point MapClient::findPos(const MapPos& mp, const MapTilePos& mtp) const {
    return findPosLocal(localOrient(mp), localOrient(mtp));
}

CL_Point MapClient::findPosLocal(const WorldPos& p) const {
    std::pair<MapPos, MapTilePos> pp = p.split();
    return findPosLocal(pp.first, pp.second);
}

CL_Point MapClient::findPosLocal(const MapPos& mp,
                                       const MapTilePos& mtp) const {
    const MapTileClient* t = getTileLocal(mp);
    return t->getOffset() + t->findPosSlope(mtp);
}

MapPos MapClient::localOrient(const MapPos& p) const {
    MapPos q = p;
    q.rotate(getDisplayRotation(), origWidth, origHeight);
    return q;
}

MapTilePos MapClient::localOrient(const MapTilePos& p) const {
    return p * getDisplayRotation();
}

WorldPos MapClient::localOrient(const WorldPos& p) const {
    WorldPos q = p;
    q.rotate(getDisplayRotation(), origWidth, origHeight);
    return q;
}

Corner MapClient::localOrient(const Corner& p) const {
    return p * getDisplayRotation();
}

MapPos MapClient::serverOrient(const MapPos& p) const {
    MapPos q = p;
    q.rotate(-getDisplayRotation(), width, height);
    return q;
}

MapTilePos MapClient::serverOrient(const MapTilePos& p) const {
    return p * (-getDisplayRotation());
}

WorldPos MapClient::serverOrient(const WorldPos& p) const {
    WorldPos q = p;
    q.rotate(-getDisplayRotation(), width, height);
    return q;
}

Corner MapClient::serverOrient(const Corner& p) const {
    return p * (-getDisplayRotation());
}

bool MapClient::isValid(const MapPos& p) const {
    return p.getX() >= 0 && p.getY() >= 0
            && p.getX() < origWidth && p.getY() < origHeight;
}

bool MapClient::isValid(const WorldPos& p) const {
    return p.getX() > 0.0f && p.getY() > 0.0f
            && p.getX() < origWidth && p.getY() < origHeight;
}

bool MapClient::isValidLocal(const WorldPos& p) const {
    return p.getX() > 0.0f && p.getY() > 0.0f
            && p.getX() < width && p.getY() < height;
}

WorldPos MapClient::clipLocal(WorldPos p) const {
    if (0.0f > p.getX()) p.setX(0.125f);
    if (width < p.getX()) p.setX(width - 0.125f);
    if (0.0f > p.getY()) p.setY(0.125f);
    if (height < p.getY()) p.setY(height - 0.125f);
    return p;
}

MapTileClient* MapClient::getTileLocal(const MapPos& p) {
    return &tiles[p.getX() + p.getY() * width];
}

const MapTileClient* MapClient::getTileLocal(const MapPos& p) const {
    return &tiles[p.getX() + p.getY() * width];
}




See more files for this project here

FreePop

FreePop is a multi-platform tile-based game based on the great old game Populous 2 by Bullfrog Productions Ltd., but much improved.

Project homepage: http://sourceforge.net/projects/freepop
Programming language(s): C++
License: other

  Makefile.am
  client.cpp
  client.h
  clientmisc.cpp
  clientmisc.h
  clientstate.cpp
  clientstate.h
  connectstate.cpp
  connectstate.h
  cropsclient.cpp
  cropsclient.h
  entityclient.cpp
  entityclient.h
  entityclientfactory.cpp
  entityclientfactory.h
  firecolumnclient.cpp
  firecolumnclient.h
  gamestate.cpp
  gamestate.h
  loadstate.cpp
  loadstate.h
  mapclient.cpp
  mapclient.h
  maptileclient.cpp
  maptileclient.h
  messagebox.cpp
  messagebox.h
  oversprite.cpp
  oversprite.h
  paintable.cpp
  paintable.h
  pausefader.cpp
  pausefader.h
  peepclient.cpp
  peepclient.h
  peepmagnetclient.cpp
  peepmagnetclient.h
  playerclient.cpp
  playerclient.h
  playeroptionsdialog.cpp
  playeroptionsdialog.h
  rockclient.cpp
  rockclient.h
  swampclient.cpp
  swampclient.h
  townclient.cpp
  townclient.h
  treeclient.cpp
  treeclient.h
  worldclient.cpp
  worldclient.h