#include "Monster.h"
#include "ReplicaMember.h"
#include "BitStream.h"
#include "StringTable.h"
#include "ReplicaManager.h"
#include <stdio.h>
extern bool isServer;
extern ReplicaManager replicaManager;
extern Monster *monster;
Monster::Monster()
{
// Setup my object
position=1;
health=2;
replica = new ReplicaMember;
// Only necessary if using the replication system by containing a member variable
replica->SetParent(this);
// Objects are only processed by the system after you tell the manager to replicate them.
// Here I do it in the constructor, but in a real game you would probably do it after the object is done loading
// This does NOT call serialize automatically - it only sends a call to create the remote object.
if (isServer)
replicaManager.Construct(replica, false, UNASSIGNED_PLAYER_ID, true);
// Calling
// replicaManager.SetScope(replica, true, UNASSIGNED_PLAYER_ID)
// here would work for existing players, but not for future players.
// So we call it in SendConstruction instead, which is called once for all players.
if (isServer)
{
// For security, as a server disable all receives except REPLICA_RECEIVE_SERIALIZE
// I could do this manually by putting if (isServer) return; at the top of all my receive functions too.
replicaManager.DisableReplicaInterfaces(replica, REPLICA_RECEIVE_DESTRUCTION | REPLICA_RECEIVE_SCOPE_CHANGE);
}
else
{
// For convenience and for saving bandwidth, as a client disable all sends except REPLICA_SEND_SERIALIZE
// I could do this manually by putting if (isServer==false) return; at the top of all my send functions too.
replicaManager.DisableReplicaInterfaces(replica, REPLICA_SEND_CONSTRUCTION | REPLICA_SEND_DESTRUCTION | REPLICA_SEND_SCOPE_CHANGE);
}
}
Monster::~Monster()
{
printf("Inside ~Monster\n");
// Remove the object before it is destroyed, or you will crash the next time the ReplicaManager updates
replicaManager.Destruct(replica, UNASSIGNED_PLAYER_ID, true);
replicaManager.DereferencePointer(replica);
delete replica;
monster=0;
}
ReplicaReturnResult Monster::SendConstruction( RakNetTime currentTime, PlayerID playerId, RakNet::BitStream *outBitStream, bool *includeTimestamp )
{
// This string was pre-registered in main with stringTable->AddString so we can send it with the string table and save bandwidth
stringTable->EncodeString("Monster", 255, outBitStream);
// This means that this object starts in scope to this player. In a real game, you would only start in scope if an object
// were immediately visible to that player. This only really applies to the server in a client/server game, since clients wouldn't hide their
// own object updates from the server.
// We could have left this line out by calling ReplicaManager::SetDefaultScope(true); in main()
replicaManager.SetScope(replica, true, playerId, false);
printf("Sending monster to %i:%i\n", playerId.binaryAddress, playerId.port);
return REPLICA_PROCESSING_DONE;
}
void Monster::SendDestruction(RakNet::BitStream *outBitStream, PlayerID playerId)
{
}
ReplicaReturnResult Monster::ReceiveDestruction(RakNet::BitStream *inBitStream, PlayerID playerId)
{
delete monster;
return REPLICA_PROCESSING_DONE;
}
ReplicaReturnResult Monster::SendScopeChange(bool inScope, RakNet::BitStream *outBitStream, RakNetTime currentTime, PlayerID playerId)
{
if (inScope)
printf("Sending scope change to true in Monster\n");
else
printf("Sending scope change to false in Monster\n");
// Up to you to write this. If you write nothing, the system will treat that as if you wanted to cancel the scope change
outBitStream->Write(inScope);
return REPLICA_PROCESSING_DONE;
}
ReplicaReturnResult Monster::ReceiveScopeChange(RakNet::BitStream *inBitStream, PlayerID playerId)
{
bool inScope;
inBitStream->Read(inScope);
if (inScope)
printf("Received message that scope is now true in Monster\n");
else
printf("Received message that scope is now false in Monster\n");
return REPLICA_PROCESSING_DONE;
}
ReplicaReturnResult Monster::Serialize(bool *sendTimestamp, RakNet::BitStream *outBitStream, RakNetTime lastSendTime, PacketPriority *priority, PacketReliability *reliability, RakNetTime currentTime, PlayerID playerId)
{
if (lastSendTime==0)
printf("First call to Monster::Serialize for %i:%i\n", playerId.binaryAddress, playerId.port);
outBitStream->Write(position);
outBitStream->Write(health);
return REPLICA_PROCESSING_DONE;
}
ReplicaReturnResult Monster::Deserialize(RakNet::BitStream *inBitStream, RakNetTime timestamp, RakNetTime lastDeserializeTime, PlayerID playerId )
{
if (lastDeserializeTime==0)
printf("First call to Monster::Deserialize\n");
else
printf("Got Monster::Deserialize\n");
inBitStream->Read(position);
inBitStream->Read(health);
return REPLICA_PROCESSING_DONE;
}
bool Monster::IsNetworkIDAuthority(void) const
{
return isServer;
}
syntax highlighted by Code2HTML, v. 0.9.1