|
@@ -3,7 +3,6 @@
|
|
|
#include "Game.h"
|
|
|
#include "BlockType.h"
|
|
|
#include "ItemSkill.h"
|
|
|
-#include "PlaceBlockUpdate.h"
|
|
|
#include "EntityRemovedUpdate.h"
|
|
|
|
|
|
|
|
@@ -47,11 +46,9 @@ void ActionTarget::placeBlock(Entity* zActor, Item* zItem)
|
|
|
Block* block = zItem->zPlacedBlockType()->createBlockAt(blockPos + getDirection(targetBlockSide), zItem);
|
|
|
if (block)
|
|
|
{
|
|
|
- if (Game::INSTANCE->requestWorldUpdate(new PlaceBlockUpdate(block, block->getPos(), zActor->getCurrentDimensionId())))
|
|
|
- {
|
|
|
- zItem->onPlaced();
|
|
|
- // TODO: decrese stamina of actor
|
|
|
- }
|
|
|
+ Game::INSTANCE->zDimension(zActor->getCurrentDimensionId())->placeBlock(block->getPos(), block);
|
|
|
+ zItem->onPlaced();
|
|
|
+ // TODO: decrese stamina of actor
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -165,11 +162,14 @@ void Entity::useItem(const ItemType* zType, Item* zItem)
|
|
|
}
|
|
|
else if (zItem && zItem->isPlaceable())
|
|
|
{ // TODO: place item
|
|
|
+ cs.lock();
|
|
|
if (target)
|
|
|
target->placeBlock(this, zItem);
|
|
|
+ cs.unlock();
|
|
|
}
|
|
|
else if (!zItem || zItem->isUsable())
|
|
|
{ // use item skill
|
|
|
+ cs.lock();
|
|
|
if (target)
|
|
|
{
|
|
|
ItemSkill* selected = 0;
|
|
@@ -188,37 +188,65 @@ void Entity::useItem(const ItemType* zType, Item* zItem)
|
|
|
}
|
|
|
target->applyItemSkillOnTarget(this, selected, zItem);
|
|
|
}
|
|
|
+ cs.unlock();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void Entity::onTargetChange()
|
|
|
{}
|
|
|
|
|
|
-void Entity::prepareTick(const Dimension* zDimension)
|
|
|
-{
|
|
|
- Vec3<float> headPosition = location + faceOffset;
|
|
|
+void Entity::addMovementFrame(MovementFrame& frame)
|
|
|
+{
|
|
|
+ cs.lock();
|
|
|
+ movements.add(frame);
|
|
|
+ cs.unlock();
|
|
|
+ NetworkMessage message;
|
|
|
+ message.addressEntity(this);
|
|
|
+ char msg[37];
|
|
|
+ msg[0] = 0;
|
|
|
+ *(float*)(msg + 1) = frame.direction.x;
|
|
|
+ *(float*)(msg + 5) = frame.direction.y;
|
|
|
+ *(float*)(msg + 9) = frame.direction.z;
|
|
|
+ *(float*)(msg + 13) = frame.targetPosition.x;
|
|
|
+ *(float*)(msg + 17) = frame.targetPosition.y;
|
|
|
+ *(float*)(msg + 21) = frame.targetPosition.z;
|
|
|
+ *(int*)(msg + 25) = frame.movementFlags;
|
|
|
+ *(double*)(msg + 29) = frame.duration;
|
|
|
+ message.setMessage(msg, 37, 0);
|
|
|
+ Game::INSTANCE->broadcastMessage(&message);
|
|
|
+ // TODO: implement movement on server
|
|
|
+ setPosition(frame.targetPosition);
|
|
|
+ faceDir = frame.direction;
|
|
|
+ // TODO implement subscription system to notify only interested clients
|
|
|
+}
|
|
|
+
|
|
|
+void Entity::calculateTarget(Framework::Vec3<float> basePos, Framework::Vec3<float> direction)
|
|
|
+{
|
|
|
+ Vec3<float> headPosition = basePos + faceOffset;
|
|
|
int px = (int)floor(headPosition.x);
|
|
|
int py = (int)floor(headPosition.y);
|
|
|
int pz = (int)floor(headPosition.z);
|
|
|
- faceDir.normalize();
|
|
|
+ direction.normalize();
|
|
|
Direction dir = BOTTOM;
|
|
|
while (true)
|
|
|
{
|
|
|
- if (getDefaultBlock(Game::INSTANCE->zBlockAt(Vec3<int>{ px, py, pz }, zDimension->getDimensionId()))->isInteractable())
|
|
|
+ if (getDefaultBlock(Game::INSTANCE->zBlockAt(Vec3<int>{ px, py, pz }, currentDimensionId))->isInteractable())
|
|
|
{
|
|
|
if (!target || !target->isBlock({ px, py, pz }, dir))
|
|
|
{
|
|
|
+ cs.lock();
|
|
|
delete target;
|
|
|
target = new ActionTarget({ px, py, pz }, dir);
|
|
|
+ cs.unlock();
|
|
|
onTargetChange();
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
// collision to neighbor of current block
|
|
|
- if (faceDir.x > 0)
|
|
|
+ if (direction.x > 0)
|
|
|
{
|
|
|
- float xt = ((float)px + 1.f - headPosition.x) / faceDir.x;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * xt;
|
|
|
+ float xt = ((float)px + 1.f - headPosition.x) / direction.x;
|
|
|
+ Vec3<float> tmp = headPosition + direction * xt;
|
|
|
if (xt <= targetDistanceLimit && tmp.y >= (float)py && tmp.y < (float)py + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
|
|
|
{
|
|
|
dir = WEST;
|
|
@@ -226,10 +254,10 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- if (faceDir.x < 0)
|
|
|
+ if (direction.x < 0)
|
|
|
{
|
|
|
- float xt = ((float)px - headPosition.x) / faceDir.x;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * xt;
|
|
|
+ float xt = ((float)px - headPosition.x) / direction.x;
|
|
|
+ Vec3<float> tmp = headPosition + direction * xt;
|
|
|
if (xt <= targetDistanceLimit && tmp.y >= (float)py && tmp.y < (float)py + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
|
|
|
{
|
|
|
dir = EAST;
|
|
@@ -237,10 +265,10 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- if (faceDir.y > 0)
|
|
|
+ if (direction.y > 0)
|
|
|
{
|
|
|
- float yt = ((float)py + 1.f - headPosition.y) / faceDir.y;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * yt;
|
|
|
+ float yt = ((float)py + 1.f - headPosition.y) / direction.y;
|
|
|
+ Vec3<float> tmp = headPosition + direction * yt;
|
|
|
if (yt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
|
|
|
{
|
|
|
dir = NORTH;
|
|
@@ -248,10 +276,10 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- if (faceDir.y < 0)
|
|
|
+ if (direction.y < 0)
|
|
|
{
|
|
|
- float yt = ((float)py - headPosition.y) / faceDir.y;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * yt;
|
|
|
+ float yt = ((float)py - headPosition.y) / direction.y;
|
|
|
+ Vec3<float> tmp = headPosition + direction * yt;
|
|
|
if (yt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.z >= (float)pz && tmp.z < (float)pz + 1.f)
|
|
|
{
|
|
|
dir = SOUTH;
|
|
@@ -259,10 +287,10 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- if (faceDir.z > 0)
|
|
|
+ if (direction.z > 0)
|
|
|
{
|
|
|
- float zt = ((float)pz + 1.f - headPosition.z) / faceDir.z;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * zt;
|
|
|
+ float zt = ((float)pz + 1.f - headPosition.z) / direction.z;
|
|
|
+ Vec3<float> tmp = headPosition + direction * zt;
|
|
|
if (zt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.y >= (float)py && tmp.y < (float)py + 1.f)
|
|
|
{
|
|
|
dir = BOTTOM;
|
|
@@ -270,10 +298,10 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
|
- if (faceDir.z < 0)
|
|
|
+ if (direction.z < 0)
|
|
|
{
|
|
|
- float zt = ((float)pz - headPosition.z) / faceDir.z;
|
|
|
- Vec3<float> tmp = headPosition + faceDir * zt;
|
|
|
+ float zt = ((float)pz - headPosition.z) / direction.z;
|
|
|
+ Vec3<float> tmp = headPosition + direction * zt;
|
|
|
if (zt <= targetDistanceLimit && tmp.x >= (float)px && tmp.x < (float)px + 1.f && tmp.y >= (float)py && tmp.y < (float)py + 1)
|
|
|
{
|
|
|
dir = TOP;
|
|
@@ -283,26 +311,33 @@ void Entity::prepareTick(const Dimension* zDimension)
|
|
|
}
|
|
|
if (target)
|
|
|
{
|
|
|
+ cs.lock();
|
|
|
delete target;
|
|
|
target = 0;
|
|
|
+ cs.unlock();
|
|
|
onTargetChange();
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void Entity::prepareTick(const Dimension* zDimension)
|
|
|
+{}
|
|
|
+
|
|
|
void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
+ /*
|
|
|
Vec3<float> oldPos = location;
|
|
|
// current block cooredinates
|
|
|
int px = (int)floor(location.x);
|
|
|
int py = (int)floor(location.y);
|
|
|
int pz = (int)floor(location.z);
|
|
|
// falling down
|
|
|
- speed.z -= (zDimension->getGravity() * gravityMultiplier) / 30.f;
|
|
|
+ speed.z -= (zDimension->getGravity() * gravityMultiplier) * time;
|
|
|
// movement in current tick
|
|
|
- Vec3<float> frameSpeed = speed / 30.f;
|
|
|
+ Vec3<float> frameSpeed = speed * time;
|
|
|
// loop through all collided blocks
|
|
|
+ bool hasCollided = 0;
|
|
|
bool needCollisionCheck = 1;
|
|
|
while (needCollisionCheck)
|
|
|
{
|
|
@@ -318,6 +353,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
frameSpeed.x = frameSpeed.x * (xt - 0.1f);
|
|
|
speed.x = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
px++;
|
|
@@ -335,6 +371,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
frameSpeed.x = frameSpeed.x * (xt - 0.1f);
|
|
|
speed.x = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
px--;
|
|
@@ -352,6 +389,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
frameSpeed.y = frameSpeed.y * (yt - 0.1f);
|
|
|
speed.y = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
py++;
|
|
@@ -369,6 +407,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
frameSpeed.y = frameSpeed.y * (yt - 0.1f);
|
|
|
speed.y = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
py--;
|
|
@@ -386,6 +425,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
{
|
|
|
frameSpeed.z = frameSpeed.z * (zt - 0.1f);
|
|
|
speed.z = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
pz++;
|
|
@@ -404,6 +444,7 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
frameSpeed.z = frameSpeed.z * (zt - 0.1f);
|
|
|
onFall(speed.z);
|
|
|
speed.z = 0;
|
|
|
+ hasCollided = 1;
|
|
|
}
|
|
|
else
|
|
|
pz--;
|
|
@@ -413,18 +454,18 @@ void Entity::tick(const Dimension* zDimension)
|
|
|
}
|
|
|
}
|
|
|
location += frameSpeed;
|
|
|
- if (oldPos != location)
|
|
|
+ if (hasCollided)
|
|
|
{
|
|
|
NetworkMessage changeMsg;
|
|
|
changeMsg.addressEntity(this);
|
|
|
char msg[13];
|
|
|
- msg[0] = 0; // position changed
|
|
|
+ msg[0] = 1; // position correction
|
|
|
*(float*)(msg + 1) = this->location.x;
|
|
|
*(float*)(msg + 5) = this->location.y;
|
|
|
*(float*)(msg + 9) = this->location.z;
|
|
|
changeMsg.setMessage(msg, 13, 0);
|
|
|
- Game::INSTANCE->broadcastMessage(&changeMsg);
|
|
|
- }
|
|
|
+ Game::INSTANCE->sendMessage(&changeMsg, this);
|
|
|
+ }*/
|
|
|
}
|
|
|
|
|
|
void Entity::api(Framework::StreamReader* zRequest, NetworkMessage* zResponse)
|
|
@@ -537,3 +578,8 @@ ModelInfo Entity::getSpecialModel() const
|
|
|
{
|
|
|
return ModelInfo("", "", 0);
|
|
|
}
|
|
|
+
|
|
|
+float Entity::getMaxSpeed() const
|
|
|
+{
|
|
|
+ return maxMovementSpeed;
|
|
|
+}
|