Implemented (display) player rotation
10
Audio.cpp
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Diggler {
|
||||
|
||||
Audio::Audio(Game* G) : G(G), sounds(m_sounds) {
|
||||
Audio::Audio(Game &G) : G(G), sounds(m_sounds) {
|
||||
if (!GlobalProperties::IsSoundEnabled)
|
||||
return;
|
||||
|
||||
|
@ -64,8 +64,8 @@ Audio::~Audio() {
|
|||
static ALfloat float3data[3], plrOrient[6];
|
||||
|
||||
void Audio::updateAngle() {
|
||||
const glm::vec3 &at = G->LP->camera.getLookAt(),
|
||||
&up = G->LP->camera.getUp();
|
||||
const glm::vec3 &at = G.LP->camera.getLookAt(),
|
||||
&up = G.LP->camera.getUp();
|
||||
plrOrient[0] = at.x;
|
||||
plrOrient[1] = at.y;
|
||||
plrOrient[2] = at.z;
|
||||
|
@ -76,8 +76,8 @@ void Audio::updateAngle() {
|
|||
}
|
||||
|
||||
void Audio::updatePos() {
|
||||
const glm::vec3 &pos = G->LP->position,
|
||||
&vel = G->LP->velocity;
|
||||
const glm::vec3 &pos = G.LP->position,
|
||||
&vel = G.LP->velocity;
|
||||
float3data[0] = pos.x;
|
||||
float3data[1] = pos.y;
|
||||
float3data[2] = pos.z;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Game;
|
|||
|
||||
class Audio {
|
||||
private:
|
||||
Game *G;
|
||||
Game &G;
|
||||
std::map<std::string, SoundBuffer> m_sounds;
|
||||
std::list<Sound> m_playing;
|
||||
void gc();
|
||||
|
@ -21,7 +21,7 @@ private:
|
|||
ALCcontext *m_audioContext;
|
||||
|
||||
public:
|
||||
Audio(Game *G);
|
||||
Audio(Game &G);
|
||||
~Audio();
|
||||
|
||||
const std::map<std::string, SoundBuffer> &sounds;
|
||||
|
|
|
@ -39,7 +39,7 @@ bool Blocks::isTransparent(BlockType t) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Blocks::isFaceRemoved(BlockType t, BlockType other) {
|
||||
bool Blocks::isFaceVisible(BlockType t, BlockType other) {
|
||||
if (isTransparent(t)) {
|
||||
return (t != other);
|
||||
} else {
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
Blocks();
|
||||
~Blocks();
|
||||
static bool isTransparent(BlockType t);
|
||||
static bool isFaceRemoved(BlockType t, BlockType other);
|
||||
static bool isFaceVisible(BlockType t, BlockType other);
|
||||
static bool canGoThrough(BlockType t, Player::Team team);
|
||||
const AtlasCreator::Coord* gTC(BlockType, FaceDirection) const;
|
||||
Texture* getAtlas() const;
|
||||
|
|
49
Chunk.cpp
|
@ -146,10 +146,11 @@ void Chunk::updateServerSwap() {
|
|||
std::swap(blk, blk2);
|
||||
}
|
||||
|
||||
struct RGB { float r, g, b; };
|
||||
void Chunk::updateClient() {
|
||||
mut.lock();
|
||||
GLCoord vertex[CX * CY * CZ * 6 /* faces */ * 6 /* vertices */ / 2 /* face removing (HSR) makes a lower vert max */];
|
||||
GLushort index[CX * CY * CZ * 6 /* faces */ * 4 /* indexes */ / 2 /* HSR */];
|
||||
GLCoord vertex[CX * CY * CZ * 6 /* faces */ * 4 /* vertices */ / 2 /* face removing (HSR) makes a lower vert max */];
|
||||
GLushort index[CX * CY * CZ * 6 /* faces */ * 4 /* indices */ / 2 /* HSR */];
|
||||
int v = 0, i = 0;
|
||||
|
||||
BlockType bt;
|
||||
|
@ -158,13 +159,43 @@ void Chunk::updateClient() {
|
|||
for(uint8 y = 0; y < CY; y++) {
|
||||
for(uint8 z = 0; z < CZ; z++) {
|
||||
bt = blk[I(x,y,z)];
|
||||
|
||||
|
||||
// Empty block?
|
||||
if (!bt)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
BlockType
|
||||
/* -X face*/
|
||||
bNNZ = get(x-1, y-1, z),
|
||||
bNPZ = get(x-1, y+1, z),
|
||||
bNZN = get(x-1, y, z-1),
|
||||
bNZP = get(x-1, y, z+1),
|
||||
/* +X face*/
|
||||
bPNZ = get(x+1, y-1, z),
|
||||
bPPZ = get(x+1, y+1, z),
|
||||
bPZN = get(x+1, y, z-1),
|
||||
bPZP = get(x+1, y, z+1),
|
||||
/* Top & bottom */
|
||||
bZPN = get(x, y+1, z-1),
|
||||
bZPP = get(x, y+1, z+1),
|
||||
bZNN = get(x, y-1, z-1),
|
||||
bZNP = get(x, y+1, z+1);
|
||||
|
||||
RGB bl = {.6f, .6f, .6f}, br = {.6f, .6f, .6f},
|
||||
tl = {.6f, .6f, .6f}, tr = {.6f, .6f, .6f};
|
||||
if (bNZN == BlockType::Lava || bNNZ == BlockType::Lava) { bl.r = 1.6f; bl.g = 1.2f; }
|
||||
if (bNNZ == BlockType::Lava || bNZP == BlockType::Lava) { br.r = 1.6f; br.g = 1.2f; }
|
||||
if (bNZP == BlockType::Lava || bNPZ == BlockType::Lava) { tr.r = 1.6f; tr.g = 1.2f; }
|
||||
if (bNPZ == BlockType::Lava || bNZN == BlockType::Lava) { tl.r = 1.6f; tl.g = 1.2f; }
|
||||
vertex[v++] = {x, y, z, tc->x, tc->v, bl.r, bl.g, bl.b};
|
||||
vertex[v++] = {x, y, z + 1, tc->u, tc->v, br.r, br.g, br.b};
|
||||
vertex[v++] = {x, y + 1, z, tc->x, tc->y, tl.r, tl.g, tl.b};
|
||||
vertex[v++] = {x, y + 1, z + 1, tc->u, tc->y, tr.r, tr.g, tr.b};
|
||||
#endif
|
||||
|
||||
// View from negative x
|
||||
if (Blocks::isFaceRemoved(bt, get(x - 1, y, z))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x - 1, y, z))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
tc = BlkInf->gTC(bt, FaceDirection::XDec);
|
||||
|
@ -175,7 +206,7 @@ void Chunk::updateClient() {
|
|||
}
|
||||
|
||||
// View from positive x
|
||||
if (Blocks::isFaceRemoved(bt, get(x + 1, y, z))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x + 1, y, z))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
tc = BlkInf->gTC(bt, FaceDirection::XInc);
|
||||
|
@ -186,7 +217,7 @@ void Chunk::updateClient() {
|
|||
}
|
||||
|
||||
// Negative Y
|
||||
if (Blocks::isFaceRemoved(bt, get(x, y - 1, z))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x, y - 1, z))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
float shade = (blk[I(x,y,z)] == BlockType::Shock) ? 1.5f : .2f;;
|
||||
|
@ -198,7 +229,7 @@ void Chunk::updateClient() {
|
|||
}
|
||||
|
||||
// Positive Y
|
||||
if (Blocks::isFaceRemoved(bt, get(x, y + 1, z))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x, y + 1, z))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
tc = BlkInf->gTC(bt, FaceDirection::YInc);
|
||||
|
@ -209,7 +240,7 @@ void Chunk::updateClient() {
|
|||
}
|
||||
|
||||
// Negative Z
|
||||
if (Blocks::isFaceRemoved(bt, get(x, y, z - 1))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x, y, z - 1))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
tc = BlkInf->gTC(bt, FaceDirection::ZDec);
|
||||
|
@ -220,7 +251,7 @@ void Chunk::updateClient() {
|
|||
}
|
||||
|
||||
// Positive Z
|
||||
if (Blocks::isFaceRemoved(bt, get(x, y, z + 1))) {
|
||||
if (Blocks::isFaceVisible(bt, get(x, y, z + 1))) {
|
||||
index[i++] = v; index[i++] = v+1; index[i++] = v+2;
|
||||
index[i++] = v+3; index[i++] = v+2; index[i++] = v+1;
|
||||
tc = BlkInf->gTC(bt, FaceDirection::ZInc);
|
||||
|
|
4
Game.cpp
|
@ -15,8 +15,8 @@ void Game::init() {
|
|||
PM = new ProgramManager(*this);
|
||||
LP = new LocalPlayer(this);
|
||||
RP = new RenderProperties;
|
||||
A = new Audio(this);
|
||||
KB = new KeyBinds();
|
||||
A = new Audio(*this);
|
||||
KB = new KeyBinds;
|
||||
}
|
||||
if (GlobalProperties::IsServer) {
|
||||
CCH = new ChunkChangeHelper();
|
||||
|
|
9
Game.hpp
|
@ -14,9 +14,6 @@ namespace UI {
|
|||
class Manager;
|
||||
}
|
||||
|
||||
class Audio;
|
||||
class KeyBinds;
|
||||
|
||||
class Game {
|
||||
public:
|
||||
// Shared
|
||||
|
@ -39,9 +36,9 @@ public:
|
|||
struct RenderProperties {
|
||||
bool bloom;
|
||||
} *RP;
|
||||
Audio *A;
|
||||
Net::Peer NS; // Net Server
|
||||
KeyBinds *KB;
|
||||
class Audio *A;
|
||||
Net::Peer NS;
|
||||
class KeyBinds *KB;
|
||||
|
||||
Game();
|
||||
void init();
|
||||
|
|
|
@ -320,6 +320,7 @@ void GameState::onCursorPos(double x, double y) {
|
|||
if(angles.y > M_PI / 2)
|
||||
angles.y = M_PI / 2 - 0.001;
|
||||
|
||||
G->LP->angle = angles.x;
|
||||
lookat.x = sinf(angles.x) * cosf(angles.y);
|
||||
lookat.y = sinf(angles.y);
|
||||
lookat.z = cosf(angles.x) * cosf(angles.y);
|
||||
|
@ -513,6 +514,7 @@ void GameState::gameLoop() {
|
|||
msg.writeVec3(LP->position);
|
||||
msg.writeVec3(LP->velocity);
|
||||
msg.writeVec3(LP->accel);
|
||||
msg.writeFloat(LP->angle);
|
||||
sendMsg(msg, Net::Tfer::Unrel, Net::Channels::Movement);
|
||||
nextNetUpdate = T+0.25;//+1;
|
||||
}
|
||||
|
@ -665,7 +667,8 @@ void GameState::renderDeathScreen() {
|
|||
}
|
||||
|
||||
void GameState::updateUI() {
|
||||
int altitude = G->LP->position.y;
|
||||
LocalPlayer &LP = *G->LP;
|
||||
int altitude = LP.position.y;
|
||||
if (altitude != UI.lastAltitude) {
|
||||
char str[15]; std::snprintf(str, 15, "Altitude: %d", altitude);
|
||||
UI.lastAltitude = altitude;
|
||||
|
@ -674,11 +677,12 @@ void GameState::updateUI() {
|
|||
if (showDebugInfo) {
|
||||
std::ostringstream oss;
|
||||
oss << std::setprecision(3) <<
|
||||
W->getW() << 'x' << W->getH() << std::endl <<
|
||||
"x: " << G->LP->position.x << std::endl <<
|
||||
"y: " << G->LP->position.y << std::endl <<
|
||||
"z: " << G->LP->position.z << std::endl <<
|
||||
"vy: " << G->LP->velocity.y << std::endl;
|
||||
"HP: " << LP.health << std::endl <<
|
||||
"x: " << LP.position.x << std::endl <<
|
||||
"y: " << LP.position.y << std::endl <<
|
||||
"z: " << LP.position.z << std::endl <<
|
||||
"vy: " << LP.velocity.y << std::endl <<
|
||||
"rx: " << LP.angle << std::endl;
|
||||
UI.DebugInfo->setText(oss.str());
|
||||
}
|
||||
}
|
||||
|
@ -733,6 +737,7 @@ bool GameState::processNetwork() {
|
|||
vel = m_msg.readVec3(),
|
||||
acc = m_msg.readVec3();
|
||||
plr.setPosVel(pos, vel, acc);
|
||||
plr.angle = m_msg.readFloat();
|
||||
} break;
|
||||
case Net::PlayerUpdateType::Die:
|
||||
plr.setDead(false, (Player::DeathReason)m_msg.readU8());
|
||||
|
|
|
@ -66,7 +66,7 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
|||
#if GLM_ARCH & GLM_ARCH_SSE2
|
||||
<< "SSE2"
|
||||
#endif
|
||||
<< std::endl;
|
||||
;
|
||||
|
||||
if (!IsGlewInited) {
|
||||
GLenum glewStatus = glewInit();
|
||||
|
@ -75,7 +75,7 @@ GameWindow::GameWindow(Game *G) : G(G) {
|
|||
std::terminate();
|
||||
}
|
||||
IsGlewInited = true;
|
||||
getOutputStreamRaw() << "GLEW " << glewGetString(GLEW_VERSION) << std::endl;
|
||||
getOutputStreamRaw() << " -- GLEW " << glewGetString(GLEW_VERSION) << std::endl;
|
||||
}
|
||||
|
||||
if (InstanceCount == 1) { // If we're the first instance
|
||||
|
|
|
@ -11,17 +11,19 @@ namespace Diggler {
|
|||
|
||||
static float Acceleration = 18.0f;
|
||||
|
||||
static float MvmtDamping = 1/Acceleration;
|
||||
static float MvmtDamping = 1/(Acceleration*2.f);
|
||||
|
||||
static float Gravity = 18.0f; // -Y acceleration (blocks/sec/sec)
|
||||
|
||||
static float JumpForce = Gravity/2.8f;
|
||||
static float JumpForce = Gravity/2.7f;
|
||||
|
||||
static float MaxSpeed = 5.f;
|
||||
static float RoadMaxSpeed = MaxSpeed*2;
|
||||
|
||||
static float MinYVelocity = -80.f;
|
||||
static float MinLethalYVelocity = -20.f;
|
||||
|
||||
static float HurtYVelocity = -12.f;
|
||||
static float LethalYVelocity = -16.f;
|
||||
|
||||
static int i(const float &f) {
|
||||
if (f >= 0)
|
||||
|
@ -30,14 +32,11 @@ static int i(const float &f) {
|
|||
}
|
||||
|
||||
LocalPlayer::LocalPlayer(Game *G) : Player(G), goingForward(false), goingBackward(false), goingLeft(false), goingRight(false),
|
||||
hasGravity(true), hasNoclip(false) {
|
||||
hasGravity(true), hasNoclip(false), health(1) {
|
||||
size = glm::vec3(0.3f, 1.9f, 0.3f);
|
||||
eyesPos = glm::vec3(0.f, 1.3f, 0.f);
|
||||
}
|
||||
|
||||
void LocalPlayer::special1() {
|
||||
}
|
||||
|
||||
// Thanks http://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
|
||||
// FIXME: not all platforms use IEEE754
|
||||
inline double fpow(double a, double b) {
|
||||
|
@ -56,6 +55,10 @@ void LocalPlayer::lookAt(const glm::vec3& at) {
|
|||
}
|
||||
|
||||
void LocalPlayer::update(const float &delta) {
|
||||
health += delta/10;
|
||||
if (health >= 1)
|
||||
health = 1;
|
||||
|
||||
bool moving = goingForward || goingBackward || goingLeft || goingRight;
|
||||
glm::vec3 initialVel = velocity;
|
||||
if (!moving) {
|
||||
|
@ -65,7 +68,7 @@ void LocalPlayer::update(const float &delta) {
|
|||
if (!this->hasGravity)
|
||||
velocity.y *= finalDamp;
|
||||
}
|
||||
|
||||
|
||||
// Apply player's will movement
|
||||
glm::vec3 normMove = glm::normalize(glm::vec3(camera.m_lookAt.x, camera.m_lookAt.y * !hasGravity, camera.m_lookAt.z));
|
||||
float acceleration = Acceleration*delta;
|
||||
|
@ -81,16 +84,20 @@ void LocalPlayer::update(const float &delta) {
|
|||
if (goingRight) {
|
||||
velocity -= acceleration * glm::rotateY(glm::normalize(glm::vec3(normMove.x, 0, normMove.z)), (float)M_PI/2);
|
||||
}
|
||||
|
||||
|
||||
// Apply gravity
|
||||
if (hasGravity) {
|
||||
if (!onGround && velocity.y <= MinLethalYVelocity) {
|
||||
if (!onGround && velocity.y <= HurtYVelocity) {
|
||||
BlockType b = G->SC->get(position.x, position.y-1, position.z);
|
||||
onGround = !Blocks::canGoThrough(b, team);
|
||||
if (onGround) {
|
||||
setDead(true, DeathReason::Fall, true);
|
||||
velocity = glm::vec3(0);
|
||||
return;
|
||||
if (velocity.y <= LethalYVelocity) {
|
||||
setDead(true, DeathReason::Fall, true);
|
||||
velocity = glm::vec3(0);
|
||||
return;
|
||||
}
|
||||
G->A->playSound("hitground");
|
||||
health -= (velocity.y-HurtYVelocity)/(LethalYVelocity-HurtYVelocity);
|
||||
}
|
||||
}
|
||||
if (onGround) {
|
||||
|
@ -101,7 +108,7 @@ void LocalPlayer::update(const float &delta) {
|
|||
if (!onGround)
|
||||
velocity.y -= Gravity * delta;
|
||||
}
|
||||
|
||||
|
||||
if (!hasNoclip) {
|
||||
glm::vec3 velXZ(velocity.x, 0, velocity.z);
|
||||
int maxSpeed = (onRoad ? RoadMaxSpeed : MaxSpeed);
|
||||
|
@ -113,14 +120,14 @@ void LocalPlayer::update(const float &delta) {
|
|||
if (velocity.y < MinYVelocity)
|
||||
velocity.y = MinYVelocity;
|
||||
}
|
||||
|
||||
|
||||
if (velocity.x > -0.001f && velocity.x < 0.001f) velocity.x = 0.f;
|
||||
if (velocity.y > -0.001f && velocity.y < 0.001f) velocity.y = 0.f;
|
||||
if (velocity.z > -0.001f && velocity.z < 0.001f) velocity.z = 0.f;
|
||||
|
||||
|
||||
glm::vec3 destPos = position + velocity * delta;
|
||||
accel = velocity - initialVel;
|
||||
|
||||
|
||||
if (velocity != glm::vec3(0.f)) { // avoids useless calculus
|
||||
if (hasNoclip) {
|
||||
position = destPos;
|
||||
|
@ -197,7 +204,7 @@ void LocalPlayer::update(const float &delta) {
|
|||
switch (bBottom) {
|
||||
case BlockType::Jump:
|
||||
if (G->Time - lastJumpTime > 0.2) {
|
||||
velocity.y = JumpForce * 2;
|
||||
velocity.y = JumpForce * 1.6f;
|
||||
NetHelper::SendEvent(G, Net::EventType::PlayerJumpOnPad);
|
||||
lastJumpTime = G->Time;
|
||||
}
|
||||
|
@ -212,9 +219,7 @@ void LocalPlayer::update(const float &delta) {
|
|||
}
|
||||
position += velocity * delta;
|
||||
}
|
||||
|
||||
camera.setPosition(position + eyesPos);
|
||||
|
||||
G->A->updatePos();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ private:
|
|||
bool hasGravity, hasNoclip, onGround, onRoad;
|
||||
|
||||
public:
|
||||
float health;
|
||||
// Fixes
|
||||
double lastJumpTime = 0.0;
|
||||
double deathTime = 0.0;
|
||||
|
@ -42,7 +43,6 @@ public:
|
|||
void setDead(bool, DeathReason = DeathReason::None, bool send = false);
|
||||
bool raytracePointed(glm::ivec3 *pointed, glm::ivec3 *face);
|
||||
bool raytracePointed(int maxDist, glm::ivec3 *pointed, glm::ivec3 *face, float granularity = .2f);
|
||||
void special1();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "Mutex.hpp"
|
||||
#include <cstdlib>
|
||||
#include "Platform.hpp"
|
||||
|
||||
#ifdef BUILDINFO_PLATFORM_PTHREAD
|
||||
#include <pthread.h>
|
||||
|
||||
namespace Diggler {
|
||||
|
@ -26,4 +29,6 @@ void Mutex::unlock() {
|
|||
pthread_mutex_unlock((pthread_mutex_t*)data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -218,4 +218,11 @@ std::ostream &Diggler::getOutputStreamRaw() {
|
|||
return std::cout;
|
||||
}
|
||||
|
||||
float Diggler::rmod(float x, float y) {
|
||||
float ret = fmod(x, y);
|
||||
if (ret < 0)
|
||||
return y+ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint Diggler::FastRand_Seed = 0;
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
#elif defined(__ANDROID_API__) // Android
|
||||
#define BUILDINFO_PLATFORM "Android"
|
||||
#define BUILDINFO_PLATFORM_ANDROID
|
||||
#define BUILDINFO_PLATFORM_PTHREAD
|
||||
#elif defined(__linux__) || defined(linux) || defined(_linux) // Linux
|
||||
#define BUILDINFO_PLATFORM "Linux"
|
||||
#define BUILDINFO_PLATFORM_LINUX
|
||||
#define BUILDINFO_PLATFORM_PTHREAD
|
||||
#elif defined(__APPLE__) // Mac
|
||||
#define BUILDINFO_PLATFORM "Mac"
|
||||
#define BUILDINFO_PLATFORM_MAC
|
||||
|
@ -125,6 +127,11 @@ inline float FastRandF() {
|
|||
return (float)FastRand() / 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
///
|
||||
/// Real Modulus
|
||||
/// @returns Real modulus operation result, as such mod(x,y) is always positive
|
||||
///
|
||||
float rmod(float x, float y);
|
||||
|
||||
namespace fs {
|
||||
bool isDir(const std::string &path);
|
||||
|
|
15
Player.cpp
|
@ -67,7 +67,7 @@ int Player::getMaxWeight(Class c) {
|
|||
|
||||
Player::Player(Game *G) : team(Team::Red),
|
||||
playerclass(Class::Prospector), tool(Tools::Pickaxe), G(G),
|
||||
position(0), velocity(0), accel(0),
|
||||
position(0), velocity(0), accel(0), angle(0),
|
||||
isAlive(true), ore(0), loot(0) {
|
||||
if (GlobalProperties::IsClient) {
|
||||
if (TexInfos == nullptr) {
|
||||
|
@ -148,11 +148,20 @@ void Player::update(const float &delta) {
|
|||
m_predictPos += velocity * delta;
|
||||
}
|
||||
|
||||
static inline int getSide(float angle) {
|
||||
if (angle >= 2*M_PI-M_PI/4 || angle < M_PI/4)
|
||||
return 1; // Back
|
||||
if (angle >= M_PI/4 && angle < M_PI-M_PI/4)
|
||||
return 2; // Left
|
||||
if (angle >= M_PI-M_PI/4 && angle >= M_PI+M_PI/4)
|
||||
return 0; // Right
|
||||
return 3; // Front
|
||||
}
|
||||
|
||||
void Player::render(const glm::mat4 &transform) const {
|
||||
RenderProgram->bind();
|
||||
TexInfos[(uint8)team][(uint8)tool]->tex->bind();
|
||||
TexInfos[(uint8)team][(uint8)tool]->side[(int)(G->Time*4)%4].vbos[((int)G->Time)%4]->bind();
|
||||
//idle->bind();
|
||||
TexInfos[(uint8)team][(uint8)tool]->side[getSide(rmod(atan2(position.x-G->LP->position.x, position.z-G->LP->position.z)-angle, M_PI*2))].vbos[((int)G->Time)%4]->bind();
|
||||
glEnableVertexAttribArray(RenderProgram_attrib_texcoord);
|
||||
glEnableVertexAttribArray(RenderProgram_attrib_coord);
|
||||
glm::vec3 &lpPos = G->LP->position;
|
||||
|
|
|
@ -66,6 +66,7 @@ public:
|
|||
} deathReason;
|
||||
Game *G;
|
||||
glm::vec3 position, velocity, accel;
|
||||
float angle;
|
||||
std::string name;
|
||||
uint32 id;
|
||||
bool isAlive;
|
||||
|
|
101
Server.cpp
|
@ -19,21 +19,21 @@ namespace Diggler {
|
|||
|
||||
Player* Server::getPlayerByPeer(const Peer &peer) {
|
||||
try {
|
||||
return &G->players.getByPeer(peer);
|
||||
return &G.players.getByPeer(peer);
|
||||
} catch (const std::out_of_range &e) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Player* Server::getPlayerById(uint32 id) {
|
||||
try {
|
||||
return &G->players.getById(id);
|
||||
return &G.players.getById(id);
|
||||
} catch (const std::out_of_range &e) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Player* Server::getPlayerByName(const std::string &name) {
|
||||
try {
|
||||
return &G->players.getByName(name);
|
||||
return &G.players.getByName(name);
|
||||
} catch (const std::out_of_range &e) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ void Server::handlePlayerJoin(InMessage &msg, Peer &peer) {
|
|||
return;
|
||||
}
|
||||
|
||||
Player &plr = G->players.add();
|
||||
Player &plr = G.players.add();
|
||||
plr.name = name;
|
||||
plr.id = FastRand();
|
||||
plr.P = peer;
|
||||
|
@ -65,7 +65,7 @@ void Server::handlePlayerJoin(InMessage &msg, Peer &peer) {
|
|||
H.send(peer, join, Tfer::Rel);
|
||||
|
||||
// Send the player list
|
||||
for (Player &p : G->players) {
|
||||
for (Player &p : G.players) {
|
||||
if (p.id == plr.id)
|
||||
continue; // ok, he knows he's here
|
||||
OutMessage playerMsg(MessageType::PlayerJoin);
|
||||
|
@ -75,14 +75,14 @@ void Server::handlePlayerJoin(InMessage &msg, Peer &peer) {
|
|||
}
|
||||
|
||||
OutMessage map(MessageType::MapTransfer);
|
||||
G->SC->writeMsg(map);
|
||||
G.SC->writeMsg(map);
|
||||
H.send(peer, map, Tfer::Rel);
|
||||
|
||||
// Broadcast player's join
|
||||
OutMessage broadcast(MessageType::PlayerJoin);
|
||||
broadcast.writeU32(plr.id);
|
||||
broadcast.writeString(plr.name);
|
||||
for (Player &p : G->players) {
|
||||
for (Player &p : G.players) {
|
||||
if (p.id == plr.id)
|
||||
continue; // dont send broadcast to the player
|
||||
H.send(p.P, broadcast, Tfer::Rel);
|
||||
|
@ -97,13 +97,13 @@ void Server::handlePlayerQuit(Peer &peer, QuitReason reason) {
|
|||
// Broadcast disconnection
|
||||
OutMessage broadcast(MessageType::PlayerQuit, reason);
|
||||
broadcast.writeU32(plr.id);
|
||||
for (Player &p : G->players) {
|
||||
for (Player &p : G.players) {
|
||||
if (p.id == plr.id)
|
||||
continue; // dont send broadcast to the player
|
||||
H.send(p.P, broadcast, Tfer::Rel);
|
||||
}
|
||||
getOutputStream() << plr.name << " disconnected" << endl;
|
||||
G->players.remove(plr);
|
||||
G.players.remove(plr);
|
||||
} else {
|
||||
getOutputStream() << peer.getHost() << " disconnected" << endl;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ void Server::handleDisconnect(Peer &peer) {
|
|||
}
|
||||
|
||||
void Server::handleEvent(InMessage &msg, Peer &peer) {
|
||||
Player &plr = G->players.getByPeer(peer);
|
||||
Player &plr = G.players.getByPeer(peer);
|
||||
switch (msg.getSubtype()) {
|
||||
case Net::EventType::PlayerJumpOnPad: {
|
||||
OutMessage out;
|
||||
|
@ -130,7 +130,7 @@ void Server::handleEvent(InMessage &msg, Peer &peer) {
|
|||
void Server::handleChat(InMessage &msg, Peer &peer) {
|
||||
try {
|
||||
// TODO: implement codecvt_utf8<utf32> when libstdc++ supports it
|
||||
Player &plr = G->players.getByPeer(peer);
|
||||
Player &plr = G.players.getByPeer(peer);
|
||||
std::string chatMsg = msg.readString();
|
||||
getOutputStream() << plr.name << ": " << chatMsg << endl;
|
||||
std::ostringstream contentFormatter;
|
||||
|
@ -146,7 +146,7 @@ void Server::handleChat(InMessage &msg, Peer &peer) {
|
|||
|
||||
void Server::handlePlayerUpdate(InMessage &msg, Peer &peer) {
|
||||
try {
|
||||
Player &plr = G->players.getByPeer(peer);
|
||||
Player &plr = G.players.getByPeer(peer);
|
||||
|
||||
switch (msg.getSubtype()) {
|
||||
case PlayerUpdateType::Move: {
|
||||
|
@ -156,10 +156,13 @@ void Server::handlePlayerUpdate(InMessage &msg, Peer &peer) {
|
|||
glm::vec3 pos = msg.readVec3(),
|
||||
vel = msg.readVec3(),
|
||||
acc = msg.readVec3();
|
||||
plr.setPosVel(pos, vel, acc);
|
||||
plr.angle = msg.readFloat();
|
||||
bcast.writeVec3(pos);
|
||||
bcast.writeVec3(vel);
|
||||
bcast.writeVec3(acc);
|
||||
for (Player &p : G->players) {
|
||||
bcast.writeFloat(plr.angle);
|
||||
for (Player &p : G.players) {
|
||||
if (p.id == plr.id)
|
||||
continue; // dont send broadcast to the player
|
||||
// TODO: confirm position to player
|
||||
|
@ -182,11 +185,11 @@ void Server::handlePlayerMapUpdate(InMessage &msg, Peer &peer) {
|
|||
// TODO: distance & tool check, i.e. legitimate update
|
||||
int x = msg.readU16(), y = msg.readU16(), z = msg.readU16();
|
||||
BlockType b = (BlockType)msg.readU8();
|
||||
G->SC->set(x, y, z, b);
|
||||
G.SC->set(x, y, z, b);
|
||||
// FIXME: v This might interfere with the ticker
|
||||
if (!G->CCH->empty()) {
|
||||
OutMessage msg(MessageType::MapUpdate, G->CCH->count());
|
||||
G->CCH->flush(msg);
|
||||
if (!G.CCH->empty()) {
|
||||
OutMessage msg(MessageType::MapUpdate, G.CCH->count());
|
||||
G.CCH->flush(msg);
|
||||
NetHelper::Broadcast(G, msg, Tfer::Rel, Channels::MapUpdate);
|
||||
}
|
||||
}
|
||||
|
@ -198,13 +201,13 @@ void Server::handlePlayerDeath(InMessage &msg, Player &plr) {
|
|||
OutMessage out(MessageType::PlayerUpdate, PlayerUpdateType::Die);
|
||||
out.writeU32(plr.id);
|
||||
out.writeU8(drb);
|
||||
for (Player &p : G->players) {
|
||||
for (Player &p : G.players) {
|
||||
if (p.id != plr.id)
|
||||
H.send(p.P, out, Tfer::Rel, Channels::Life);
|
||||
}
|
||||
|
||||
// Respawn player later
|
||||
Game *G = this->G; uint32 id = plr.id;
|
||||
Game *G = &this->G; uint32 id = plr.id;
|
||||
std::thread respawn([G, id] {
|
||||
getDebugStream() << "Respawn " << id << " in 2 secs " << std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
|
@ -220,8 +223,8 @@ void Server::handlePlayerDeath(InMessage &msg, Player &plr) {
|
|||
respawn.detach();
|
||||
}
|
||||
|
||||
Server::Server(Game *G, uint16 port) : G(G) {
|
||||
G->init();
|
||||
Server::Server(Game &G, uint16 port) : G(G) {
|
||||
G.init();
|
||||
|
||||
getOutputStream() << "Diggler v" << VersionString << " Server, port " << port << ", "
|
||||
<< std::thread::hardware_concurrency() << " HW threads supported" << endl;
|
||||
|
@ -241,44 +244,44 @@ Server::Server(Game *G, uint16 port) : G(G) {
|
|||
}
|
||||
|
||||
#if 1
|
||||
G->SC->setSize(4, 4, 4);
|
||||
G.SC->setSize(4, 4, 4);
|
||||
|
||||
//for (int i=0; i < 8192; i++) G->SC->set(FastRand(CX*G->SC->getChunksX()), FastRand(CY*G->SC->getChunksY()), FastRand(CZ*G->SC->getChunksZ()), (BlockType)(FastRand((int)BlockType::LAST)));
|
||||
for(int x=0;x<CX*G->SC->getChunksX();x++) for(int z=0;z<(CZ*G->SC->getChunksZ())/2;z++) G->SC->set(x, 0, z, BlockType::Dirt);
|
||||
for(int x=0;x<CX*G->SC->getChunksX();x++) for(int z=0;z<(CZ*G->SC->getChunksZ())/2;z++) G->SC->set(x, 0, z+(CZ*G->SC->getChunksZ())/2, BlockType::Road);
|
||||
// for(int x=0;x<CX*G->SC->getChunksX();x++) for(int y=0;y<16;y++) for(int z=0;z<CZ*G->SC->getChunksZ();z++) G->SC->set(x,y,z,BlockType::Dirt);
|
||||
for(int x=0; x < (int)BlockType::LAST; x++) G->SC->set(x, 2, 0, (BlockType)(x));
|
||||
G->SC->set(4, 4, 4, BlockType::Shock);
|
||||
G->SC->set(4, 0, 4, BlockType::Jump);
|
||||
//for (int i=0; i < 8192; i++) G.SC->set(FastRand(CX*G.SC->getChunksX()), FastRand(CY*G.SC->getChunksY()), FastRand(CZ*G.SC->getChunksZ()), (BlockType)(FastRand((int)BlockType::LAST)));
|
||||
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 0, z, BlockType::Dirt);
|
||||
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 0, z+(CZ*G.SC->getChunksZ())/2, BlockType::Road);
|
||||
// for(int x=0;x<CX*G.SC->getChunksX();x++) for(int y=0;y<16;y++) for(int z=0;z<CZ*G.SC->getChunksZ();z++) G.SC->set(x,y,z,BlockType::Dirt);
|
||||
for(int x=0; x < (int)BlockType::LAST; x++) G.SC->set(x, 2, 0, (BlockType)(x));
|
||||
G.SC->set(4, 4, 4, BlockType::Shock);
|
||||
G.SC->set(4, 0, 4, BlockType::Jump);
|
||||
|
||||
G->SC->set(0, 1, 1, BlockType::Metal);
|
||||
G->SC->set(0, 2, 1, BlockType::Metal);
|
||||
G->SC->set(0, 3, 1, BlockType::Metal);
|
||||
G.SC->set(0, 1, 1, BlockType::Metal);
|
||||
G.SC->set(0, 2, 1, BlockType::Metal);
|
||||
G.SC->set(0, 3, 1, BlockType::Metal);
|
||||
|
||||
G->SC->set(1, 3, 1, BlockType::Metal);
|
||||
G->SC->set(2, 3, 1, BlockType::Metal);
|
||||
G.SC->set(1, 3, 1, BlockType::Metal);
|
||||
G.SC->set(2, 3, 1, BlockType::Metal);
|
||||
|
||||
G->SC->set(3, 1, 1, BlockType::Metal);
|
||||
G->SC->set(3, 2, 1, BlockType::Metal);
|
||||
G->SC->set(3, 3, 1, BlockType::Metal);
|
||||
G.SC->set(3, 1, 1, BlockType::Metal);
|
||||
G.SC->set(3, 2, 1, BlockType::Metal);
|
||||
G.SC->set(3, 3, 1, BlockType::Metal);
|
||||
|
||||
CaveGenerator::PaintAtPoint(*(G->SC), 8, 8, 8, 1, BlockType::Dirt);
|
||||
CaveGenerator::PaintAtPoint(*(G->SC), 16, 8, 8, 2, BlockType::Dirt);
|
||||
CaveGenerator::PaintAtPoint(*(G->SC), 24, 8, 8, 3, BlockType::Dirt);
|
||||
CaveGenerator::PaintAtPoint(*(G.SC), 8, 8, 8, 1, BlockType::Dirt);
|
||||
CaveGenerator::PaintAtPoint(*(G.SC), 16, 8, 8, 2, BlockType::Dirt);
|
||||
CaveGenerator::PaintAtPoint(*(G.SC), 24, 8, 8, 3, BlockType::Dirt);
|
||||
|
||||
for(int x=0;x<CX*G->SC->getChunksX();x++) for(int z=0;z<(CZ*G->SC->getChunksZ())/2;z++) G->SC->set(x, 64, z, BlockType::Dirt);
|
||||
G->SC->set(2*CX, 68, 2*CY, BlockType::Lava);
|
||||
for(int x=0;x<CX*G.SC->getChunksX();x++) for(int z=0;z<(CZ*G.SC->getChunksZ())/2;z++) G.SC->set(x, 64, z, BlockType::Dirt);
|
||||
G.SC->set(2*CX, 68, 2*CY, BlockType::Lava);
|
||||
#else
|
||||
G->SC->setSize(4, 4, 4);
|
||||
CaveGenerator::GenerateCaveSystem(*(G->SC), true, 15);
|
||||
G.SC->setSize(4, 4, 4);
|
||||
CaveGenerator::GenerateCaveSystem(*(G.SC), true, 15);
|
||||
#endif
|
||||
|
||||
//G->SC->save("/tmp/a");
|
||||
//G->SC->load("/tmp/a");
|
||||
//G.SC->save("/tmp/a");
|
||||
//G.SC->load("/tmp/a");
|
||||
|
||||
/*{
|
||||
Game *G = this->G;
|
||||
std::thread make([G]{CaveGenerator::GenerateCaveSystem(*(G->SC), true, 15);});
|
||||
std::thread make([G]{CaveGenerator::GenerateCaveSystem(*(G.SC), true, 15);});
|
||||
make.detach();
|
||||
}*/
|
||||
}
|
||||
|
@ -319,7 +322,7 @@ void chunk_updater(Game *G, Superchunk *sc, Host &H) {
|
|||
void Server::run() {
|
||||
InMessage msg;
|
||||
Peer peer;
|
||||
std::thread upd(chunk_updater, G, G->SC.get(), std::ref(H));
|
||||
std::thread upd(chunk_updater, &G, G.SC.get(), std::ref(H));
|
||||
while (true) {
|
||||
if (H.recv(msg, peer, 100)) {
|
||||
switch (msg.getType()) {
|
||||
|
@ -358,7 +361,7 @@ void Server::run() {
|
|||
}
|
||||
|
||||
bool Server::isPlayerOnline(const std::string &playername) const {
|
||||
for (const Player &p : G->players) {
|
||||
for (const Player &p : G.players) {
|
||||
if (p.name == playername)
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class Game;
|
|||
|
||||
class Server {
|
||||
private:
|
||||
Game *G;
|
||||
Game &G;
|
||||
|
||||
void handlePlayerJoin(Net::InMessage&, Net::Peer&);
|
||||
void handlePlayerQuit(Net::Peer&, Net::QuitReason reason = Net::QuitReason::Quit);
|
||||
|
@ -27,7 +27,7 @@ private:
|
|||
public:
|
||||
Net::Host H;
|
||||
|
||||
Server(Game *G, uint16 port);
|
||||
Server(Game &G, uint16 port);
|
||||
~Server();
|
||||
|
||||
void run();
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 957 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 977 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 915 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 906 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 871 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 975 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 866 B |
2
main.cpp
|
@ -134,7 +134,7 @@ int main(int argc, char **argv) {
|
|||
getErrorStream() << "Network init failed!" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
Server S(&G, port);
|
||||
Server S(G, port);
|
||||
G.S = &S;
|
||||
S.run();
|
||||
}
|
||||
|
|
|
@ -7,8 +7,12 @@ namespace Diggler {
|
|||
namespace NetHelper {
|
||||
|
||||
void Broadcast(Game *G, const Net::OutMessage &msg, Net::Tfer tfer, Net::Channels chan) {
|
||||
for (Player &p : G->players) {
|
||||
G->S->H.send(p.P, msg, tfer, chan);
|
||||
Broadcast(*G, msg, tfer, chan);
|
||||
}
|
||||
|
||||
void Broadcast(Game &G, const Net::OutMessage &msg, Net::Tfer tfer, Net::Channels chan) {
|
||||
for (Player &p : G.players) {
|
||||
G.S->H.send(p.P, msg, tfer, chan);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace NetHelper {
|
|||
|
||||
// Server only
|
||||
void Broadcast(Game*, const Net::OutMessage&, Net::Tfer = Net::Tfer::Rel, Net::Channels = Net::Channels::Base);
|
||||
void Broadcast(Game&, const Net::OutMessage&, Net::Tfer = Net::Tfer::Rel, Net::Channels = Net::Channels::Base);
|
||||
void MakeEvent(Net::OutMessage&, Net::EventType, const glm::vec3&);
|
||||
void MakeEvent(Net::OutMessage&, Net::EventType, const Player&);
|
||||
|
||||
|
|