Compare commits

...

8 Commits

Author SHA1 Message Date
Kayne Ruse 99af76c5b5 Merge branch 'develop'
Conflicts:
	todo.txt
2014-12-27 23:44:54 +11:00
Kayne Ruse cc6458daa7 Merge branch 'high-water-mark' into develop
Thank fuck that's over.
2014-12-27 23:34:51 +11:00
Kayne Ruse 8708cfbee0 I give up, I'm just using the stop-dead system for now. 2014-12-27 23:16:48 +11:00
Kayne Ruse b67e85e87b Moved some messy code from InWorld::Update() to utility methods 2014-12-27 21:00:00 +11:00
Kayne Ruse 33c3143de9 Added unary negative to Vector2
This is the only fragment I'm bothering to salvage from the collisions
branch.
2014-12-27 20:31:09 +11:00
Kayne Ruse 5deb6a9d8e Merge branch 'develop' 2014-11-23 04:12:51 +11:00
Kayne Ruse 3192524922 Merge commit '0f13956'
* also eliminated ./todo.txt
2014-11-07 00:17:31 +11:00
Kayne Ruse 2a7a2889c6 Merge branch 'unix-compat' 2014-10-19 05:50:13 +11:00
6 changed files with 93 additions and 75 deletions
+12
View File
@@ -21,3 +21,15 @@
*/ */
#include "local_character.hpp" #include "local_character.hpp"
#include <iostream>
bool LocalCharacter::ProcessCollisionGrid(std::list<BoundingBox> boxList) {
for(auto& box : boxList) {
if (box.CheckOverlap(origin + bounds)) {
origin -= motion;
motion = {0, 0};
return true;
}
}
return false;
}
+6
View File
@@ -23,12 +23,18 @@
#define LOCALCHARACTER_HPP_ #define LOCALCHARACTER_HPP_
#include "base_character.hpp" #include "base_character.hpp"
#include "bounding_box.hpp"
#include "vector2.hpp"
#include <list>
class LocalCharacter: public BaseCharacter { class LocalCharacter: public BaseCharacter {
public: public:
LocalCharacter() = default; LocalCharacter() = default;
virtual ~LocalCharacter() = default; virtual ~LocalCharacter() = default;
bool ProcessCollisionGrid(std::list<BoundingBox>);
private: private:
//NOTE: NO MEMBERS //NOTE: NO MEMBERS
}; };
+68 -44
View File
@@ -134,23 +134,8 @@ void InWorld::Update() {
//free the buffer //free the buffer
delete reinterpret_cast<char*>(packetBuffer); delete reinterpret_cast<char*>(packetBuffer);
//check the connection (heartbeat) //heartbeat system
if (Clock::now() - lastBeat > std::chrono::seconds(3)) { CheckHeartBeat();
if (attemptedBeats > 2) {
//escape to the disconnect screen
SendDisconnectRequest();
SetNextScene(SceneList::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
}
else {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(Channels::SERVER, &newPacket);
attemptedBeats++;
lastBeat = Clock::now();
}
}
//update all entities //update all entities
for (auto& it : characterMap) { for (auto& it : characterMap) {
@@ -168,35 +153,14 @@ void InWorld::Update() {
return; return;
} }
//prepare for collisions //get the collidable boxes
BoundingBox wallBounds = {0, 0, tileSheet.GetTileW(), tileSheet.GetTileH()}; std::list<BoundingBox> boxList = GenerateCollisionGrid(localCharacter, tileSheet.GetTileW(), tileSheet.GetTileH());
std::list<BoundingBox> boxList;
//NOTE: for loops were too dense to work with, so I've just used while loops
//NOTE: this code is complex, and can be replaced with hard-coded relative positions, at the cost of variable-sized sprites/bounding boxes
//outer loop
wallBounds.x = snapToBase((double)wallBounds.w, localCharacter->GetOrigin().x) - wallBounds.w;
while(wallBounds.x < (localCharacter->GetOrigin() + localCharacter->GetBounds()).x + localCharacter->GetBounds().w) {
//inner loop
wallBounds.y = snapToBase((double)wallBounds.h, localCharacter->GetOrigin().y) - wallBounds.h;
while(wallBounds.y < (localCharacter->GetOrigin() + localCharacter->GetBounds()).y + localCharacter->GetBounds().h) {
//check to see if this tile is solid
if (regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
//push onto the box set
boxList.push_front(wallBounds);
}
//increment
wallBounds.y += wallBounds.h;
}
//increment
wallBounds.x += wallBounds.w;
}
//process the collisions //process the collisions
std::cout << "boxList.size(): " << boxList.size() << std::endl; if (localCharacter->ProcessCollisionGrid(boxList)) {
localCharacter->CorrectSprite();
SendLocalCharacterMotion();
}
//update the camera //update the camera
camera.x = localCharacter->GetOrigin().x - camera.marginX; camera.x = localCharacter->GetOrigin().x - camera.marginX;
@@ -499,6 +463,26 @@ void InWorld::HandleDisconnectForced(ClientPacket* const argPacket) {
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server"; ConfigUtility::GetSingleton()["client.disconnectMessage"] = "You have been forcibly disconnected by the server";
} }
void InWorld::CheckHeartBeat() {
//check the connection (heartbeat)
if (Clock::now() - lastBeat > std::chrono::seconds(3)) {
if (attemptedBeats > 2) {
//escape to the disconnect screen
SendDisconnectRequest();
SetNextScene(SceneList::DISCONNECTEDSCREEN);
ConfigUtility::GetSingleton()["client.disconnectMessage"] = "Error: Lost connection to the server";
}
else {
ServerPacket newPacket;
newPacket.type = SerialPacketType::PING;
network.SendTo(Channels::SERVER, &newPacket);
attemptedBeats++;
lastBeat = Clock::now();
}
}
}
//------------------------- //-------------------------
//map management //map management
//------------------------- //-------------------------
@@ -691,6 +675,11 @@ void InWorld::HandleCharacterSetRoom(CharacterPacket* const argPacket) {
} }
void InWorld::HandleCharacterSetOrigin(CharacterPacket* const argPacket) { void InWorld::HandleCharacterSetOrigin(CharacterPacket* const argPacket) {
//TODO: Authentication
if (argPacket->characterIndex == characterIndex) {
return;
}
//check that this character exists //check that this character exists
std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex); std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex);
if (characterIt != characterMap.end()) { if (characterIt != characterMap.end()) {
@@ -702,6 +691,11 @@ void InWorld::HandleCharacterSetOrigin(CharacterPacket* const argPacket) {
} }
void InWorld::HandleCharacterSetMotion(CharacterPacket* const argPacket) { void InWorld::HandleCharacterSetMotion(CharacterPacket* const argPacket) {
//TODO: Authentication
if (argPacket->characterIndex == characterIndex) {
return;
}
//check that this character exists //check that this character exists
std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex); std::map<int, BaseCharacter>::iterator characterIt = characterMap.find(argPacket->characterIndex);
if (characterIt != characterMap.end()) { if (characterIt != characterMap.end()) {
@@ -728,4 +722,34 @@ void InWorld::SendLocalCharacterMotion() {
newPacket.motion = localCharacter->GetMotion(); newPacket.motion = localCharacter->GetMotion();
network.SendTo(Channels::SERVER, &newPacket); network.SendTo(Channels::SERVER, &newPacket);
}
std::list<BoundingBox> InWorld::GenerateCollisionGrid(Entity* ptr, int tileWidth, int tileHeight) {
//prepare for collisions
BoundingBox wallBounds = {0, 0, tileWidth, tileHeight};
std::list<BoundingBox> boxList;
//NOTE: for loops were too dense to work with, so I've just used while loops
//outer loop
wallBounds.x = snapToBase((double)wallBounds.w, ptr->GetOrigin().x);
while(wallBounds.x < (ptr->GetOrigin() + ptr->GetBounds()).x + ptr->GetBounds().w) {
//inner loop
wallBounds.y = snapToBase((double)wallBounds.h, ptr->GetOrigin().y);
while(wallBounds.y < (ptr->GetOrigin() + ptr->GetBounds()).y + ptr->GetBounds().h) {
//check to see if this tile is solid
if (regionPager.GetSolid(wallBounds.x / wallBounds.w, wallBounds.y / wallBounds.h)) {
//push onto the box set
boxList.push_front(wallBounds);
}
//increment
wallBounds.y += wallBounds.h;
}
//increment
wallBounds.x += wallBounds.w;
}
return std::move(boxList);
} }
+3
View File
@@ -85,6 +85,8 @@ protected:
void HandleDisconnectResponse(ClientPacket* const); void HandleDisconnectResponse(ClientPacket* const);
void HandleDisconnectForced(ClientPacket* const); void HandleDisconnectForced(ClientPacket* const);
void CheckHeartBeat();
//map management //map management
void SendRegionRequest(int roomIndex, int x, int y); void SendRegionRequest(int roomIndex, int x, int y);
void HandleRegionContent(RegionPacket* const); void HandleRegionContent(RegionPacket* const);
@@ -100,6 +102,7 @@ protected:
//player movement //player movement
void SendLocalCharacterMotion(); void SendLocalCharacterMotion();
std::list<BoundingBox> GenerateCollisionGrid(Entity*, int tileWidth, int tileHeight);
//indexes //indexes
int& clientIndex; int& clientIndex;
+4
View File
@@ -92,6 +92,10 @@ public:
return ret; return ret;
} }
//unary operators
Vector2 operator-() { return {-x, -y}; }
//comparison operators
bool operator==(Vector2 v) { return (x == v.x && y == v.y); } bool operator==(Vector2 v) { return (x == v.x && y == v.y); }
bool operator!=(Vector2 v) { return (x != v.x || y != v.y); } bool operator!=(Vector2 v) { return (x != v.x || y != v.y); }
-31
View File
@@ -1,31 +0,0 @@
TODO: Account system needs salts & hashes for security
TODO: Character system might need an API
TODO: Door system needs an API
TODO: monster system needs an API
TODO: rewrite the main body of the server
TODO: I need a better way to handle the statistics
TODO: Fix shoddy movement
TODO: Handle statistics server-side
TODO: Periodic mass server saves
TODO: join vs login
TODO: Remove the big "Shut Down" button
TODO: Make a way for the server owner to control the server directly
TODO: The TileSheet class should implement the surface itself
TODO: Passwords/Authentication
TODO: Time delay for requesting region packets
TODO: A proper logging system
-------------------------
The entities might need an API, which interfaces with all entity types (characters, monsters, doors, etc.)
The Entity base class handles position (including room) and motion, so something generic like this could be used (or aliased by other APIs)
entity:
-------------------------
Lobby:
JOIN_REQUEST -> JOIN_RESPONSE, JOIN_REJECTION
LOGIN_REQUEST -> LOGIN_RESPONSE, LOGIN_REJECTION