소스 검색

use server side collision detection

Kolja Strohm 1 개월 전
부모
커밋
51f213aecc

+ 2 - 11
FactoryCraft/Dimension.cpp

@@ -11,8 +11,7 @@ using namespace Framework;
 Dimension::Dimension()
     : id(-1),
       chunks(new RCTrie<Chunk>()),
-      entities(new RCArray<Entity>()),
-      gravity(0.0f)
+      entities(new RCArray<Entity>())
 {}
 
 Dimension::~Dimension()
@@ -161,9 +160,6 @@ void Dimension::api(char* message)
             }
             break;
         }
-    case 6: // set gravity
-        gravity = *(float*)(message + 1);
-        break;
     case 7: // add entity
         {
             int type = *(int*)(message + 1);
@@ -346,9 +342,4 @@ void Dimension::removeEntity(int id)
 int Dimension::getId() const
 {
     return id;
-}
-
-float Dimension::getGravity() const
-{
-    return gravity;
-}
+}

+ 0 - 2
FactoryCraft/Dimension.h

@@ -13,7 +13,6 @@ class Dimension : public virtual Framework::Model3DCollection
 {
 private:
     int id;
-    float gravity;
     Framework::RCTrie<Chunk>* chunks;
     Framework::Array<Chunk*> chunkList;
     Framework::RCArray<Entity>* entities;
@@ -44,7 +43,6 @@ public:
     Entity* getEntity(int id);
     void removeEntity(int id);
     int getId() const;
-    float getGravity() const;
 
     inline static Framework::Vec3<int> chunkCoordinates(
         Framework::Vec3<int> worldLocation)

+ 40 - 534
FactoryCraft/Entity.cpp

@@ -11,28 +11,17 @@ Entity::Entity(const EntityType* zType,
     Framework::Model3DTextur* texture,
     int id,
     Framework::Vec3<float> position,
-    float maxMovementSpeed,
-    float gravityMultiplier,
-    float jumpSpeed,
     float size)
     : FactoryCraftModel(),
       id(id),
       zType(zType),
-      playerControlled(0),
-      maxMovementSpeed(maxMovementSpeed),
-      lastFlags(0),
-      timeSinceSync(0),
-      gravityMultiplier(gravityMultiplier),
-      jumpSpeed(jumpSpeed),
-      speed(0, 0, 0)
+      playerControlled(0)
 {
     pos = position;
     setModelDaten(model);
     setModelTextur(texture);
-    lastDirection = World::INSTANCE->zKamera()->getDirection();
     currentFrame.duration = 0;
     rend = 1;
-    lastFlags = MOVEMENT_FLAG_FLY;
     setSize(size);
 }
 
@@ -45,37 +34,18 @@ void Entity::api(char* message)
     case 0:
         { // add movement frame
             MovementFrame frame;
-            frame.direction.x = *(float*)(message += 1);
-            frame.direction.y = *(float*)(message += 4);
-            frame.direction.z = *(float*)(message += 4);
-            frame.targetPosition.x = *(float*)(message += 4);
-            frame.targetPosition.y = *(float*)(message += 4);
-            frame.targetPosition.z = *(float*)(message += 4);
-            frame.movementFlags = *(int*)(message += 4);
-            frame.duration = *(double*)(message += 4);
-            Vec2<float> norm = {0, -1};
-            this->setDrehungZ((frame.direction.x < 0 ? -1 : 1)
-                              * norm.angle(Vec2<float>(
-                                  frame.direction.x, frame.direction.y)));
-            if (!playerControlled)
-            {
-                cs.lock();
-                movements.add(frame);
-                cs.unlock();
-            }
-            break;
-        }
-    case 1:
-        { // position correction
-            if (playerControlled)
-            {
-                timeSinceSync = 0;
-                pos.x = *(float*)(message += 1);
-                pos.y = *(float*)(message += 4);
-                pos.z = *(float*)(message += 4);
-                lastDirection = World::INSTANCE->zKamera()->getDirection();
-                lastFlags = 0;
-            }
+            frame.position.x = *(float*)(message += 1);
+            frame.position.y = *(float*)(message += 4);
+            frame.position.z = *(float*)(message += 4);
+            frame.rotation = *(float*)(message += 4);
+            frame.duration = *(float*)(message += 4);
+            cs.lock();
+            frames.add(frame);
+            if (frames.getEintragAnzahl() > 10)
+            {
+                frames.remove(0);
+            }
+            cs.unlock();
             break;
         }
     }
@@ -83,462 +53,47 @@ void Entity::api(char* message)
 
 bool Entity::tick(double time)
 {
-    if (!World::INSTANCE || !World::INSTANCE->zKamera()) return 0;
-    if (playerControlled && GetForegroundWindow() == window->getFensterHandle())
+    double totalTime = time;
+    cs.lock();
+    while (totalTime > 0)
     {
-        bool chunkLoaded = 1;
-        if (!World::INSTANCE->zChunk(
-                World::INSTANCE->getChunkCenter((int)pos.x, (int)pos.y)))
-        {
-            chunkLoaded = 0;
-        }
-        Vec3<float> direction = World::INSTANCE->zKamera()->getDirection();
-        Vec3<float> lastPos = pos;
-        int flags = 0;
-        if ((lastFlags | MOVEMENT_FLAG_JUMP) != lastFlags
-            && (speed.z == 0.f || (lastFlags | MOVEMENT_FLAG_FLY) == lastFlags))
-        { // not jumping and not falling
-            speed = {0, 0, speed.z};
-            if (GetKeyState('w') & 0x8000 || GetKeyState('W') & 0x8000)
-            {
-                flags |= MOVEMENT_FLAG_FORWARD;
-                speed += {direction.x, direction.y, 0};
-            }
-            if (GetKeyState('a') & 0x8000 || GetKeyState('A') & 0x8000)
-            {
-                flags |= MOVEMENT_FLAG_LEFT;
-                Vec2<float> norm = {direction.x, direction.y};
-                norm.CCW90().normalize();
-                speed += {norm.x, norm.y, 0};
-            }
-            if (GetKeyState('s') & 0x8000 || GetKeyState('S') & 0x8000)
-            {
-                flags |= MOVEMENT_FLAG_BACKWARD;
-                speed += {-direction.x, -direction.y, 0};
-            }
-            if (GetKeyState('d') & 0x8000 || GetKeyState('D') & 0x8000)
-            {
-                flags |= MOVEMENT_FLAG_RIGHT;
-                Vec2<float> norm = {direction.x, direction.y};
-                norm.CW90().normalize();
-                speed += {norm.x, norm.y, 0};
-            }
-        }
-        else
+        if (currentFrame.duration <= 0)
         {
-            speed = {speed.x, speed.y, speed.z};
-        }
-        if ((lastFlags | MOVEMENT_FLAG_FLY) == lastFlags)
-        { // fly mode
-            flags |= MOVEMENT_FLAG_FLY;
-            if (GetKeyState(T_Shift) & 0x8000)
+            if (frames.getEintragAnzahl() > 0)
             {
-                if (getTastenStand(T_Strg))
-                { // end fly
-                    flags &= ~MOVEMENT_FLAG_FLY;
-                    speed.z = 0;
-                }
-                else
-                {
-                    flags |= MOVEMENT_FLAG_DOWN;
-                    speed.z = -maxMovementSpeed;
-                }
-            }
-            else if (GetKeyState(T_Space) & 0x8000)
-            {
-                flags |= MOVEMENT_FLAG_UP;
-                speed.z = maxMovementSpeed;
+                currentFrame = frames.get(0);
+                frames.remove(0);
             }
             else
             {
-                speed.z = 0;
-            }
-        }
-        else
-        { // walk mode
-            if (GetKeyState(T_Space) & 0x8000)
-            {
-                if (getTastenStand(T_Strg))
-                { // begin fly
-                    flags |= MOVEMENT_FLAG_FLY;
-                    speed.z = 0;
-                }
-                else if ((flags | MOVEMENT_FLAG_JUMP) != lastFlags
-                         && speed.z == 0.f)
-                { // begin jump
-                    flags |= MOVEMENT_FLAG_JUMP;
-                    speed.z = jumpSpeed;
-                }
-            }
-            if ((flags | MOVEMENT_FLAG_JUMP) == lastFlags
-                && (flags | MOVEMENT_FLAG_FLY) != flags)
-            {
-                flags |= MOVEMENT_FLAG_JUMP; // keep jumping
+                break;
             }
         }
-        Vec2<float> norm = {speed.x, speed.y};
-        if (norm.getLengthSq() != 0)
+        float t = min(currentFrame.duration, (float)totalTime);
+        pos += (currentFrame.position - pos) * (t / currentFrame.duration);
+        if (getZDrehung() - currentFrame.rotation > (float)PI)
         {
-            norm.normalize();
-            speed.x = norm.x * maxMovementSpeed;
-            speed.y = norm.y * maxMovementSpeed;
+            setDrehungZ(getZDrehung() - 2.f * (float)PI);
         }
-        if ((flags | MOVEMENT_FLAG_FLY) != flags)
+        else if (currentFrame.rotation - getZDrehung() > (float)PI)
         {
-            if (chunkLoaded)
-            {
-                speed.z -= World::INSTANCE->zDimension()->getGravity()
-                         * gravityMultiplier * (float)time;
-            }
-        }
-        // collision checking
-        Vec3<float> minP = model->getMinPos();
-        Vec3<float> maxP = model->getMaxPos();
-        Vec3<float> worldBoundingBox[8];
-        worldBoundingBox[0] = applyWorldTransformation(minP);
-        worldBoundingBox[1]
-            = applyWorldTransformation({minP.x, minP.y, maxP.z});
-        worldBoundingBox[2]
-            = applyWorldTransformation({minP.x, maxP.y, minP.z});
-        worldBoundingBox[3]
-            = applyWorldTransformation({maxP.x, minP.y, minP.z});
-        worldBoundingBox[4]
-            = applyWorldTransformation({maxP.x, minP.y, maxP.z});
-        worldBoundingBox[5]
-            = applyWorldTransformation({maxP.x, maxP.y, minP.z});
-        worldBoundingBox[6]
-            = applyWorldTransformation({minP.x, maxP.y, maxP.z});
-        worldBoundingBox[7] = applyWorldTransformation(maxP);
-        Vec3<float> worldBoundingBoxFloor[8];
-        for (int i = 0; i < 8; i++)
-        {
-            worldBoundingBoxFloor[i] = Vec3<float>(floor(worldBoundingBox[i].x),
-                floor(worldBoundingBox[i].y),
-                floor(worldBoundingBox[i].z));
+            setDrehungZ(getZDrehung() + 2.f * (float)PI);
         }
-        Vec3<float> frameSpeed = speed * (float)time;
-        bool hasCollided = 0;
-        for (int m = 0; m < 20; m++)
+        setDrehungZ(getZDrehung()
+                    + (currentFrame.rotation - getZDrehung())
+                          * (t / currentFrame.duration));
+        currentFrame.duration -= t;
+        totalTime -= t;
+        if (currentFrame.duration <= 0)
         {
-            float tf = 1.f;
-            int collType = 0;
-            int updateType = 0;
-            int updateI = 0;
-            if (frameSpeed.x > 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.x) >= abs(worldBoundingBoxFloor[i].x
-                                                 + 1.f - worldBoundingBox[i].x))
-                    {
-                        float xt = (worldBoundingBoxFloor[i].x + 1.f
-                                       - worldBoundingBox[i].x)
-                                 / frameSpeed.x;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
-                        if (tmp.y >= worldBoundingBoxFloor[i].y
-                            && tmp.y < worldBoundingBoxFloor[i].y + 1.f
-                            && tmp.z >= worldBoundingBoxFloor[i].z
-                            && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x + 1,
-                                    (int)worldBoundingBoxFloor[i].y,
-                                    (int)worldBoundingBoxFloor[i].z});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (xt < tf)
-                                {
-                                    tf = xt;
-                                    collType = 1;
-                                    updateType = 0;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (xt < tf)
-                                {
-                                    tf = xt;
-                                    collType = 0;
-                                    updateType = 1;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (frameSpeed.x < 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.x) >= abs(
-                            worldBoundingBoxFloor[i].x - worldBoundingBox[i].x))
-                    {
-                        float xt = (worldBoundingBoxFloor[i].x
-                                       - worldBoundingBox[i].x)
-                                 / frameSpeed.x;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
-                        if (tmp.y >= worldBoundingBoxFloor[i].y
-                            && tmp.y < worldBoundingBoxFloor[i].y + 1.f
-                            && tmp.z >= worldBoundingBoxFloor[i].z
-                            && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x - 1,
-                                    (int)worldBoundingBoxFloor[i].y,
-                                    (int)worldBoundingBoxFloor[i].z});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (xt < tf)
-                                {
-                                    tf = xt;
-                                    collType = 1;
-                                    updateType = 0;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (xt < tf)
-                                {
-                                    tf = xt;
-                                    collType = 0;
-                                    updateType = 1;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (frameSpeed.y > 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.y) >= abs(worldBoundingBoxFloor[i].y
-                                                 + 1.f - worldBoundingBox[i].y))
-                    {
-                        float yt = (worldBoundingBoxFloor[i].y + 1.f
-                                       - worldBoundingBox[i].y)
-                                 / frameSpeed.y;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
-                        if (tmp.x >= worldBoundingBoxFloor[i].x
-                            && tmp.x < worldBoundingBoxFloor[i].x + 1.f
-                            && tmp.z >= worldBoundingBoxFloor[i].z
-                            && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x,
-                                    (int)worldBoundingBoxFloor[i].y + 1,
-                                    (int)worldBoundingBoxFloor[i].z});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (yt < tf)
-                                {
-                                    tf = yt;
-                                    collType = 2;
-                                    updateType = 0;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (yt < tf)
-                                {
-                                    tf = yt;
-                                    collType = 0;
-                                    updateType = 2;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (frameSpeed.y < 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.y) >= abs(
-                            worldBoundingBoxFloor[i].y - worldBoundingBox[i].y))
-                    {
-                        float yt = (worldBoundingBoxFloor[i].y
-                                       - worldBoundingBox[i].y)
-                                 / frameSpeed.y;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
-                        if (tmp.x >= worldBoundingBoxFloor[i].x
-                            && tmp.x < worldBoundingBoxFloor[i].x + 1.f
-                            && tmp.z >= worldBoundingBoxFloor[i].z
-                            && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x,
-                                    (int)worldBoundingBoxFloor[i].y - 1,
-                                    (int)worldBoundingBoxFloor[i].z});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (yt < tf)
-                                {
-                                    tf = yt;
-                                    collType = 2;
-                                    updateType = 0;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (yt < tf)
-                                {
-                                    tf = yt;
-                                    collType = 0;
-                                    updateType = 2;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (frameSpeed.z > 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.z) >= abs(worldBoundingBoxFloor[i].z
-                                                 + 1.f - worldBoundingBox[i].z))
-                    {
-                        float zt = (worldBoundingBoxFloor[i].z + 1.f
-                                       - worldBoundingBox[i].z)
-                                 / frameSpeed.z;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
-                        if (zt <= 1.f && tmp.x >= worldBoundingBoxFloor[i].x
-                            && tmp.x < worldBoundingBoxFloor[i].x + 1.f
-                            && tmp.y >= worldBoundingBoxFloor[i].y
-                            && tmp.y < worldBoundingBoxFloor[i].y + 1.f)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x,
-                                    (int)worldBoundingBoxFloor[i].y,
-                                    (int)worldBoundingBoxFloor[i].z + 1});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (zt < tf)
-                                {
-                                    tf = zt;
-                                    collType = 3;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (zt < tf)
-                                {
-                                    tf = zt;
-                                    collType = 0;
-                                    updateType = 3;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (frameSpeed.z < 0)
-            {
-                for (int i = 0; i < 8; i++)
-                {
-                    if (abs(frameSpeed.z) >= abs(
-                            worldBoundingBoxFloor[i].z - worldBoundingBox[i].z))
-                    {
-                        float zt = (worldBoundingBoxFloor[i].z
-                                       - worldBoundingBox[i].z)
-                                 / frameSpeed.z;
-                        Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
-                        if (tmp.x >= worldBoundingBoxFloor[i].x
-                            && tmp.x < worldBoundingBoxFloor[i].x + 1.f
-                            && tmp.y >= worldBoundingBoxFloor[i].y
-                            && tmp.y < worldBoundingBoxFloor[i].y + 1)
-                        {
-                            Block* b = World::INSTANCE->zBlockAt(
-                                Vec3<int>{(int)worldBoundingBoxFloor[i].x,
-                                    (int)worldBoundingBoxFloor[i].y,
-                                    (int)worldBoundingBoxFloor[i].z - 1});
-                            if (b) // TODO: ignore passable blocks
-                            {
-                                if (zt < tf)
-                                {
-                                    tf = zt;
-                                    collType = 3;
-                                    updateType = 0;
-                                }
-                                hasCollided = 1;
-                            }
-                            else
-                            {
-                                if (zt < tf)
-                                {
-                                    tf = zt;
-                                    collType = 0;
-                                    updateType = 3;
-                                    updateI = i;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            if (collType == 1)
-                frameSpeed.x = tf > 0.1f ? frameSpeed.x * (tf - 0.1f) : 0.f;
-            if (collType == 2)
-                frameSpeed.y = tf > 0.1f ? frameSpeed.y * (tf - 0.1f) : 0.f;
-            if (collType == 3)
-            {
-                frameSpeed.z = tf > 0.1f ? frameSpeed.z * (tf - 0.1f) : 0.f;
-                if (speed.z < 0)
-                {
-                    flags &= ~MOVEMENT_FLAG_JUMP;
-                    if (-speed.z > 2)
-                    {
-                        char message[5];
-                        message[0] = 10;
-                        *(float*)(message + 1) = -speed.z;
-                        World::INSTANCE->zClient()->sendPlayerAction(
-                            message, 5);
-                    }
-                }
-                speed.z = 0;
-            }
-            if (updateType == 1)
-            {
-                if ((int)worldBoundingBoxFloor[updateI].x
-                    <= (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
-                    worldBoundingBoxFloor[updateI].x++;
-                if ((int)worldBoundingBoxFloor[updateI].x
-                    > (int)floor(worldBoundingBox[updateI].x + frameSpeed.x))
-                    worldBoundingBoxFloor[updateI].x--;
-            }
-            if (updateType == 2)
-            {
-                if ((int)worldBoundingBoxFloor[updateI].y
-                    <= (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
-                    worldBoundingBoxFloor[updateI].y++;
-                if ((int)worldBoundingBoxFloor[updateI].y
-                    > (int)floor(worldBoundingBox[updateI].y + frameSpeed.y))
-                    worldBoundingBoxFloor[updateI].y--;
-            }
-            if (updateType == 3)
-            {
-                if ((int)worldBoundingBoxFloor[updateI].z
-                    <= (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
-                    worldBoundingBoxFloor[updateI].z++;
-                if ((int)worldBoundingBoxFloor[updateI].z
-                    > (int)floor(worldBoundingBox[updateI].z + frameSpeed.z))
-                    worldBoundingBoxFloor[updateI].z--;
-            }
-            if (updateType || collType) continue;
-            break;
+            pos = currentFrame.position;
+            setDrehungZ(currentFrame.rotation);
         }
-        pos += frameSpeed;
+        rend = 1;
+    }
+    cs.unlock();
+    if (playerControlled)
+    {
         World::INSTANCE->zKamera()->setPosition(
             pos + Vec3<float>(0.f, 0.f, 1.5f));
         Model3D* target = World::INSTANCE->getCurrentTarget();
@@ -547,55 +102,6 @@ bool Entity::tick(double time)
             ->updatePosition(
                 pos, b != 0, b ? b->getLocation() : Vec3<int>(0, 0, 0));
         if (target) target->release();
-        if (flags != lastFlags || direction != lastDirection
-            || timeSinceSync >= 1 || hasCollided)
-        {
-            if (timeSinceSync > 0)
-            {
-                MovementFrame frame;
-                frame.direction = lastDirection;
-                frame.targetPosition = lastPos;
-                frame.movementFlags = lastFlags;
-                frame.duration = timeSinceSync;
-                World::INSTANCE->zClient()->sendPlayerMovement(frame);
-            }
-            lastFlags = flags;
-            lastDirection = direction;
-            timeSinceSync = 0;
-        }
-        timeSinceSync += time;
-        rend = 1;
-    }
-    else
-    {
-        double totalTime = time;
-        while (totalTime > 0)
-        {
-            if (currentFrame.duration <= 0)
-            {
-                if (movements.getEintragAnzahl() > 0)
-                {
-                    currentFrame = movements.get(0);
-                    cs.lock();
-                    movements.remove(0);
-                    cs.unlock();
-                }
-                else
-                {
-                    break;
-                }
-            }
-            double t = min(currentFrame.duration, totalTime);
-            pos += (currentFrame.targetPosition - pos)
-                 * (float)(t / currentFrame.duration);
-            currentFrame.duration -= t;
-            totalTime -= t;
-            if (currentFrame.duration <= 0)
-            {
-                pos = currentFrame.targetPosition;
-            }
-            rend = 1;
-        }
     }
     return Model3D::tick(time);
 }

+ 5 - 29
FactoryCraft/Entity.h

@@ -12,23 +12,9 @@ class Block;
 
 struct MovementFrame
 {
-    Framework::Vec3<float> direction;
-    Framework::Vec3<float> targetPosition;
-    int movementFlags = 0;
-    double duration = 0;
-};
-
-enum MovementFlag
-{
-    MOVEMENT_FLAG_NONE = 0,
-    MOVEMENT_FLAG_FORWARD = 0x1,
-    MOVEMENT_FLAG_LEFT = 0x2,
-    MOVEMENT_FLAG_BACKWARD = 0x4,
-    MOVEMENT_FLAG_RIGHT = 0x8,
-    MOVEMENT_FLAG_DOWN = 0x10,
-    MOVEMENT_FLAG_UP = 0x20,
-    MOVEMENT_FLAG_JUMP = 0x40,
-    MOVEMENT_FLAG_FLY = 0x80,
+    Framework::Vec3<float> position;
+    float rotation;
+    float duration;
 };
 
 class Entity : public FactoryCraftModel
@@ -36,17 +22,10 @@ class Entity : public FactoryCraftModel
 private:
     int id;
     const EntityType* zType;
-    Framework::Critical cs;
     bool playerControlled;
-    float maxMovementSpeed;
-    int lastFlags;
-    double timeSinceSync;
-    float gravityMultiplier;
-    float jumpSpeed;
-    Framework::Vec3<float> lastDirection;
-    Framework::Array<MovementFrame> movements;
-    Framework::Vec3<float> speed;
+    Framework::Critical cs;
     MovementFrame currentFrame;
+    Framework::Array<MovementFrame> frames;
 
 public:
     Entity(const EntityType* zType,
@@ -54,9 +33,6 @@ public:
         Framework::Model3DTextur* texture,
         int id,
         Framework::Vec3<float> position,
-        float maxMovementSpeed,
-        float gravityMultiplier,
-        float jumpSpeed,
         float size);
     ~Entity();
 

+ 0 - 12
FactoryCraft/EntityType.cpp

@@ -16,12 +16,6 @@ Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
     zReader->lese((char*)&position.x, 4);
     zReader->lese((char*)&position.y, 4);
     zReader->lese((char*)&position.z, 4);
-    float maxSpeed;
-    zReader->lese((char*)&maxSpeed, 4);
-    float gravityMultiplier;
-    zReader->lese((char*)&gravityMultiplier, 4);
-    float jumpSpeed;
-    zReader->lese((char*)&jumpSpeed, 4);
     bool specialModel = 0;
     zReader->lese((char*)&specialModel, 1);
     Entity* e;
@@ -33,9 +27,6 @@ Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
             model.getTexture(),
             id,
             position,
-            maxSpeed,
-            gravityMultiplier,
-            jumpSpeed,
             model.getSize());
     }
     else
@@ -45,9 +36,6 @@ Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
             model.getTexture(),
             id,
             position,
-            maxSpeed,
-            gravityMultiplier,
-            jumpSpeed,
             model.getSize());
     }
     if (World::INSTANCE->zKamera()->getEntityId() == id)

+ 20 - 11
FactoryCraft/FactoryClient.cpp

@@ -960,23 +960,32 @@ void FactoryClient::sendPlayerAction(const char* data, unsigned short length)
     cs.unlock();
 }
 
-void FactoryClient::sendPlayerMovement(MovementFrame& frame)
+void FactoryClient::sendPlayerFaceDirection(Vec3<float> dir)
 {
     if (!foreground) return;
     cs.lock();
-    short length = 38;
+    short length = 14;
     foreground->sende((char*)&length, 2);
     char msgId = 2; // player message
     foreground->sende(&msgId, 1);
-    foreground->sende(&msgId, 1); // set movement
-    foreground->sende((char*)&frame.direction.x, 4);
-    foreground->sende((char*)&frame.direction.y, 4);
-    foreground->sende((char*)&frame.direction.z, 4);
-    foreground->sende((char*)&frame.targetPosition.x, 4);
-    foreground->sende((char*)&frame.targetPosition.y, 4);
-    foreground->sende((char*)&frame.targetPosition.z, 4);
-    foreground->sende((char*)&frame.movementFlags, 4);
-    foreground->sende((char*)&frame.duration, 8);
+    foreground->sende(&msgId, 1); // set face direction
+    foreground->sende((char*)&dir.x, 4);
+    foreground->sende((char*)&dir.y, 4);
+    foreground->sende((char*)&dir.z, 4);
+    cs.unlock();
+}
+
+void FactoryClient::sendPlayerMovement(int flags)
+{
+    if (!foreground) return;
+    cs.lock();
+    short length = 6;
+    foreground->sende((char*)&length, 2);
+    char msgId = 2; // player message
+    foreground->sende(&msgId, 1);
+    msgId = 10; // set movement
+    foreground->sende(&msgId, 1);
+    foreground->sende((char*)&flags, 4);
     cs.unlock();
 }
 

+ 2 - 1
FactoryCraft/FactoryClient.h

@@ -40,7 +40,8 @@ public:
     Network::NetworkReader* getNextBackgroundMessage();
     void endMessageReading(bool bg);
     void sendPlayerAction(const char* data, unsigned short length);
-    void sendPlayerMovement(MovementFrame& frame);
+    void sendPlayerFaceDirection(Vec3<float> dir);
+    void sendPlayerMovement(int flags);
     void entityAPIRequest(
         int entityId, const char* message, unsigned short length);
     void blockAPIRequest(

+ 1 - 1
FactoryCraft/Load.cpp

@@ -96,7 +96,7 @@ void LoadMenu::load(FactoryClient* client,
         "Load Menu", [this, client, name, secret, port, onFinish]() {
             Text tmp = secret;
             int result = client->join(name, tmp, port);
-            onFinish(result, secret);
+            onFinish(result, tmp);
         });
 }
 

+ 119 - 0
FactoryCraft/PlayerKam.cpp

@@ -5,6 +5,22 @@
 #include "Game.h"
 #include "Globals.h"
 
+class MovementFlags
+{
+public:
+    static const int SNEAKING = 0x00001;
+    static const int SPRINTING = 0x00002;
+    static const int FLYING = 0x00004;
+    static const int JUMPING = 0x00008;
+    static const int WALK_FORWARD = 0x00010;
+    static const int WALK_BACKWARD = 0x00020;
+    static const int WALK_LEFT = 0x00040;
+    static const int WALK_RIGHT = 0x00080;
+    static const int ROTATE_LEFT = 0x00100;
+    static const int ROTATE_RIGHT = 0x00200;
+    static const int GROUND_CONTACT = 0x01000;
+};
+
 PlayerKam::PlayerKam(Framework::Bildschirm3D* zScreen)
     : Kam3D()
 {
@@ -14,7 +30,10 @@ PlayerKam::PlayerKam(Framework::Bildschirm3D* zScreen)
     setStyle(
         Kam3D::Style::Tick | Kam3D::Style::Movable | Kam3D::Style::Rotatable);
     setRotation({(float)PI / 2.f, 0, 0});
+    lastDirection = {0, 0, 0};
     entityId = -1;
+    movementFlags = 0;
+    lastMovementFlags = 0;
 }
 
 void PlayerKam::setDirection(Framework::Vec3<float> direction)
@@ -28,6 +47,10 @@ void PlayerKam::setDirection(Framework::Vec3<float> direction)
 
 void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
 {
+    if (!World::INSTANCE)
+    {
+        return;
+    }
     if (te.id == TE_Press)
     {
         if (te.taste[0] >= '0' && te.taste[0] <= '9')
@@ -38,6 +61,37 @@ void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
             if (*(int*)(action + 1) < 0) *(int*)(action + 1) = 9;
             World::INSTANCE->zClient()->sendPlayerAction(action, 5);
         }
+        if (kameraControll)
+        {
+            if (te.virtualKey == 'W')
+            {
+                movementFlags |= MovementFlags::WALK_FORWARD;
+            }
+            if (te.virtualKey == 'S')
+            {
+                movementFlags |= MovementFlags::WALK_BACKWARD;
+            }
+            if (te.virtualKey == 'A')
+            {
+                movementFlags |= MovementFlags::WALK_LEFT;
+            }
+            if (te.virtualKey == 'D')
+            {
+                movementFlags |= MovementFlags::WALK_RIGHT;
+            }
+            if (te.virtualKey == VK_SPACE)
+            {
+                movementFlags |= MovementFlags::JUMPING;
+            }
+            if (te.virtualKey == T_Shift)
+            {
+                movementFlags |= MovementFlags::SPRINTING;
+            }
+            if (te.virtualKey == T_Strg)
+            {
+                movementFlags |= MovementFlags::SNEAKING;
+            }
+        }
     }
     if (te.id == TE_Release)
     {
@@ -45,6 +99,7 @@ void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
         {
             bool oldControl = kameraControll;
             kameraControll = 0;
+            movementFlags = 0;
             setShowCursor(true);
             if (!oldControl)
                 ((Game*)(Menu*)menuRegister->get("game"))->closeCurrentDialog();
@@ -63,15 +118,64 @@ void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
         {
             ((Game*)(Menu*)menuRegister->get("game"))->zMap()->setVisibility(1);
         }
+        if (te.virtualKey == 'W')
+        {
+            movementFlags &= ~MovementFlags::WALK_FORWARD;
+        }
+        if (te.virtualKey == 'S')
+        {
+            movementFlags &= ~MovementFlags::WALK_BACKWARD;
+        }
+        if (te.virtualKey == 'A')
+        {
+            movementFlags &= ~MovementFlags::WALK_LEFT;
+        }
+        if (te.virtualKey == 'D')
+        {
+            movementFlags &= ~MovementFlags::WALK_RIGHT;
+        }
+        if (te.virtualKey == VK_SPACE)
+        {
+            movementFlags &= ~MovementFlags::JUMPING;
+        }
+        if (te.virtualKey == T_Shift)
+        {
+            movementFlags &= ~MovementFlags::SPRINTING;
+        }
+        if (te.virtualKey == T_Strg)
+        {
+            movementFlags &= ~MovementFlags::SNEAKING;
+        }
+        if (te.taste[0] == 'F')
+        {
+            if (movementFlags & MovementFlags::FLYING)
+            {
+                movementFlags &= ~MovementFlags::FLYING;
+            }
+            else
+            {
+                movementFlags |= MovementFlags::FLYING;
+            }
+        }
+    }
+    if (lastMovementFlags != movementFlags)
+    {
+        World::INSTANCE->zClient()->sendPlayerMovement(movementFlags);
+        lastMovementFlags = movementFlags;
     }
 }
 
 void PlayerKam::doMausEreignis(Framework::MausEreignis& me)
 {
+    if (!World::INSTANCE)
+    {
+        return;
+    }
     if (me.verarbeitet && me.id != ME_RLinks && me.id != ME_RRechts)
     {
         kameraControll = 0;
         setShowCursor(true);
+        movementFlags = 0;
     }
     else
     {
@@ -107,10 +211,19 @@ void PlayerKam::doMausEreignis(Framework::MausEreignis& me)
         }
         me.verarbeitet = 1;
     }
+    if (lastMovementFlags != movementFlags)
+    {
+        World::INSTANCE->zClient()->sendPlayerMovement(movementFlags);
+        lastMovementFlags = movementFlags;
+    }
 }
 
 bool PlayerKam::tick(double time)
 {
+    if (!World::INSTANCE)
+    {
+        return 1;
+    }
     __int64 style = 0;
     if (hatStyle(Style::Movable)) style |= Style::Movable;
     if (hatStyle(Style::Rotatable)) style |= Style::Rotatable;
@@ -139,6 +252,12 @@ bool PlayerKam::tick(double time)
         setShowCursor(false);
         setMausPos(window->getPosition() + window->getGröße() / 2);
     }
+    Vec3<float> direction = getDirection();
+    if (direction != lastDirection)
+    {
+        World::INSTANCE->zClient()->sendPlayerFaceDirection(direction);
+        lastDirection = direction;
+    }
     return 1;
 }
 

+ 4 - 0
FactoryCraft/PlayerKam.h

@@ -2,6 +2,7 @@
 #include <Bildschirm.h>
 #include <Kam3D.h>
 #include <TastaturEreignis.h>
+#include <Vec3.h>
 #include <Zeit.h>
 
 class PlayerKam : public Framework::Kam3D
@@ -9,6 +10,9 @@ class PlayerKam : public Framework::Kam3D
 private:
     bool kameraControll;
     int entityId;
+    Framework::Vec3<float> lastDirection;
+    int movementFlags;
+    int lastMovementFlags;
 
 public:
     PlayerKam(Framework::Bildschirm3D* zScreen);

+ 3 - 1
FactoryCraft/World.cpp

@@ -20,6 +20,7 @@ World::World(Bildschirm3D* zScreen, FactoryClient* client)
     : Thread(),
       client(client)
 {
+    zScreen->lock();
     renderedWorld = new Welt3D();
     renderedWorld->addDiffuseLight(DiffuseLight{
         Vec3<float>(0.5f, 0.5f, -1.f), Vec3<float>(1.f, 1.f, 1.f)});
@@ -57,11 +58,12 @@ World::World(Bildschirm3D* zScreen, FactoryClient* client)
     {
         selectionModel->zTextur()->setPolygonTextur(i,
             zScreen->zGraphicsApi()->createOrGetTextur(
-                "blocks.ltdb/selectedblock.p"));
+                "data/textures/blocks.ltdb/selectedblock.p"));
     }
     selectionModel->setAlpha(1);
     selectionModel->setUseEffectAlpha(1);
     renderedWorld->addZeichnung(selectionModel);
+    zScreen->unlock();
     start();
 }