158 lines
3.4 KiB
C++
158 lines
3.4 KiB
C++
#include "object.h"
|
|
#include "obj_group.h"
|
|
#include "util/save_file.h"
|
|
#include "empire.h"
|
|
#include "physics/physics_world.h"
|
|
#include "main/references.h"
|
|
#include "main/logging.h"
|
|
#include "network/message.h"
|
|
#include "lock.h"
|
|
|
|
//TODO: Handle save files with different script type definitions
|
|
|
|
void Object::save(SaveFile& file) {
|
|
file << id;
|
|
|
|
file << name;
|
|
file << (flags & objFlagSaveMask);
|
|
|
|
file << alwaysVisible << sightRange << visibleMask << sightedMask;
|
|
file << position << velocity << acceleration << rotation;
|
|
file << radius;
|
|
file << seeableRange;
|
|
|
|
file << lockHint;
|
|
|
|
file << (group ? group->id : int(0));
|
|
file << (owner ? owner->id : INVALID_EMPIRE);
|
|
|
|
if(!isValid())
|
|
return;
|
|
|
|
auto* func = type->functions[SOC_save];
|
|
if(func) {
|
|
SaveMessage msg(file);
|
|
|
|
scripts::Call cl = devices.scripts.server->call(func);
|
|
cl.setObject(script);
|
|
cl.push((void*)this);
|
|
cl.push((void*)&msg);
|
|
if(cl.call()) {
|
|
char* pData; net::msize_t size;
|
|
msg.getAsPacket(pData, size);
|
|
|
|
file << size;
|
|
file.write(pData, size);
|
|
}
|
|
else {
|
|
file << (net::msize_t)0;
|
|
}
|
|
}
|
|
else {
|
|
file << (net::msize_t)0;
|
|
}
|
|
}
|
|
|
|
void Object::load(SaveFile& file) {
|
|
if(!getFlag(objUninitialized))
|
|
throw SaveFileError("Object already initialized");
|
|
|
|
file >> name;
|
|
file >> flags;
|
|
|
|
file >> alwaysVisible >> sightRange >> visibleMask >> sightedMask;
|
|
file >> position >> velocity >> acceleration >> rotation;
|
|
file >> radius;
|
|
if(file < SFV_0001) {
|
|
double dummy;
|
|
file >> dummy;
|
|
}
|
|
if(file >= SFV_0017)
|
|
file >> seeableRange;
|
|
|
|
if(file >= SFV_0009) {
|
|
file >> lockHint;
|
|
if(lockHint > 0)
|
|
lockGroup = getLock(lockHint % getLockCount());
|
|
}
|
|
|
|
int groupID = file;
|
|
if(groupID != 0 && isValid()) {
|
|
group = ObjectGroup::byID(groupID);
|
|
if(group) {
|
|
for(unsigned i = 0; i < group->getObjectCount(); ++i) {
|
|
if(group->getObject(i) == this) {
|
|
physItem = group->getPhysicsItem(i);
|
|
physItem->bound = AABBoxd::fromCircle(position, radius);
|
|
physItem->gridLocation = 0;
|
|
physItem->type = PIT_Object;
|
|
physItem->object = this;
|
|
break;
|
|
}
|
|
}
|
|
if(!physItem) {
|
|
error("%s (#%d) missing in group", name.c_str(), id);
|
|
group->drop();
|
|
group = nullptr;
|
|
}
|
|
}
|
|
else {
|
|
error("%s (#%d) missing group", name.c_str(), id);
|
|
}
|
|
}
|
|
|
|
owner = Empire::getEmpireByID(file);
|
|
|
|
if(!isValid())
|
|
return;
|
|
|
|
if(!physItem && !getFlag(objNoPhysics))
|
|
physItem = devices.physics->registerItem(AABBoxd::fromCircle(position, radius), this);
|
|
|
|
void* mixinMem = this + 1;
|
|
type->states->prepare(mixinMem);
|
|
|
|
script = type->create();
|
|
|
|
auto* loadFunc = type->functions[SOC_load];
|
|
SaveMessage scriptTypeData(file);
|
|
|
|
net::msize_t size = file;
|
|
if(size > 0) {
|
|
char* buffer = (char*)malloc(size);
|
|
file.read(buffer, size);
|
|
scriptTypeData.setPacket(buffer, size);
|
|
free(buffer);
|
|
}
|
|
|
|
//Either load the saved message, or default initialize
|
|
if(loadFunc) {
|
|
scripts::Call cl = devices.scripts.server->call(loadFunc);
|
|
cl.setObject(script);
|
|
cl.push((void*)this);
|
|
cl.push((void*)&scriptTypeData);
|
|
cl.call();
|
|
}
|
|
else {
|
|
scripts::Call cl = devices.scripts.server->call(type->functions[SOC_init]);
|
|
if(cl.valid()) {
|
|
cl.setObject(script);
|
|
cl.push((void*)this);
|
|
cl.call();
|
|
}
|
|
}
|
|
|
|
lockGroup->add(this);
|
|
setFlag(objUninitialized, false);
|
|
}
|
|
|
|
void Object::postLoad() {
|
|
auto* func = type->functions[SOC_postLoad];
|
|
if(func && script) {
|
|
scripts::Call cl = devices.scripts.server->call(func);
|
|
cl.setObject(script);
|
|
cl.push((void*)this);
|
|
cl.call();
|
|
}
|
|
}
|