Merge branch 'net-map'

This commit is contained in:
Kayne Ruse
2014-04-08 21:13:17 +10:00
15 changed files with 336 additions and 35 deletions
+3 -8
View File
@@ -62,7 +62,7 @@ void ClientApplication::Init() {
if (SDL_Init(SDL_INIT_VIDEO)) { if (SDL_Init(SDL_INIT_VIDEO)) {
throw(std::runtime_error("Failed to initialize SDL")); throw(std::runtime_error("Failed to initialize SDL"));
} }
BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF : SDL_HWSURFACE); BaseScene::SetScreen(config.Int("screen.w"), config.Int("screen.h"), 0, (config.Bool("screen.f")) ? SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN : SDL_HWSURFACE|SDL_DOUBLEBUF);
//initialize SDL_net //initialize SDL_net
if (SDLNet_Init()) { if (SDLNet_Init()) {
@@ -77,7 +77,7 @@ void ClientApplication::Proc() {
//prepare the time system //prepare the time system
typedef std::chrono::steady_clock Clock; typedef std::chrono::steady_clock Clock;
Clock::duration delta(16 * Clock::duration::period::den / std::milli::den); std::chrono::duration<int, std::milli> delta(16);
Clock::time_point simTime = Clock::now(); Clock::time_point simTime = Clock::now();
Clock::time_point realTime; Clock::time_point realTime;
@@ -95,15 +95,12 @@ void ClientApplication::Proc() {
//simulate game time //simulate game time
while (simTime < realTime) { while (simTime < realTime) {
//call each user defined function //call each user defined function
activeScene->RunFrame(double(delta.count()) / Clock::duration::period::den); activeScene->RunFrame(double(delta.count()) / std::chrono::duration<int, std::milli>::period::den);
simTime += delta; simTime += delta;
} }
//draw the game to the screen //draw the game to the screen
activeScene->RenderFrame(); activeScene->RenderFrame();
//give the computer a break
SDL_Delay(10);
} }
UnloadScene(); UnloadScene();
@@ -121,7 +118,6 @@ void ClientApplication::Quit() {
void ClientApplication::LoadScene(SceneList sceneIndex) { void ClientApplication::LoadScene(SceneList sceneIndex) {
UnloadScene(); UnloadScene();
switch(sceneIndex) { switch(sceneIndex) {
//add scene creation calls here //add scene creation calls here
case SceneList::FIRST: case SceneList::FIRST:
@@ -143,7 +139,6 @@ void ClientApplication::LoadScene(SceneList sceneIndex) {
case SceneList::INCOMBAT: case SceneList::INCOMBAT:
activeScene = new InCombat(); activeScene = new InCombat();
break; break;
default: default:
throw(std::logic_error("Failed to recognize the scene index")); throw(std::logic_error("Failed to recognize the scene index"));
} }
+1 -1
View File
@@ -36,7 +36,7 @@ public:
void Update(double delta); void Update(double delta);
void DrawTo(SDL_Surface* const dest) { sprite.DrawTo(dest, position.x, position.y); } void DrawTo(SDL_Surface* const dest, int camX, int camY) { sprite.DrawTo(dest, position.x - camX, position.y - camY); }
//clunky code results in smooth movement and controls //clunky code results in smooth movement and controls
void AdjustDirection(Direction); void AdjustDirection(Direction);
+181 -10
View File
@@ -23,8 +23,15 @@
#include "channels.hpp" #include "channels.hpp"
#include <algorithm>
#include <cmath>
#include <stdexcept> #include <stdexcept>
//debugging
#include <iostream>
using std::cout;
using std::endl;
//------------------------- //-------------------------
//Public access members //Public access members
//------------------------- //-------------------------
@@ -55,6 +62,14 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
disconnectButton.SetText("Disconnect"); disconnectButton.SetText("Disconnect");
shutDownButton.SetText("Shut Down"); shutDownButton.SetText("Shut Down");
//load the tilesheet
tileSheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
//setup the map object
mapPager.SetRegionWidth(REGION_WIDTH);
mapPager.SetRegionHeight(REGION_HEIGHT);
mapPager.SetRegionDepth(REGION_DEPTH);
//create the server-side player object //create the server-side player object
NetworkPacket packet; NetworkPacket packet;
packet.meta.type = NetworkPacket::Type::PLAYER_NEW; packet.meta.type = NetworkPacket::Type::PLAYER_NEW;
@@ -73,6 +88,9 @@ InWorld::InWorld(ConfigUtility* const argConfig, UDPNetworkUtility* const argNet
packet.meta.type = NetworkPacket::Type::SYNCHRONIZE; packet.meta.type = NetworkPacket::Type::SYNCHRONIZE;
serialize(&packet, buffer); serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
//debug
// RequestRegion(0, 0);
} }
InWorld::~InWorld() { InWorld::~InWorld() {
@@ -88,29 +106,59 @@ void InWorld::FrameStart() {
} }
void InWorld::Update(double delta) { void InWorld::Update(double delta) {
//suck in all waiting packets
NetworkPacket packet; NetworkPacket packet;
//suck in all waiting packets
while(network.Receive()) { while(network.Receive()) {
deserialize(&packet, network.GetInData()); deserialize(&packet, network.GetInData());
packet.meta.srcAddress = network.GetInPacket()->address; packet.meta.srcAddress = network.GetInPacket()->address;
HandlePacket(packet); HandlePacket(packet);
} }
//update the characters
for (auto& it : playerCharacters) { for (auto& it : playerCharacters) {
it.second.Update(delta); it.second.Update(delta);
} }
//TODO: sort the players and entities by Y position
//update the camera
if(localCharacter) {
camera.x = localCharacter->GetPosition().x - camera.marginX;
camera.y = localCharacter->GetPosition().y - camera.marginY;
}
//check the map
UpdateMap();
} }
void InWorld::FrameEnd() { void InWorld::FrameEnd() {
// //
} }
void InWorld::RenderFrame() {
// SDL_FillRect(GetScreen(), 0, 0);
Render(GetScreen());
SDL_Flip(GetScreen());
}
void InWorld::Render(SDL_Surface* const screen) { void InWorld::Render(SDL_Surface* const screen) {
for (auto& it : playerCharacters) { //draw the map
it.second.DrawTo(screen); for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); it++) {
tileSheet.DrawRegionTo(screen, *it, camera.x, camera.y);
} }
//draw characters
for (auto& it : playerCharacters) {
it.second.DrawTo(screen, camera.x, camera.y);
}
//draw UI
disconnectButton.DrawTo(screen); disconnectButton.DrawTo(screen);
shutDownButton.DrawTo(screen); shutDownButton.DrawTo(screen);
font.DrawStringTo(to_string_custom(fps.GetFrameRate()), screen, 0, 0);
fps.Calculate();
} }
//------------------------- //-------------------------
@@ -212,24 +260,27 @@ void InWorld::KeyUp(SDL_KeyboardEvent const& key) {
} }
} }
//-------------------------
//Network handlers
//-------------------------
void InWorld::HandlePacket(NetworkPacket packet) { void InWorld::HandlePacket(NetworkPacket packet) {
switch(packet.meta.type) { switch(packet.meta.type) {
case NetworkPacket::Type::DISCONNECT: case NetworkPacket::Type::DISCONNECT:
HandleDisconnect(packet); HandleDisconnect(packet);
break; break;
case NetworkPacket::Type::PLAYER_NEW: case NetworkPacket::Type::PLAYER_NEW:
HandlePlayerNew(packet); HandlePlayerNew(packet);
break; break;
case NetworkPacket::Type::PLAYER_DELETE: case NetworkPacket::Type::PLAYER_DELETE:
HandlePlayerDelete(packet); HandlePlayerDelete(packet);
break; break;
case NetworkPacket::Type::PLAYER_UPDATE: case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet); HandlePlayerUpdate(packet);
break; break;
case NetworkPacket::Type::REGION_CONTENT:
HandleRegionContent(packet);
break;
//handle errors //handle errors
default: default:
throw(std::runtime_error("Unknown NetworkPacket::Type encountered")); throw(std::runtime_error("Unknown NetworkPacket::Type encountered"));
@@ -257,6 +308,12 @@ void InWorld::HandlePlayerNew(NetworkPacket packet) {
if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) { if (packet.playerInfo.clientIndex == clientIndex && !localCharacter) {
playerIndex = packet.playerInfo.playerIndex; playerIndex = packet.playerInfo.playerIndex;
localCharacter = &playerCharacters[playerIndex]; localCharacter = &playerCharacters[playerIndex];
//setup the camera
camera.width = GetScreen()->w;
camera.height = GetScreen()->h;
//center on the player's character
camera.marginX = (GetScreen()->w / 2 - localCharacter->GetSprite()->GetImage()->GetClipW() / 2);
camera.marginY = (GetScreen()->h / 2 - localCharacter->GetSprite()->GetImage()->GetClipH() / 2);
} }
} }
@@ -288,6 +345,28 @@ void InWorld::HandlePlayerUpdate(NetworkPacket packet) {
playerCharacters[packet.playerInfo.playerIndex].ResetDirection(); playerCharacters[packet.playerInfo.playerIndex].ResetDirection();
} }
void InWorld::HandleRegionContent(NetworkPacket packet) {
//replace existing regions
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
mapPager.UnloadRegion(packet.regionInfo.x, packet.regionInfo.y);
}
mapPager.PushRegion(packet.regionInfo.region);
packet.regionInfo.region = nullptr;
//debugging
cout << "Received region: " << packet.regionInfo.x << ", " << packet.regionInfo.y << endl;
if (mapPager.FindRegion(packet.regionInfo.x, packet.regionInfo.y)) {
cout << "Success" << endl;
}
else {
cout << "Failure" << endl;
}
}
//-------------------------
//Server control
//-------------------------
void InWorld::SendState() { void InWorld::SendState() {
NetworkPacket packet; NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE]; char buffer[PACKET_BUFFER_SIZE];
@@ -296,8 +375,6 @@ void InWorld::SendState() {
packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE; packet.meta.type = NetworkPacket::Type::PLAYER_UPDATE;
packet.playerInfo.clientIndex = clientIndex; packet.playerInfo.clientIndex = clientIndex;
packet.playerInfo.playerIndex = playerIndex; packet.playerInfo.playerIndex = playerIndex;
// snprintf(packet.playerInfo.handle, PACKET_STRING_SIZE, "%s", config["player.handle"].c_str());
// snprintf(packet.playerInfo.avatar, PACKET_STRING_SIZE, "%s", config["player.avatar"].c_str());
packet.playerInfo.position = localCharacter->GetPosition(); packet.playerInfo.position = localCharacter->GetPosition();
packet.playerInfo.motion = localCharacter->GetMotion(); packet.playerInfo.motion = localCharacter->GetMotion();
@@ -325,4 +402,98 @@ void InWorld::RequestShutDown() {
packet.clientInfo.index = clientIndex; packet.clientInfo.index = clientIndex;
serialize(&packet, buffer); serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE); network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
} }
void InWorld::RequestRegion(int x, int y) {
NetworkPacket packet;
char buffer[PACKET_BUFFER_SIZE];
//pack the region's data
packet.meta.type = NetworkPacket::Type::REGION_REQUEST;
packet.regionInfo.x = x;
packet.regionInfo.y = y;
serialize(&packet, buffer);
network.Send(Channels::SERVER, buffer, PACKET_BUFFER_SIZE);
}
//-------------------------
//Utilities
//-------------------------
int InWorld::CheckBufferDistance(Region* const region) {
/* DOCUMENTATION
* This algorithm is extremely complex and involed, but initial tests show
* that it gives the right answers. The purpose is to determine how far off screen
* a certain region is, so that it can be unloaded when necessary.
*
* If the region is actually onscreen, then there's no reason to run the rest, so
* the algorithm corrects for the camera's location, before checking the bounds of
* the screen.
*
* The next part is tricky. If X or Y is negative, then it is divided by the
* graphical size of the regions, resulting in a usable integer, representing how
* far from the screen it is in "region units". If, however, X or Y is larger than
* 0, than first, the size of the screen is subtracted from that variable, before
* it is then divided by the graphical size of a region. Finally, to compensate for
* the off by one error, 1 is added at the end.
*
* Since only the magnitude of the distance in either direction is needed, this
* method returns the largest absolute value of X or Y.
*
* The final result of this algorithm is an integer representing how far, rounded
* up, a certain region is from the screen's edges in any direction, measured in
* "region units". This algorithm may be flawed, in which case, I recommend simply
* replacing it with a boolean check, to see if the region's distance from the player
* is larger than a certain value. This algorithm lacks the advantages I initially
* expected, so that may be beneficial at some point.
*/
//locations relative to the camera
int x = region->GetX() - camera.x;
int y = region->GetY() - camera.y;
//if the region is visible, return -1
if (x >= -mapPager.GetRegionWidth() * tileSheet.GetTileW() && x < camera.width &&
y >= -mapPager.GetRegionHeight() * tileSheet.GetTileH() && y < camera.height) {
return -1;
}
//prune the screen's area from the algorithm; get the pseudo-indexes
if (x < 0) x /= (mapPager.GetRegionWidth() * tileSheet.GetTileW());
if (y < 0) y /= (mapPager.GetRegionHeight() * tileSheet.GetTileH());
if (x > 0) x = (x - camera.width) / (mapPager.GetRegionWidth() * tileSheet.GetTileW()) + 1;
if (y > 0) y = (y - camera.height) / (mapPager.GetRegionHeight() * tileSheet.GetTileH()) + 1;
//return the pseudo-index with the greatest magnitude
return std::max(abs(x), abs(y));
}
void InWorld::UpdateMap() {
//prune distant regions
for (auto it = mapPager.GetContainer()->begin(); it != mapPager.GetContainer()->end(); /* EMPTY */) {
if (CheckBufferDistance(*it) > 2) {
//debugging
cout << "unloading: " << (*it)->GetX() << ", " << (*it)->GetY() << endl;
mapPager.UnloadRegion((*it)->GetX(), (*it)->GetY());
//reset
it = mapPager.GetContainer()->begin();
continue;
}
++it;
}
//TODO: make the region units official
int regionUnitX = mapPager.GetRegionWidth() * tileSheet.GetTileW();
int regionUnitY = mapPager.GetRegionHeight() * tileSheet.GetTileH();
//request empty regions, including buffers (-1 & +1 region unit)
for (int i = snapToBase(regionUnitX, camera.x - regionUnitX); i <= snapToBase(regionUnitX, camera.x + camera.width + regionUnitX); i += regionUnitX) {
for (int j = snapToBase(regionUnitY, camera.y - regionUnitY); j <= snapToBase(regionUnitY, camera.y + camera.height + regionUnitY); j += regionUnitY) {
if (!mapPager.FindRegion(i, j)) {
RequestRegion(i, j);
}
}
}
}
+15
View File
@@ -36,9 +36,11 @@
#include "image.hpp" #include "image.hpp"
#include "raster_font.hpp" #include "raster_font.hpp"
#include "button.hpp" #include "button.hpp"
#include "tile_sheet.hpp"
//common //common
#include "config_utility.hpp" #include "config_utility.hpp"
#include "frame_rate.hpp"
//client //client
#include "base_scene.hpp" #include "base_scene.hpp"
@@ -58,6 +60,7 @@ protected:
void FrameStart(); void FrameStart();
void Update(double delta); void Update(double delta);
void FrameEnd(); void FrameEnd();
void RenderFrame();
void Render(SDL_Surface* const); void Render(SDL_Surface* const);
//Event handlers //Event handlers
@@ -68,24 +71,34 @@ protected:
void KeyDown(SDL_KeyboardEvent const&); void KeyDown(SDL_KeyboardEvent const&);
void KeyUp(SDL_KeyboardEvent const&); void KeyUp(SDL_KeyboardEvent const&);
//Network handlers
void HandlePacket(NetworkPacket); void HandlePacket(NetworkPacket);
void HandleDisconnect(NetworkPacket); void HandleDisconnect(NetworkPacket);
void HandlePlayerNew(NetworkPacket); void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket); void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket); void HandlePlayerUpdate(NetworkPacket);
void HandleRegionContent(NetworkPacket);
//Server control
void SendState(); void SendState();
void RequestDisconnect(); void RequestDisconnect();
void RequestShutDown(); void RequestShutDown();
void RequestRegion(int x, int y);
//utilities
int CheckBufferDistance(Region* const);
void UpdateMap();
//globals //globals
ConfigUtility& config; ConfigUtility& config;
FrameRate fps;
UDPNetworkUtility& network; UDPNetworkUtility& network;
int& clientIndex; int& clientIndex;
//graphics //graphics
Image buttonImage; Image buttonImage;
RasterFont font; RasterFont font;
TileSheet tileSheet;
//map //map
RegionPager<BlankGenerator, DummyFormat> mapPager; RegionPager<BlankGenerator, DummyFormat> mapPager;
@@ -95,6 +108,8 @@ protected:
Button shutDownButton; Button shutDownButton;
struct { struct {
int x = 0, y = 0; int x = 0, y = 0;
int width = 0, height = 0;
int marginX = 0, marginY = 0;
} camera; } camera;
//game //game
+48
View File
@@ -0,0 +1,48 @@
/* Copyright: (c) Kayne Ruse 2014
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#ifndef FRAMERATE_HPP_
#define FRAMERATE_HPP_
#include <chrono>
class FrameRate {
public:
typedef std::chrono::high_resolution_clock Clock;
FrameRate() = default;
int Calculate() {
frameCount++;
if (Clock::now() - tick >= std::chrono::duration<int>(1)) {
lastFrameRate = frameCount;
frameCount = 0;
tick = Clock::now();
}
return lastFrameRate;
}
int GetFrameRate() { return lastFrameRate; }
private:
int frameCount = 0;
int lastFrameRate = 0;
Clock::time_point tick = Clock::now();
};
#endif
+1 -1
View File
@@ -1,5 +1,5 @@
#config #config
INCLUDES+=. .. INCLUDES+=. .. ../map
LIBS+= LIBS+=
CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES)) CXXFLAGS+=-std=c++11 -DDEBUG $(addprefix -I,$(INCLUDES))
CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES)) CFLAGS+=-DDEBUG $(addprefix -I,$(INCLUDES))
+23 -3
View File
@@ -34,8 +34,28 @@ void TileSheet::Unload() {
XCount = YCount = 0; XCount = YCount = 0;
} }
void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, int tile) { void TileSheet::DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile) {
image.SetClipX(tile % XCount * image.GetClipW()); //0 is invisible
image.SetClipY(tile / XCount * image.GetClipH()); if (tile == 0) return;
image.SetClipX((tile-1) % XCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH());
image.DrawTo(dest, x, y); image.DrawTo(dest, x, y);
} }
void TileSheet::DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY) {
Region::type_t tile = 0;
for (register int i = 0; i < region->GetWidth(); ++i) {
for (register int j = 0; j < region->GetHeight(); ++j) {
for (register int k = 0; k < region->GetDepth(); ++k) {
tile = region->GetTile(i, j, k);
//0 is invisible
if (tile == 0) continue;
image.SetClipX((tile-1) % XCount * image.GetClipW());
image.SetClipY((tile-1) / XCount * image.GetClipH());
image.DrawTo(dest,
region->GetX() + i * image.GetClipW() - camX,
region->GetY() + j * image.GetClipH() - camY);
}
}
}
}
+4 -1
View File
@@ -22,6 +22,8 @@
#ifndef TILESHEET_HPP_ #ifndef TILESHEET_HPP_
#define TILESHEET_HPP_ #define TILESHEET_HPP_
#include "region.hpp"
#include "image.hpp" #include "image.hpp"
#include <string> #include <string>
@@ -35,7 +37,8 @@ public:
void Load(std::string fname, int XCount, int YCount); void Load(std::string fname, int XCount, int YCount);
void Unload(); void Unload();
void DrawTo(SDL_Surface* const dest, int x, int y, int tile); void DrawTo(SDL_Surface* const dest, int x, int y, Region::type_t tile);
void DrawRegionTo(SDL_Surface* const dest, Region* const region, int camX, int camY);
//accessors //accessors
Image* GetImage() { return &image; } Image* GetImage() { return &image; }
+2 -2
View File
@@ -24,11 +24,11 @@
#include <stdexcept> #include <stdexcept>
void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) { void DummyFormat::Load(Region** const ptr, int width, int height, int depth, int x, int y) {
//TODO //EMPTY
} }
void DummyFormat::Save(Region* const ptr) { void DummyFormat::Save(Region* const ptr) {
//TODO //EMPTY
} }
/* /*
void VerboseFormat::Load(Region** const ptr, int x, int y) { void VerboseFormat::Load(Region** const ptr, int x, int y) {
+18 -5
View File
@@ -50,15 +50,28 @@ Region* RegionPagerBase::GetRegion(int x, int y) {
x = snapToBase(regionWidth, x); x = snapToBase(regionWidth, x);
y = snapToBase(regionHeight, y); y = snapToBase(regionHeight, y);
//get the region by various means
//TODO: revert this try/catch point
Region* ptr = nullptr;
ptr = FindRegion(x, y);
if (ptr) return ptr;
ptr = LoadRegion(x, y);
if (ptr) return ptr;
return CreateRegion(x, y);
}
Region* RegionPagerBase::FindRegion(int x, int y) {
//find the region //find the region
for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) { for (std::list<Region*>::iterator it = regionList.begin(); it != regionList.end(); it++) {
if ((*it)->GetX() == x && (*it)->GetY() == y) { if ((*it)->GetX() == x && (*it)->GetY() == y) {
return *it; return *it;
} }
} }
return nullptr;
//get the region by other means
Region* ptr = LoadRegion(x, y);
if (ptr) return ptr;
return CreateRegion(x, y);
} }
Region* RegionPagerBase::PushRegion(Region* ptr) {
regionList.push_front(ptr);
return regionList.front();
}
+8 -1
View File
@@ -33,18 +33,23 @@ public:
RegionPagerBase(int regionWidth, int regionHeight, int regionDepth); RegionPagerBase(int regionWidth, int regionHeight, int regionDepth);
virtual ~RegionPagerBase(); virtual ~RegionPagerBase();
//tile manipulation
Region::type_t SetTile(int x, int y, int z, Region::type_t v); Region::type_t SetTile(int x, int y, int z, Region::type_t v);
Region::type_t GetTile(int x, int y, int z); Region::type_t GetTile(int x, int y, int z);
//region manipulation
Region* GetRegion(int x, int y); Region* GetRegion(int x, int y);
Region* FindRegion(int x, int y);
Region* PushRegion(Region*);
//interface //interface
virtual Region* LoadRegion(int x, int y) = 0; virtual Region* LoadRegion(int x, int y) = 0;
virtual Region* SaveRegion(int x, int y) = 0; virtual Region* SaveRegion(int x, int y) = 0;
virtual Region* CreateRegion(int x, int y) = 0; virtual Region* CreateRegion(int x, int y) = 0;
virtual void UnloadRegion(int x, int y) = 0; virtual void UnloadRegion(int x, int y) = 0;
//TODO: delete?
//accessors //accessors & mutators
//NOTE: don't change the sizes mid-program, it will cause issues //NOTE: don't change the sizes mid-program, it will cause issues
int SetRegionWidth(int i) { return regionWidth = i; } int SetRegionWidth(int i) { return regionWidth = i; }
int SetRegionHeight(int i) { return regionHeight = i; } int SetRegionHeight(int i) { return regionHeight = i; }
@@ -53,6 +58,8 @@ public:
int GetRegionWidth() const { return regionWidth; } int GetRegionWidth() const { return regionWidth; }
int GetRegionHeight() const { return regionHeight; } int GetRegionHeight() const { return regionHeight; }
int GetRegionDepth() const { return regionDepth; } int GetRegionDepth() const { return regionDepth; }
std::list<Region*>* GetContainer() { return &regionList; }
protected: protected:
int regionWidth; int regionWidth;
int regionHeight; int regionHeight;
+10 -3
View File
@@ -61,7 +61,13 @@ EditorScene::EditorScene(ConfigUtility* const arg1):
pager.SetRegionDepth(REGION_DEPTH); pager.SetRegionDepth(REGION_DEPTH);
//debug //debug
tsheet.Load(config["dir.tilesets"] + "sand.bmp", 12, 3); tsheet.Load(config["dir.tilesets"] + "terrain.bmp", 12, 15);
for (int i = 0; i < REGION_WIDTH; i++) {
for (int j = 0; j < REGION_HEIGHT; j++) {
pager.SetTile(i, j, 0, 14);
}
}
pager.SetTile(5, 10, 1, 48);
} }
EditorScene::~EditorScene() { EditorScene::~EditorScene() {
@@ -85,7 +91,8 @@ void EditorScene::FrameEnd() {
} }
void EditorScene::Render(SDL_Surface* const screen) { void EditorScene::Render(SDL_Surface* const screen) {
//debug tsheet.DrawRegionTo(screen, pager.GetRegion(0, 0), camera.x, camera.y);
/* //debug
for (int i = 0; i < pager.GetRegionWidth()*2; i++) { for (int i = 0; i < pager.GetRegionWidth()*2; i++) {
for (int j = 0; j < pager.GetRegionHeight()*2; j++) { for (int j = 0; j < pager.GetRegionHeight()*2; j++) {
for (int k = 0; k < pager.GetRegionDepth(); k++) { for (int k = 0; k < pager.GetRegionDepth(); k++) {
@@ -99,7 +106,7 @@ void EditorScene::Render(SDL_Surface* const screen) {
} }
} }
} }
*/
//draw a big bar across the top (hackish) //draw a big bar across the top (hackish)
buttonImage.SetClipY(0); buttonImage.SetClipY(0);
for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) { for (int i = 0; i < screen->w; i += buttonImage.GetClipW()) {
+10
View File
@@ -2,6 +2,16 @@ print("Lua script check OK (./rsc)")
function Region.Create(r) function Region.Create(r)
print("Region:Create(r", Region.GetX(r), Region.GetY(r), ")") print("Region:Create(r", Region.GetX(r), Region.GetY(r), ")")
for i = 1, Region.GetWidth(r) do
for j = 1, Region.GetHeight(r) do
if math.abs(i) == math.abs(j) then
Region.SetTile(r, i, j, 1, 50)
else
Region.SetTile(r, i, j, 1, 14)
end
end
end
print("done")
end end
function Region.Unload(r) function Region.Unload(r)
+11
View File
@@ -180,6 +180,9 @@ void ServerApplication::HandlePacket(NetworkPacket packet) {
case NetworkPacket::Type::PLAYER_UPDATE: case NetworkPacket::Type::PLAYER_UPDATE:
HandlePlayerUpdate(packet); HandlePlayerUpdate(packet);
break; break;
case NetworkPacket::Type::REGION_REQUEST:
HandleRegionRequest(packet);
break;
//handle errors //handle errors
default: default:
throw(runtime_error("Unknown NetworkPacket::Type encountered")); throw(runtime_error("Unknown NetworkPacket::Type encountered"));
@@ -340,6 +343,14 @@ void ServerApplication::HandlePlayerUpdate(NetworkPacket packet) {
PumpPacket(packet); PumpPacket(packet);
} }
void ServerApplication::HandleRegionRequest(NetworkPacket packet) {
char buffer[PACKET_BUFFER_SIZE];
packet.meta.type = NetworkPacket::Type::REGION_CONTENT;
packet.regionInfo.region = mapPager.GetRegion(packet.regionInfo.x, packet.regionInfo.y);
serialize(&packet, buffer);
network.Send(&packet.meta.srcAddress, buffer, PACKET_BUFFER_SIZE);
}
void ServerApplication::PumpPacket(NetworkPacket packet) { void ServerApplication::PumpPacket(NetworkPacket packet) {
//I don't really like this, but it'll do for now //I don't really like this, but it'll do for now
char buffer[PACKET_BUFFER_SIZE]; char buffer[PACKET_BUFFER_SIZE];
+1
View File
@@ -81,6 +81,7 @@ private:
void HandlePlayerNew(NetworkPacket); void HandlePlayerNew(NetworkPacket);
void HandlePlayerDelete(NetworkPacket); void HandlePlayerDelete(NetworkPacket);
void HandlePlayerUpdate(NetworkPacket); void HandlePlayerUpdate(NetworkPacket);
void HandleRegionRequest(NetworkPacket);
void PumpPacket(NetworkPacket); void PumpPacket(NetworkPacket);