mirror of
https://github.com/worldforge/cyphesis
synced 2026-08-13 12:26:04 -04:00
* server/Player.cpp: Arg order of std::string.compare() is incompatable between recent libstdc++ versions. Switch back to old version, still in most common use. * rulesets/Thing.cpp: Set refno on ops handled in game. * rulesets/Python_API.cpp: Modify Entity() python constructor so that commonly used attributes from old atlas are translated to their modern equivalents. * rulesets/Py_Thing.cpp, rulesets/Py_Mind.cpp: Differentiate between previously identical error messages in several places. * rulesets/Py_Object.cpp: Rework conversion of python dict to Atlas map to be more efficient and clean. * rulesets/Py_Location.cpp: Rework setting of vector parts of location so that it can accept vectors from python in more formats, including lists and tuples. * rulesets/Creator.h, rulesets/Character.h, common/BaseEntity.h: Re-order virtual methods declarations to fit a convention. * common/stringstream.h: Hardcode use of local stringstream class, as the version provided with older libstdc++ seems to be broken. * common/database.cpp: Use the common header to pick the right stringstream implementation. * common/BaseWorld.cpp, server/Persistance.cpp: Removed unused stringstream include. * rulesets/Creator.cpp: Added extra debug output. * client/define_world.h, client/define_world.cpp, client/CommClient.h: Use CreatorClient to store Creators mind, instead of BaseMind. * client/client.cpp, client/ObserverClient.h, client/ObserverClient.cpp, client/CreatorClient.h, client/CommClient.h, client/CommClient.cpp: Modify method names to fit capitalisation conventions. * client/CreatorClient.cpp: Implement creation of in-game entities, using creator entity. * client/CommClient.cpp: Added correct client side monitoring of creator entity. * client/ClientConnection.h, client/ClientConnection.cpp: Added pending method to establish if ops are in the queue. Switched send() method so we only send ops. Add setting of serialno of sent ops, starting with an offset of 512. * client/CharacterClient.h: Removed unused member, opFound. * client/CharacterClient.cpp: Debugged sendAndWait() method. Al Riddoch <alriddoch@zepler.org>
200 lines
5.6 KiB
C++
200 lines
5.6 KiB
C++
// This file may be redistributed and modified only under the terms of
|
|
// the GNU General Public License (See COPYING for details).
|
|
// Copyright (C) 2000 Alistair Riddoch
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
|
|
#include <Python.h>
|
|
|
|
#include "Python_API.h"
|
|
#include "Entity.h"
|
|
|
|
static PyObject * Thing_as_entity(ThingObject * self, PyObject * args)
|
|
{
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing as_entity");
|
|
return NULL;
|
|
}
|
|
if (!PyArg_ParseTuple(args, "")) {
|
|
return NULL;
|
|
}
|
|
AtlasObject * ret = newAtlasObject(NULL);
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->m_obj = new Object(self->m_thing->asObject());
|
|
return (PyObject *)ret;
|
|
}
|
|
|
|
static PyObject * Thing_get_xyz(ThingObject * self, PyObject * args)
|
|
{
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing get_xyz");
|
|
return NULL;
|
|
}
|
|
if (!PyArg_ParseTuple(args, "")) {
|
|
return NULL;
|
|
}
|
|
Vector3DObject * ret = newVector3DObject(NULL);
|
|
if (ret == NULL) {
|
|
return NULL;
|
|
}
|
|
ret->coords = self->m_thing->getXyz();
|
|
return (PyObject *)ret;
|
|
}
|
|
|
|
static PyMethodDef Thing_methods[] = {
|
|
{"get_xyz", (PyCFunction)Thing_get_xyz, 1},
|
|
{"as_entity", (PyCFunction)Thing_as_entity, 1},
|
|
{NULL, NULL} /* sentinel */
|
|
};
|
|
|
|
static void Thing_dealloc(ThingObject *self)
|
|
{
|
|
//if (self->m_thing != NULL) {
|
|
//delete self->m_thing;
|
|
//}
|
|
Py_XDECREF(self->Thing_attr);
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
static PyObject * Thing_getattr(ThingObject *self, char *name)
|
|
{
|
|
// Fairly major re-write of this to use operator[] of Thing base class
|
|
if (self->m_thing == NULL) {
|
|
PyErr_SetString(PyExc_TypeError, "invalid thing getattr");
|
|
return NULL;
|
|
}
|
|
// If operation search gets to here, it goes no further
|
|
if (strstr(name, "_operation") != NULL) {
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
return NULL;
|
|
}
|
|
if (strcmp(name, "type") == 0) {
|
|
PyObject * list = PyList_New(0);
|
|
if (list == NULL) {
|
|
return NULL;
|
|
}
|
|
PyObject * ent = PyString_FromString(self->m_thing->type.c_str());
|
|
PyList_Append(list, ent);
|
|
Py_DECREF(ent);
|
|
return list;
|
|
}
|
|
// if (strcmp(name, "map") == 0) {
|
|
// MemMap * tMap = self->m_thing->getMap();
|
|
// if (tMap == NULL) {
|
|
// PyErr_SetString(PyExc_TypeError, "Body entity has no map");
|
|
// return NULL;
|
|
// }
|
|
// MapObject * map = newMapObject(NULL);
|
|
// map->m_map = tMap;
|
|
// return (PyObject *)map;
|
|
// }
|
|
if (strcmp(name, "location") == 0) {
|
|
LocationObject * loc = newLocationObject(NULL);
|
|
loc->location = &self->m_thing->location;
|
|
loc->own = 0;
|
|
return (PyObject *)loc;
|
|
}
|
|
if (strcmp(name, "world") == 0) {
|
|
WorldObject * world = newWorldObject(NULL);
|
|
world->world = self->m_thing->world;
|
|
return (PyObject *)world;
|
|
}
|
|
if (self->Thing_attr != NULL) {
|
|
PyObject *v = PyDict_GetItemString(self->Thing_attr, name);
|
|
if (v != NULL) {
|
|
Py_INCREF(v);
|
|
return v;
|
|
}
|
|
}
|
|
Entity * thing = self->m_thing;
|
|
std::string attr(name);
|
|
PyObject * ret = Object_asPyObject((*thing)[attr]);
|
|
if (ret == NULL) {
|
|
return Py_FindMethod(Thing_methods, (PyObject *)self, name);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int Thing_setattr(ThingObject *self, char *name, PyObject *v)
|
|
{
|
|
if (self->m_thing == NULL) {
|
|
return -1;
|
|
}
|
|
if (self->Thing_attr == NULL) {
|
|
self->Thing_attr = PyDict_New();
|
|
if (self->Thing_attr == NULL) {
|
|
return -1;
|
|
}
|
|
}
|
|
if (strcmp(name, "status") == 0) {
|
|
// This needs to be here until we can sort the difference
|
|
// between floats and ints in python.
|
|
if (PyInt_Check(v)) {
|
|
self->m_thing->status = (double)PyInt_AsLong(v);
|
|
} else if (PyFloat_Check(v)) {
|
|
self->m_thing->status = PyFloat_AsDouble(v);
|
|
} else {
|
|
PyErr_SetString(PyExc_TypeError, "status must be numeric type");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
if (strcmp(name, "map") == 0) {
|
|
return -1;
|
|
}
|
|
Entity * thing = self->m_thing;
|
|
//std::string attr(name);
|
|
//if (v == NULL) {
|
|
//thing->attributes.erase(attr);
|
|
//return 0;
|
|
//}
|
|
Object obj = PyObject_asObject(v);
|
|
if (!obj.IsNone() && !obj.IsMap() && !obj.IsList()) {
|
|
thing->set(name, obj);
|
|
return 0;
|
|
}
|
|
// If we get here, then the attribute is not Atlas compatable, so we
|
|
// need to store it in a python dictionary
|
|
return PyDict_SetItemString(self->Thing_attr, name, v);
|
|
}
|
|
|
|
static int Thing_compare(ThingObject *self, ThingObject *other)
|
|
{
|
|
if ((self->m_thing == NULL) || (other->m_thing == NULL)) {
|
|
return -1;
|
|
}
|
|
return (self->m_thing == other->m_thing) ? 0 : 1;
|
|
}
|
|
|
|
PyTypeObject Thing_Type = {
|
|
PyObject_HEAD_INIT(&PyType_Type)
|
|
0, /*ob_size*/
|
|
"cppThing", /*tp_name*/
|
|
sizeof(ThingObject), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
/* methods */
|
|
(destructor)Thing_dealloc, /*tp_dealloc*/
|
|
0, /*tp_print*/
|
|
(getattrfunc)Thing_getattr, /*tp_getattr*/
|
|
(setattrfunc)Thing_setattr, /*tp_setattr*/
|
|
(cmpfunc)Thing_compare, /*tp_compare*/
|
|
0, /*tp_repr*/
|
|
0, /*tp_as_number*/
|
|
0, /*tp_as_sequence*/
|
|
0, /*tp_as_mapping*/
|
|
0, /*tp_hash*/
|
|
};
|
|
|
|
ThingObject * newThingObject(PyObject *arg)
|
|
{
|
|
ThingObject * self;
|
|
self = PyObject_NEW(ThingObject, &Thing_Type);
|
|
if (self == NULL) {
|
|
return NULL;
|
|
}
|
|
self->Thing_attr = NULL;
|
|
return self;
|
|
}
|