-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathobject.cpp
112 lines (92 loc) · 3.31 KB
/
object.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
SA:MP Multiplayer Modification
Copyright 2004-2005 SA:MP Team
Version: $Id: vehicle.cpp,v 1.5 2006/05/07 15:35:32 kyeman Exp $
*/
#include "main.h"
//----------------------------------------------------------
// Global
CObject::CObject(int iModel, VECTOR * vecPos, VECTOR * vecRot)
{
// Set the initial pos
memset(&m_matWorld,0,sizeof(MATRIX4X4));
m_matWorld.pos.X = vecPos->X;
m_matWorld.pos.Y = vecPos->Y;
m_matWorld.pos.Z = vecPos->Z;
m_matWorld.up.X = vecRot->X;
m_matWorld.up.Y = vecRot->Y;
m_matWorld.up.Z = vecRot->Z;
m_byteMoving = 0;
m_iModel = iModel;
m_bIsActive = true;
}
//----------------------------------------------------
// This is the method used for spawning players that
// already exist in the world when the client connects.
void CObject::SpawnForPlayer(BYTE byteForPlayerID)
{
RakNet::BitStream bsObjectSpawn;
bsObjectSpawn.Write(m_byteObjectID);
bsObjectSpawn.Write(m_iModel);
bsObjectSpawn.Write(m_matWorld.pos.X);
bsObjectSpawn.Write(m_matWorld.pos.Y);
bsObjectSpawn.Write(m_matWorld.pos.Z);
bsObjectSpawn.Write(m_matWorld.up.X);
bsObjectSpawn.Write(m_matWorld.up.Y);
bsObjectSpawn.Write(m_matWorld.up.Z);
//printf("player: %d, id: %d, model: %d, others: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n", byteForPlayerID, m_byteObjectID, m_iModel, m_matWorld.pos.X, m_matWorld.pos.Y, m_matWorld.pos.Z, m_matWorld.up.X, m_matWorld.up.Y, m_matWorld.up.Z);
pNetGame->GetRakServer()->RPC(RPC_ScrCreateObject,&bsObjectSpawn,HIGH_PRIORITY,RELIABLE_ORDERED,
0,pNetGame->GetRakServer()->GetPlayerIDFromIndex(byteForPlayerID),false,false);
}
int CObject::Process(float fElapsedTime)
{
int ret = 0;
if (m_byteMoving & 1)
{
// Calculate new position based on elapsed time (interpolate)
// distance = speed * time
// time = fElapsedTime
// speed = m_fMoveSpeed
float distance = fElapsedTime * m_fMoveSpeed;
float remaining = DistanceRemaining();
if (distance >= remaining)
{
ret |= 1; // The object will reach it's destination
m_byteMoving &= ~1; // Stop it moving
m_matWorld.pos.X = m_matTarget.pos.X;
m_matWorld.pos.Y = m_matTarget.pos.Y;
m_matWorld.pos.Z = m_matTarget.pos.Z;
// Force the final location so we don't overshoot slightly
}
else
{
// Else interpolate the new position between the current and final positions
remaining /= distance; // Calculate ratio
m_matWorld.pos.X += (m_matTarget.pos.X - m_matWorld.pos.X) / remaining;
m_matWorld.pos.Y += (m_matTarget.pos.Y - m_matWorld.pos.Y) / remaining;
m_matWorld.pos.Z += (m_matTarget.pos.Z - m_matWorld.pos.Z) / remaining;
}
}
return ret;
}
float CObject::DistanceRemaining()
{
float fSX,fSY,fSZ;
fSX = (m_matWorld.pos.X - m_matTarget.pos.X) * (m_matWorld.pos.X - m_matTarget.pos.X);
fSY = (m_matWorld.pos.Y - m_matTarget.pos.Y) * (m_matWorld.pos.Y - m_matTarget.pos.Y);
fSZ = (m_matWorld.pos.Z - m_matTarget.pos.Z) * (m_matWorld.pos.Z - m_matTarget.pos.Z);
return (float)sqrt(fSX + fSY + fSZ);
}
float CObject::MoveTo(float X, float Y, float Z, float speed)
{
m_matTarget.pos.X = X;
m_matTarget.pos.Y = Y;
m_matTarget.pos.Z = Z;
m_fMoveSpeed = speed;
m_byteMoving |= 1;
float fSX,fSY,fSZ;
fSX = (X - m_matWorld.pos.X) * (X - m_matWorld.pos.X);
fSY = (Y - m_matWorld.pos.Y) * (Y - m_matWorld.pos.Y);
fSZ = (Z - m_matWorld.pos.Z) * (Z - m_matWorld.pos.Z);
return (float)(sqrt(fSX + fSY + fSZ) / speed);
}