//*****************************************************************************
//
// furniture.c
//
// handles all of the functioning of the furniture item type. Stores data about
// the capacity of the furniture, and what type of furniture it is.
//
//*****************************************************************************
#include "../mud.h"
#include "../utils.h"
#include "../storage.h"
#include "../object.h"
#include "../world.h"
#include "../socket.h"
#include "../olc2/olc.h"
#include "items.h"
#include "iedit.h"
#include "furniture.h"
//*****************************************************************************
// mandatory modules
//*****************************************************************************
#include "../scripts/scripts.h"
#include "../scripts/pyobj.h"
//*****************************************************************************
// item data for furnitures
//*****************************************************************************
typedef struct furniture_data {
int capacity;
int type;
} FURNITURE_DATA;
FURNITURE_DATA *newFurnitureData() {
FURNITURE_DATA *data = malloc(sizeof(FURNITURE_DATA));
data->capacity = 0;
data->type = FURNITURE_AT;
return data;
}
void deleteFurnitureData(FURNITURE_DATA *data) {
free(data);
}
void furnitureDataCopyTo(FURNITURE_DATA *from, FURNITURE_DATA *to) {
*to = *from;
}
FURNITURE_DATA *furnitureDataCopy(FURNITURE_DATA *data) {
FURNITURE_DATA *new_data = newFurnitureData();
furnitureDataCopyTo(data, new_data);
return new_data;
}
STORAGE_SET *furnitureDataStore(FURNITURE_DATA *data) {
STORAGE_SET *set = new_storage_set();
store_int(set, "capacity", data->capacity);
store_int(set, "type", data->type);
return set;
}
FURNITURE_DATA *furnitureDataRead(STORAGE_SET *set) {
FURNITURE_DATA *data = newFurnitureData();
data->capacity = read_int(set, "capacity");
data->type = read_int(set, "type");
return data;
}
//*****************************************************************************
// functions for interacting with furnitures
//*****************************************************************************
int furnitureGetCapacity(OBJ_DATA *obj) {
FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
return data->capacity;
}
void furnitureSetCapacity(OBJ_DATA *obj, int capacity) {
FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
data->capacity = capacity;
}
int furnitureGetType(OBJ_DATA *obj) {
FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
return data->type;
}
void furnitureSetType(OBJ_DATA *obj, int type) {
FURNITURE_DATA *data = objGetTypeData(obj, "furniture");
data->type = type;
}
const char *furniture_names[NUM_FURNITURES] = {
"at",
"on"
};
const char *furnitureTypeGetName(int type) {
return furniture_names[type];
}
int furnitureTypeGetNum(const char *type) {
int i;
for(i = 0; i < NUM_FURNITURES; i++)
if(!strcasecmp(furniture_names[i], type))
return i;
return FURNITURE_NONE;
}
//*****************************************************************************
// furniture olc
//*****************************************************************************
#define IEDIT_FURNITURE_CAPACITY 1
#define IEDIT_FURNITURE_TYPE 2
// the resedit olc needs these declared
void iedit_furniture_menu(SOCKET_DATA *sock, FURNITURE_DATA *data) {
send_to_socket(sock,
"{g1) Capacity: {c%d\r\n"
"{g2) Sit Type: {c%s\r\n",
data->capacity,
furnitureTypeGetName(data->type));
}
int iedit_furniture_chooser(SOCKET_DATA *sock, FURNITURE_DATA *data,
const char *option) {
switch(toupper(*option)) {
case '1':
text_to_buffer(sock, "Enter a new weight capacity for the furniture: ");
return IEDIT_FURNITURE_CAPACITY;
case '2':
olc_display_table(sock, furnitureTypeGetName, NUM_FURNITURES, 1);
text_to_buffer(sock, "Pick a furniture type: ");
return IEDIT_FURNITURE_TYPE;
default: return MENU_CHOICE_INVALID;
}
}
bool iedit_furniture_parser (SOCKET_DATA *sock, FURNITURE_DATA *data, int choice,
const char *arg) {
switch(choice) {
case IEDIT_FURNITURE_CAPACITY: {
int capacity = atoi(arg);
if(capacity <= 0)
return FALSE;
data->capacity = capacity;
return TRUE;
}
case IEDIT_FURNITURE_TYPE: {
int type = atoi(arg);
if(type < 0 || type >= NUM_FURNITURES || !isdigit(*arg))
return FALSE;
data->type = type;
return TRUE;
}
default: return FALSE;
}
}
void furniture_from_proto(FURNITURE_DATA *data, BUFFER *buf) {
const char *code = bufferString(buf);
char line[SMALL_BUFFER];
char *lptr = line;
int capacity = 0;
// two lines: capacity and type. First capacity, then type
code = strcpyto(line, code, '\n');
sscanf(line, "me.furniture_capacity = %d", &capacity);
data->capacity = capacity;
code = strcpyto(line, code , '\n');
while(*lptr && *lptr != '\"') lptr++;
lptr++; // skip the leading "
lptr[next_letter_in(lptr, '\"')] = '\0'; // kill closing "
data->type = furnitureTypeGetNum(lptr);
}
void furniture_to_proto(FURNITURE_DATA *data, BUFFER *buf) {
bprintf(buf, "me.furniture_capacity = %d\n", data->capacity);
bprintf(buf, "me.furniture_type = \"%s\"\n",
furnitureTypeGetName(data->type));
}
//*****************************************************************************
// pyobj getters and setters
//*****************************************************************************
PyObject *PyObj_getfurncapacity(PyObject *self, void *closure) {
OBJ_DATA *obj = PyObj_AsObj(self);
if(obj == NULL)
return NULL;
else if(objIsType(obj, "furniture"))
return Py_BuildValue("i", furnitureGetCapacity(obj));
else {
PyErr_Format(PyExc_TypeError, "Can only get capacity for furniture.");
return NULL;
}
}
int PyObj_setfurncapacity(PyObject *self, PyObject *value, void *closure) {
OBJ_DATA *obj = PyObj_AsObj(self);
if(obj == NULL) {
PyErr_Format(PyExc_StandardError, "Tried to set capacity for nonexistent "
"furniture, %d", PyObj_AsUid(self));
return -1;
}
else if(!objIsType(obj, "furniture")) {
PyErr_Format(PyExc_TypeError, "Tried to set capacity for non-furniture, %s",
objGetClass(obj));
return -1;
}
if(!PyInt_Check(value)) {
PyErr_Format(PyExc_TypeError, "furniture capacity must be an integer.");
return -1;
}
furnitureSetCapacity(obj, PyInt_AsLong(value));
return 0;
}
PyObject *PyObj_getfurntype(PyObject *self, void *closure) {
OBJ_DATA *obj = PyObj_AsObj(self);
if(obj == NULL)
return NULL;
else if(objIsType(obj, "furniture"))
return Py_BuildValue("s", furnitureTypeGetName(furnitureGetType(obj)));
else {
PyErr_Format(PyExc_TypeError, "Can only get furniture type for furniture.");
return NULL;
}
}
int PyObj_setfurntype(PyObject *self, PyObject *value, void *closure) {
OBJ_DATA *obj = PyObj_AsObj(self);
if(obj == NULL) {
PyErr_Format(PyExc_StandardError, "Tried to set furniture type for "
"nonexistent furniture, %d", PyObj_AsUid(self));
return -1;
}
else if(!objIsType(obj, "furniture")) {
PyErr_Format(PyExc_TypeError, "Tried to set furniture type for "
"non-furniture, %s", objGetClass(obj));
return -1;
}
if(!PyString_Check(value)) {
PyErr_Format(PyExc_TypeError, "furniture type must be a string.");
return -1;
}
else if(furnitureTypeGetNum(PyString_AsString(value)) == FURNITURE_NONE) {
PyErr_Format(PyExc_TypeError, "Invalid furniture type, %s",
PyString_AsString(value));
return -1;
}
furnitureSetType(obj, furnitureTypeGetNum(PyString_AsString(value)));
return 0;
}
//*****************************************************************************
// install the furniture item type
//*****************************************************************************
//
// this will need to be called by init_items() in items/items.c
void init_furniture(void) {
item_add_type("furniture",
newFurnitureData, deleteFurnitureData,
furnitureDataCopyTo, furnitureDataCopy,
furnitureDataStore, furnitureDataRead);
// set up the furniture OLC too
item_add_olc("furniture", iedit_furniture_menu, iedit_furniture_chooser,
iedit_furniture_parser, furniture_from_proto,furniture_to_proto);
// add our getters and setters for furniture
PyObj_addGetSetter("furniture_capacity",
PyObj_getfurncapacity, PyObj_setfurncapacity,
"The capacity of a furniture object.");
PyObj_addGetSetter("furniture_type", PyObj_getfurntype, PyObj_setfurntype,
"The type of furniture this is: 'at' or 'on'.");
}