forked from github/server
357 lines
9.6 KiB
C
357 lines
9.6 KiB
C
#include <platform.h>
|
|
#include <kernel/config.h>
|
|
|
|
#include "spells.h"
|
|
|
|
/* kernel includes */
|
|
#include <kernel/faction.h>
|
|
#include <kernel/item.h>
|
|
#include <kernel/messages.h>
|
|
#include <kernel/region.h>
|
|
#include <kernel/unit.h>
|
|
|
|
/* util includes */
|
|
#include <util/language.h>
|
|
#include <util/message.h>
|
|
#include <util/nrmessage.h>
|
|
|
|
/* lua includes */
|
|
#include <tolua.h>
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#define E_OK 0
|
|
#define E_INVALID_MESSAGE 1
|
|
#define E_INVALID_PARAMETER_NAME 2
|
|
#define E_INVALID_PARAMETER_TYPE 3
|
|
#define E_INVALID_PARAMETER_VALUE 4
|
|
|
|
typedef struct lua_message {
|
|
const message_type *mtype;
|
|
message *msg;
|
|
variant *args;
|
|
} lua_message;
|
|
|
|
int mtype_get_param(const message_type * mtype, const char *param)
|
|
{
|
|
int i;
|
|
for (i = 0; i != mtype->nparameters; ++i) {
|
|
if (strcmp(mtype->pnames[i], param) == 0) {
|
|
return i;
|
|
}
|
|
}
|
|
return mtype->nparameters;
|
|
}
|
|
|
|
static lua_message *msg_create_message(const char *type)
|
|
{
|
|
lua_message *lmsg = malloc(sizeof(lua_message));
|
|
lmsg->msg = 0;
|
|
lmsg->args = 0;
|
|
lmsg->mtype = mt_find(type);
|
|
if (lmsg->mtype) {
|
|
lmsg->args = (variant *)calloc(lmsg->mtype->nparameters, sizeof(variant));
|
|
}
|
|
return lmsg;
|
|
}
|
|
|
|
/*
|
|
static void
|
|
msg_destroy_message(lua_message * msg)
|
|
{
|
|
if (msg->msg) msg_release(msg->msg);
|
|
if (msg->mtype) {
|
|
int i;
|
|
for (i=0;i!=msg->mtype->nparameters;++i) {
|
|
if (msg->mtype->types[i]->release) {
|
|
msg->mtype->types[i]->release(msg->args[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
int msg_set_resource(lua_message * msg, const char *param, const char *resname)
|
|
{
|
|
if (msg->mtype) {
|
|
int i = mtype_get_param(msg->mtype, param);
|
|
const resource_type * rtype;
|
|
if (i == msg->mtype->nparameters) {
|
|
return E_INVALID_PARAMETER_NAME;
|
|
}
|
|
if (strcmp(msg->mtype->types[i]->name, "resource") != 0) {
|
|
return E_INVALID_PARAMETER_TYPE;
|
|
}
|
|
|
|
rtype = rt_find(resname);
|
|
if (rtype) {
|
|
msg->args[i].v = (void *)rtype;
|
|
}
|
|
else {
|
|
return E_INVALID_PARAMETER_VALUE;
|
|
}
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_set_unit(lua_message * msg, const char *param, const unit * u)
|
|
{
|
|
if (msg->mtype) {
|
|
int i = mtype_get_param(msg->mtype, param);
|
|
|
|
if (i == msg->mtype->nparameters) {
|
|
return E_INVALID_PARAMETER_NAME;
|
|
}
|
|
if (strcmp(msg->mtype->types[i]->name, "unit") != 0) {
|
|
return E_INVALID_PARAMETER_TYPE;
|
|
}
|
|
|
|
msg->args[i].v = (void *)u;
|
|
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_set_region(lua_message * msg, const char *param, const region * r)
|
|
{
|
|
if (msg->mtype) {
|
|
int i = mtype_get_param(msg->mtype, param);
|
|
|
|
if (i == msg->mtype->nparameters) {
|
|
return E_INVALID_PARAMETER_NAME;
|
|
}
|
|
if (strcmp(msg->mtype->types[i]->name, "region") != 0) {
|
|
return E_INVALID_PARAMETER_TYPE;
|
|
}
|
|
|
|
msg->args[i].v = (void *)r;
|
|
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_set_string(lua_message * msg, const char *param, const char *value)
|
|
{
|
|
if (msg->mtype) {
|
|
int i = mtype_get_param(msg->mtype, param);
|
|
variant var;
|
|
|
|
if (i == msg->mtype->nparameters) {
|
|
return E_INVALID_PARAMETER_NAME;
|
|
}
|
|
if (strcmp(msg->mtype->types[i]->name, "string") != 0) {
|
|
return E_INVALID_PARAMETER_TYPE;
|
|
}
|
|
|
|
var.v = (void *)value;
|
|
msg->args[i] = msg->mtype->types[i]->copy(var);
|
|
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_set_int(lua_message * msg, const char *param, int value)
|
|
{
|
|
if (msg->mtype) {
|
|
int i = mtype_get_param(msg->mtype, param);
|
|
if (i == msg->mtype->nparameters) {
|
|
return E_INVALID_PARAMETER_NAME;
|
|
}
|
|
if (strcmp(msg->mtype->types[i]->name, "int") != 0) {
|
|
return E_INVALID_PARAMETER_TYPE;
|
|
}
|
|
|
|
msg->args[i].i = value;
|
|
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_send_faction(lua_message * msg, faction * f)
|
|
{
|
|
assert(f);
|
|
assert(msg);
|
|
|
|
if (msg->mtype) {
|
|
if (msg->msg == NULL) {
|
|
msg->msg = msg_create(msg->mtype, msg->args);
|
|
}
|
|
add_message(&f->msgs, msg->msg);
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
int msg_send_region(lua_message * lmsg, region * r)
|
|
{
|
|
if (lmsg->mtype) {
|
|
if (lmsg->msg == NULL) {
|
|
lmsg->msg = msg_create(lmsg->mtype, lmsg->args);
|
|
}
|
|
add_message(&r->msgs, lmsg->msg);
|
|
return E_OK;
|
|
}
|
|
return E_INVALID_MESSAGE;
|
|
}
|
|
|
|
static int tolua_msg_create(lua_State * L)
|
|
{
|
|
const char *type = tolua_tostring(L, 1, 0);
|
|
lua_message *lmsg = msg_create_message(type);
|
|
tolua_pushusertype(L, (void *)lmsg, TOLUA_CAST "message");
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set_string(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char *param = tolua_tostring(L, 2, 0);
|
|
const char *value = tolua_tostring(L, 3, 0);
|
|
int result = msg_set_string(lmsg, param, value);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set_int(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char *param = tolua_tostring(L, 2, 0);
|
|
int value = (int)tolua_tonumber(L, 3, 0);
|
|
int result = msg_set_int(lmsg, param, value);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set_resource(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char *param = tolua_tostring(L, 2, 0);
|
|
const char *value = tolua_tostring(L, 3, 0);
|
|
int result = msg_set_resource(lmsg, param, value);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set_unit(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char *param = tolua_tostring(L, 2, 0);
|
|
unit *value = (unit *)tolua_tousertype(L, 3, 0);
|
|
int result = msg_set_unit(lmsg, param, value);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set_region(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char *param = tolua_tostring(L, 2, 0);
|
|
region *value = (region *)tolua_tousertype(L, 3, 0);
|
|
int result = msg_set_region(lmsg, param, value);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_set(lua_State * L)
|
|
{
|
|
tolua_Error err;
|
|
if (tolua_isnumber(L, 3, 0, &err)) {
|
|
return tolua_msg_set_int(L);
|
|
}
|
|
else if (tolua_isusertype(L, 3, TOLUA_CAST "region", 0, &err)) {
|
|
return tolua_msg_set_region(L);
|
|
}
|
|
else if (tolua_isusertype(L, 3, TOLUA_CAST "unit", 0, &err)) {
|
|
return tolua_msg_set_unit(L);
|
|
}
|
|
tolua_pushnumber(L, (lua_Number)-1);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_send_region(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
region *r = (region *)tolua_tousertype(L, 2, 0);
|
|
int result = msg_send_region(lmsg, r);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_report_action(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
region *r = (region *)tolua_tousertype(L, 2, 0);
|
|
unit *u = (unit *)tolua_tousertype(L, 3, 0);
|
|
int result, flags = (int)tolua_tonumber(L, 4, 0);
|
|
if (lmsg->msg == NULL) {
|
|
lmsg->msg = msg_create(lmsg->mtype, lmsg->args);
|
|
}
|
|
result = report_action(r, u, lmsg->msg, flags);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
|
|
static int tolua_msg_send_faction(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
faction *f = (faction *)tolua_tousertype(L, 2, 0);
|
|
if (f && lmsg) {
|
|
int result = msg_send_faction(lmsg, f);
|
|
tolua_pushnumber(L, (lua_Number)result);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int tolua_msg_render(lua_State * L)
|
|
{
|
|
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
|
|
const char * lname = tolua_tostring(L, 2, 0);
|
|
const struct locale * lang = lname ? get_locale(lname) : default_locale;
|
|
char name[64];
|
|
|
|
if (lmsg->msg == NULL) {
|
|
lmsg->msg = msg_create(lmsg->mtype, lmsg->args);
|
|
}
|
|
nr_render(lmsg->msg, lang, name, sizeof(name), NULL);
|
|
lua_pushstring(L, name);
|
|
return 1;
|
|
}
|
|
|
|
void tolua_message_open(lua_State * L)
|
|
{
|
|
/* register user types */
|
|
tolua_usertype(L, TOLUA_CAST "message");
|
|
|
|
tolua_module(L, NULL, 0);
|
|
tolua_beginmodule(L, NULL);
|
|
{
|
|
tolua_function(L, TOLUA_CAST "message", tolua_msg_create);
|
|
|
|
tolua_cclass(L, TOLUA_CAST "message", TOLUA_CAST "message", TOLUA_CAST "",
|
|
NULL);
|
|
tolua_beginmodule(L, TOLUA_CAST "message");
|
|
{
|
|
tolua_function(L, TOLUA_CAST "render", tolua_msg_render);
|
|
tolua_function(L, TOLUA_CAST "set", tolua_msg_set);
|
|
tolua_function(L, TOLUA_CAST "set_unit", tolua_msg_set_unit);
|
|
tolua_function(L, TOLUA_CAST "set_region", tolua_msg_set_region);
|
|
tolua_function(L, TOLUA_CAST "set_resource", tolua_msg_set_resource);
|
|
tolua_function(L, TOLUA_CAST "set_int", tolua_msg_set_int);
|
|
tolua_function(L, TOLUA_CAST "set_string", tolua_msg_set_string);
|
|
tolua_function(L, TOLUA_CAST "send_faction", tolua_msg_send_faction);
|
|
tolua_function(L, TOLUA_CAST "send_region", tolua_msg_send_region);
|
|
tolua_function(L, TOLUA_CAST "report_action", tolua_msg_report_action);
|
|
|
|
tolua_function(L, TOLUA_CAST "create", tolua_msg_create);
|
|
}
|
|
tolua_endmodule(L);
|
|
}
|
|
tolua_endmodule(L);
|
|
}
|