67 #include <svnversion.h> 72 #define PYTHON_CACHE_SIZE 256 77 struct pycode_cache_entry { 84 #define MAX_COMMANDS 1024 98 vsnprintf(buf,
sizeof(buf), fmt, arg);
101 PyErr_SetString(PyExc_ValueError, buf);
120 if (!PyArg_ParseTuple(args,
"i", &eventcode))
133 if (!PyArg_ParseTuple(args,
"i", &eventcode))
157 if (!PyArg_ParseTuple(args,
"s", &obname))
170 return Py_BuildValue(
"i", i);
176 return Py_BuildValue(
"i", current_context->
returnvalue);
183 if (!PyArg_ParseTuple(args,
"i", &i))
196 if (!PyArg_ParseTuple(args,
"ss", &premiere, &seconde))
201 return Py_BuildValue(
"i", 1);
203 return Py_BuildValue(
"i", 0);
206 static PyObject *
findPlayer(PyObject *
self, PyObject *args) {
211 if (!PyArg_ParseTuple(args,
"s", &txt))
224 static PyObject *
readyMap(PyObject *
self, PyObject *args) {
230 if (!PyArg_ParseTuple(args,
"s|i", &mapname, &flags))
238 static PyObject *
createMap(PyObject *
self, PyObject *args) {
243 if (!PyArg_ParseTuple(args,
"ii", &sizex, &sizey))
293 static PyObject *
getWhoAmI(PyObject *
self, PyObject *args) {
296 if (!current_context->
who) {
300 Py_INCREF(current_context->
who);
301 return current_context->
who;
318 if (!current_context->
third) {
322 Py_INCREF(current_context->
third);
323 return current_context->
third;
329 if (*current_context->
message ==
'\0')
330 return Py_BuildValue(
"");
332 return Py_BuildValue(
"s", current_context->
message);
338 return Py_BuildValue(
"s", current_context->
script);
344 if (!*current_context->
options) {
348 return Py_BuildValue(
"s", current_context->
options);
351 static PyObject *
getEvent(PyObject *
self, PyObject *args) {
354 if (!current_context->
event) {
358 Py_INCREF(current_context->
event);
359 return current_context->
event;
386 std::vector<archetype *> archs;
391 list = PyList_New(0);
392 for (
auto arch : archs) {
398 static PyObject *
getPlayers(PyObject *
self, PyObject *args) {
406 list = PyList_New(0);
407 for (
auto pl : players) {
413 static PyObject *
getMaps(PyObject *
self, PyObject *args) {
415 std::vector<mapstruct *>
maps;
421 list = PyList_New(0);
422 for (
auto map : maps) {
428 static PyObject *
getParties(PyObject *
self, PyObject *args) {
430 std::vector<partylist *> parties;
435 list = PyList_New(0);
436 for (
auto party : parties) {
442 static PyObject *
getRegions(PyObject *
self, PyObject *args) {
449 list = PyList_New(0);
450 for (
auto reg : regions) {
463 list = PyList_New(0);
464 for (
auto ob : friends) {
471 char buf[1024], path[1024];
481 context->
third = NULL;
483 context->
event = NULL;
484 snprintf(context->
script,
sizeof(context->
script),
"%s", buf);
486 snprintf(context->
options,
sizeof(context->
options),
"%s", params);
507 if (!PyArg_ParseTuple(args,
"ssd|i", &cmdname, &scriptname, &cmdspeed, &type))
525 if (index == MAX_COMMANDS) {
532 set_exception(
"failed to register command (overriding an existing one with a different type?)");
540 static PyObject *
getTime(PyObject *
self, PyObject *args) {
548 list = PyList_New(0);
549 PyList_Append(list, Py_BuildValue(
"i", tod.
year));
550 PyList_Append(list, Py_BuildValue(
"i", tod.
month));
551 PyList_Append(list, Py_BuildValue(
"i", tod.
day));
552 PyList_Append(list, Py_BuildValue(
"i", tod.
hour));
553 PyList_Append(list, Py_BuildValue(
"i", tod.
minute));
554 PyList_Append(list, Py_BuildValue(
"i", tod.
dayofweek));
555 PyList_Append(list, Py_BuildValue(
"i", tod.
weekofmonth));
556 PyList_Append(list, Py_BuildValue(
"i", tod.
season));
557 PyList_Append(list, Py_BuildValue(
"i", tod.
periodofday));
566 if (!PyArg_ParseTuple(args,
"i", &
id))
575 if (!PyArg_ParseTuple(args,
"s", &name))
580 static PyObject *
findFace(PyObject *
self, PyObject *args) {
584 if (!PyArg_ParseTuple(args,
"s", &name))
595 if (!PyArg_ParseTuple(args,
"is", &intLevel, &message))
618 if ((message != NULL) && (message[strlen(message)] ==
'\n'))
619 cf_log(level,
"CFPython: %s", message);
621 cf_log(level,
"CFPython: %s\n", message);
630 if (!PyArg_ParseTuple(args,
"s", &name))
639 if (!PyArg_ParseTuple(args,
"i", &i))
648 if (!PyArg_ParseTuple(args,
"i", &i))
657 if (!PyArg_ParseTuple(args,
"i", &i))
666 if (!PyArg_ParseTuple(args,
"i", &i))
671 static PyObject *
addReply(PyObject *
self, PyObject *args) {
676 if (current_context->
talk == NULL) {
680 talk = current_context->
talk;
682 if (!PyArg_ParseTuple(args,
"ss", &word, &reply)) {
704 if (current_context->
talk == NULL) {
709 if (!PyArg_ParseTuple(args,
"s|i", &message, &type)) {
722 static PyObject *
npcSay(PyObject *
self, PyObject *args) {
724 char *message,
buf[2048];
730 if (current_context->
talk == NULL) {
740 if (strlen(message) >=
sizeof(buf) - 1)
741 cf_log(
llevError,
"CFPython: warning, too long message in npcSay, will be truncated");
743 snprintf(buf,
sizeof(buf),
"%s says: %s", npc->
obj->
name, message);
755 int largest_coin = 0;
758 if (!PyArg_ParseTuple(args,
"L|i", &value, &largest_coin))
762 return Py_BuildValue(
"s", buf);
766 {
"WhoAmI",
getWhoAmI, METH_NOARGS, NULL },
772 {
"WhatIsEvent",
getEvent, METH_NOARGS, NULL },
780 {
"ReadyMap",
readyMap, METH_VARARGS, NULL },
781 {
"CreateMap",
createMap, METH_VARARGS, NULL },
782 {
"FindPlayer",
findPlayer, METH_VARARGS, NULL },
783 {
"MatchString",
matchString, METH_VARARGS, NULL },
791 {
"GetPlayers",
getPlayers, METH_NOARGS, NULL },
793 {
"GetMaps",
getMaps, METH_NOARGS, NULL },
794 {
"GetParties",
getParties, METH_NOARGS, NULL },
795 {
"GetRegions",
getRegions, METH_NOARGS, NULL },
800 {
"GetTime",
getTime, METH_NOARGS, NULL },
804 {
"FindFace",
findFace, METH_VARARGS, NULL },
810 {
"AddReply",
addReply, METH_VARARGS, NULL },
812 {
"NPCSay",
npcSay, METH_VARARGS, NULL },
814 { NULL, NULL, 0, NULL }
818 current_context = NULL;
819 context_stack = NULL;
823 if (current_context == NULL) {
824 context_stack = context;
825 context->
down = NULL;
829 current_context = context;
835 if (current_context != NULL) {
837 current_context = current_context->
down;
845 Py_XDECREF(context->
event);
846 Py_XDECREF(context->
third);
847 Py_XDECREF(context->
who);
856 PyObject *scriptfile;
858 fd = open(filename, O_RDONLY);
861 scriptfile = PyFile_FromFd(fd, filename,
"r", -1, NULL, NULL, NULL, 1);
870 return fdopen(PyObject_AsFileDescriptor(obj),
"r");
879 #if defined(IS_PY3K9) || defined(IS_PY3K10) 884 static PyObject *io_module = NULL;
898 PyObject *output = PyObject_GetAttrString(
catcher,
"value");
899 PyObject* empty = PyUnicode_FromString(
"");
904 PyObject_SetAttrString(
catcher,
"value", empty);
914 PyObject *scriptfile = NULL;
916 struct stat stat_buf;
920 if (stat(filename, &stat_buf)) {
921 cf_log(
llevError,
"CFPython: script file %s can't be stat'ed\n", filename);
934 if (pycode_cache[i].file == NULL) {
935 replace = &pycode_cache[i];
937 }
else if (pycode_cache[i].file == sh_path) {
939 if (pycode_cache[i].code == NULL || (pycode_cache[i].cached_time < stat_buf.st_mtime)) {
941 replace = &pycode_cache[i];
945 run = &pycode_cache[i];
948 }
else if (replace == NULL || pycode_cache[i].used_time < replace->used_time)
950 replace = &pycode_cache[i];
955 Py_XDECREF(replace->
code);
956 replace->
code = NULL;
959 if (replace->
file != sh_path) {
965 #if defined (IS_PY3K9) || defined(IS_PY3K10) 977 io_module = PyImport_ImportModule(
"io");
978 scriptfile = PyObject_CallMethod(io_module,
"open",
"ss", filename,
"rb");
980 cf_log(
llevDebug,
"CFPython: script file %s can't be opened\n", filename);
984 PyObject *source_bytes = PyObject_CallMethod(scriptfile,
"read",
"");
985 (void)PyObject_CallMethod(scriptfile,
"close",
"");
986 PyObject *code = Py_CompileString(PyBytes_AsString(source_bytes), filename, Py_file_input);
988 replace->
code = (PyCodeObject *)code;
990 if (PyErr_Occurred())
1001 cf_log(
llevDebug,
"CFPython: script file %s can't be opened\n", filename);
1008 if ((n = PyParser_SimpleParseFile(pyfile, filename, Py_file_input))) {
1009 replace->
code = PyNode_Compile(n, filename);
1012 if (PyErr_Occurred())
1024 Py_DECREF(scriptfile);
1027 assert(run != NULL);
1028 run->used_time = time(NULL);
1033 PyCodeObject *pycode;
1044 dict = PyDict_New();
1045 PyDict_SetItemString(dict,
"__builtins__", PyEval_GetBuiltins());
1046 ret = PyEval_EvalCode((PyObject *)pycode, dict, NULL);
1047 if (PyErr_Occurred()) {
1070 snprintf(tmp,
sizeof(tmp),
"Crossfire_%s", name);
1072 cst = PyModule_New(tmp);
1073 dict = PyDict_New();
1075 while (constants[i].name != NULL) {
1076 PyModule_AddIntConstant(cst, (
char *)constants[i].name, constants[i].value);
1077 PyDict_SetItem(dict, PyLong_FromLong(constants[i].value), PyUnicode_FromString(constants[i].name));
1080 PyDict_SetItemString(PyModule_GetDict(module), name, cst);
1082 snprintf(tmp,
sizeof(tmp),
"%sName", name);
1083 PyDict_SetItemString(PyModule_GetDict(module), tmp, dict);
1101 snprintf(tmp,
sizeof(tmp),
"Crossfire_%s", name);
1103 cst = PyModule_New(tmp);
1105 while (constants[i].name != NULL) {
1106 PyModule_AddIntConstant(cst, (
char *)constants[i].name, constants[i].value);
1109 PyDict_SetItemString(PyModule_GetDict(module), name, cst);
1419 addConstants(module,
"AttackTypeNumber", cstAttackTypeNumber);
1435 PyObject *d = PyModule_GetDict(m);
1464 PyModule_AddObject(m,
"LogError", Py_BuildValue(
"i",
llevError));
1465 PyModule_AddObject(m,
"LogInfo", Py_BuildValue(
"i",
llevInfo));
1466 PyModule_AddObject(m,
"LogDebug", Py_BuildValue(
"i",
llevDebug));
1467 PyModule_AddObject(m,
"LogMonster", Py_BuildValue(
"i",
llevMonster));
1469 CFPythonError = PyErr_NewException(
"Crossfire.error", NULL, NULL);
1476 PyModuleDef_HEAD_INIT,
1498 const char *stdOutErr =
1500 class CatchOutErr:\n\ 1501 def __init__(self):\n\ 1503 def write(self, txt):\n\ 1504 self.value += txt\n\ 1505 catchOutErr = CatchOutErr()\n\ 1506 sys.stdout = catchOutErr\n\ 1507 sys.stderr = catchOutErr\n\ 1523 m = PyImport_ImportModule(
"Crossfire");
1533 m = PyImport_AddModule(
"__main__");
1534 PyRun_SimpleString(stdOutErr);
1535 catcher = PyObject_GetAttrString(m,
"catchOutErr");
1541 const char *propname;
1545 va_start(args, type);
1546 propname = va_arg(args,
const char *);
1547 if (!strcmp(propname,
"Identification")) {
1548 buf = va_arg(args,
char *);
1549 size = va_arg(args,
int);
1553 }
else if (!strcmp(propname,
"FullName")) {
1554 buf = va_arg(args,
char *);
1555 size = va_arg(args,
int);
1617 for (
int e = 0; eventFiles[e] != NULL; e++) {
1618 free(eventFiles[e]);
1629 char **eventFiles =
static_cast<char **
>(calloc(1,
sizeof(eventFiles[0])));
1630 eventFiles[0] = NULL;
1633 int allocated = 0, current = 0;
1638 snprintf(name,
sizeof(name),
"python/events/%s/", context->
options);
1646 while ((d =
readdir(dp)) != NULL) {
1647 snprintf(name,
sizeof(name),
"%s%s", path, d->d_name);
1649 if (S_ISDIR(sb.st_mode)) {
1652 if (strcmp(d->d_name + strlen(d->d_name) - 3,
".py")) {
1656 if (allocated == current) {
1658 eventFiles =
static_cast<char **
>(realloc(eventFiles,
sizeof(
char *) * (allocated + 1)));
1659 for (
int i = current; i < allocated + 1; i++) {
1660 eventFiles[i] = NULL;
1663 eventFiles[current] = strdup(name);
1671 PyObject *scriptfile;
1677 for (i = 0;
GECodes[i] != 0; i++)
1681 if (scriptfile != NULL) {
1683 PyRun_SimpleFile(pyfile,
cf_get_maps_directory(
"python/events/python_init.py", path,
sizeof(path)));
1684 Py_DECREF(scriptfile);
1688 pycode_cache[i].
code = NULL;
1689 pycode_cache[i].
file = NULL;
1698 for (
int i = 0;
GECodes[i] != 0; i++) {
1715 va_start(args, type);
1727 op = va_arg(args,
object *);
1732 op = va_arg(args,
object *);
1734 op = va_arg(args,
object *);
1740 op = va_arg(args,
object *);
1741 object* hitter = va_arg(args,
object *);
1748 pl = va_arg(args,
player *);
1750 buf = va_arg(args,
char *);
1756 pl = va_arg(args,
player *);
1758 buf = va_arg(args,
char *);
1764 op = va_arg(args,
object *);
1769 op = va_arg(args,
object *);
1771 buf = va_arg(args,
char *);
1777 op = va_arg(args,
object *);
1779 buf = va_arg(args,
char *);
1785 op = va_arg(args,
object *);
1787 buf = va_arg(args,
char *);
1793 op = va_arg(args,
object *);
1799 op = va_arg(args,
object *);
1812 op = va_arg(args,
object *);
1813 buf = va_arg(args,
char *);
1817 op = va_arg(args,
object *);
1834 context->
third = PyLong_FromUnsignedLong(va_arg(args, uint64_t));
1849 for (
int file = 0; files[file] != NULL; file++)
1852 (*copy) = (*context);
1854 Py_XINCREF(copy->
event);
1855 Py_XINCREF(copy->
third);
1856 Py_XINCREF(copy->
who);
1857 strncpy(copy->
script, files[file],
sizeof(copy->
script));
1892 va_start(args, type);
1897 buf = va_arg(args,
char *);
1901 event = va_arg(args,
object *);
1934 Py_XDECREF(pycode_cache[i].code);
1935 if (pycode_cache[i].file != NULL)
static void python_command_function(object *op, const char *params, const char *script)
#define AT_HOLYWORD
Damage based on race and caster's god.
#define EVENT_SAY
Someone speaks.
static event_registration c
int npc_msg_count
How many NPCs reacted to the text being said.
#define MOVE_WALK
Object walks.
PyObject_HEAD object * obj
#define PYTHON_CACHE_SIZE
Number of python scripts to store the bytecode of at a time.
see doc/Developers/objects
static PyObject * getSeasonName(PyObject *self, PyObject *args)
#define COMMAND_TYPE_WIZARD
Wizard-only commands.
#define AT_ELECTRICITY
Can also ignite objects (8)
#define EVENT_REMOVE
A Player character has been removed.
#define AT_COUNTERSPELL
Cancels magic spells (524288) peterm@soda.berkeley.edu.
static command_registration registered_commands[MAX_COMMANDS]
void Handle_Map_Unload_Hook(Crossfire_Map *map)
static PyObject * setReturnValue(PyObject *self, PyObject *args)
#define AT_DEPLETE
Lose one point from one stat, can be restored (65536) vick@bern.docs.uu.se.
#define RANDO
The monster will go in a random direction until it is stopped by an obstacle, then it chooses another...
#define AT_GHOSTHIT
Attacker dissolves (512)
static PyObject * createMap(PyObject *self, PyObject *args)
object * cf_create_object(void)
Wrapper for object_new().
void cf_get_time(timeofday_t *tod)
Eneq((at)csd.uu.se): Id for close_container archetype.
void cf_free_string(sstring str)
Wrapper for free_string().
static PyObject * getEvent(PyObject *self, PyObject *args)
#define CFAPI_SYSTEM_MAPS
const char * cf_get_month_name(int index)
static int do_script(CFPContext *context)
static PyObject * getTime(PyObject *self, PyObject *args)
static PyObject * getScriptParameters(PyObject *self, PyObject *args)
static PyObject * addReply(PyObject *self, PyObject *args)
#define NDI_ALL
Inform all players of this message.
#define EVENT_LOGOUT
Player logout.
#define EVENT_STOP
Thrown object stopped.
PyObject * Crossfire_Region_wrap(region *what)
std::vector< archetype * > players
#define EVENT_MAPUNLOAD
A map is freed (includes swapping out)
#define CFAPI_SYSTEM_FRIENDLY_LIST
void cf_system_unregister_command(command_registration command)
#define AT_INTERNAL
Only used for internal calculations.
static void freeContext(CFPContext *context)
static PyObject * getCFPythonVersion(PyObject *self, PyObject *args)
mapstruct * cf_get_empty_map(int sizex, int sizey)
Wrapper for get_empty_map().
static PyModuleDef CrossfireModule
#define EVENT_PICKUP
Object picked up.
PyObject * Crossfire_Map_wrap(mapstruct *what)
static std::vector< std::pair< object *, tag_t > > friends
List of all friendly objects, object and its count.
#define PACEV2
The monster will pace as above but the length of the pace area is longer and the monster stops before...
PyTypeObject Crossfire_MapType
sstring message
If not NULL, what the player will be displayed as said.
#define AT_CANCELLATION
Removes magic from items (32768) ylitalo@student.docs.uu.se.
static void freeEventFiles(char **eventFiles)
Clear the list of event files.
PyObject * PyInit_cjson(void)
#define HUGE_BUF
Used for messages - some can be quite long.
static PyObject * getWhoIsActivator(PyObject *self, PyObject *args)
sstring slaying
Which race to do double damage to.
void cf_system_get_map_vector(int property, std::vector< mapstruct *> *list)
static PyObject * getUniqueDirectory(PyObject *self, PyObject *args)
#define NDI_BLUE
Actually, it is Dodger Blue.
sstring replies[MAX_REPLIES]
Description for replies_words.
#define EVENT_SELLING
Object is being sold by another one.
const CFConstant cstMove[]
PyObject * Crossfire_Archetype_wrap(archetype *what)
DIR * opendir(const char *)
Object for applying character class modifications to someone.
static PyObject * costStringFromValue(PyObject *self, PyObject *args)
static void initConstants(PyObject *module)
sstring replies_words[MAX_REPLIES]
Available reply words.
#define EVENT_LOGIN
Player login.
#define AT_COLD
Can freeze objects into ice cubes (16)
static PyObject * private_data
int cf_timer_destroy(int id)
Destroys specified timer, equivalent of calling cftimer_destroy().
Represents the ingame time.
PyObject * Crossfire_Object_wrap(object *what)
Python initialized.
static PyObject * findPlayer(PyObject *self, PyObject *args)
#define EVENT_KICK
A player was Kicked by a DM.
#define CFAPI_SYSTEM_ARCHETYPES
Duplicator/multiplier object.
int initPlugin(const char *iversion, f_plug_api gethooksptr)
The server calls this function after loading the plugin.
#define CIRCLE1
If the upper four bits of move_type / attack_movement are set to this number, the monster will move i...
#define AT_BLIND
Blinds victim (4194304) thomas@astro.psu.edu.
PyTypeObject Crossfire_PlayerType
player * cf_player_find(const char *plname)
Wrapper for find_player_partial_name().
sstring cf_add_string(const char *str)
Wrapper for add_string().
animal 'body parts' -b.t.
#define PETMOVE
If the upper four bits of attack_movement are set to this number, the monster follows a player until ...
static std::unordered_map< std::string, Region * > regions
All defined regions.
#define HITRUN
Run to then hit player then run away cyclicly.
peterm: detector is an object which notices the presense of another object and is triggered like butt...
static PyObject * registerCommand(PyObject *self, PyObject *args)
#define NDI_DK_ORANGE
DarkOrange2.
static PyObject * destroyTimer(PyObject *self, PyObject *args)
CF_PLUGIN int postInitPlugin(void)
The server calls this function to actually initialize the plugin here, after object handlers are regi...
const CFConstant cstAttackTypeNumber[]
const char * cf_get_weekday_name(int index)
#define EVENT_ATTACKED
Object attacked, with weapon or spell.
int cf_find_animation(const char *txt)
Wrapper for find_animation().
void cf_log(LogLevel logLevel, const char *format,...)
Wrapper for LOG().
#define AT_TURN_UNDEAD
Like Fear, but for undead only (8192)
static PyObject * getWhoAmI(PyObject *self, PyObject *args)
PyCodeObject * code
Compiled code, NULL if there was an error.
static void log_python_error(void)
Trace a Python error to the Crossfire log.
#define MOVE_ALL
Mask of all movement types.
#define AT_LIFE_STEALING
16777216 for hp drain
Used during character creation.
Allows the use of a skill.
void cf_log_plain(LogLevel logLevel, const char *message)
Wrapper for LOG() that uses directly a buffer, without format.
#define AT_CHAOS
None by itself, uses random other types (262144) peterm@soda.berkeley.edu.
Generic item builder, see subtypes below.
const char * cf_get_season_name(int index)
#define RUNATT
Run but attack if player catches up to object.
const CFConstant cstTime[]
CF_PLUGIN int eventListener(int *type,...)
Handles an object-related event.
#define AT_GODPOWER
Adds relevant god's attacktype (1048576) peterm@soda.berkeley.edu.
reply_type
Various kind of messages a player or NPC can say.
Floor tile -> native layer 0.
static PyObject * getSharedDictionary(PyObject *self, PyObject *args)
PyObject * Crossfire_Party_wrap(partylist *what)
#define EVENT_CRASH
Triggered when the server crashes.
int replies_count
How many items in replies_words and replies.
const CFConstant cstAttackType[]
int cf_init_plugin(f_plug_api getHooks)
static PyObject * getMonthName(PyObject *self, PyObject *args)
static PyObject * getPrivateDictionary(PyObject *self, PyObject *args)
static void addConstants(PyObject *module, const char *name, const CFConstant *constants)
Add constants and a reverse dictionary to get the name from the value.
#define MAX_REPLIES
How many NPC replies maximum to tell the player.
#define AT_DISEASE
33554432 disease attacktypes
static PyObject * setPlayerMessage(PyObject *self, PyObject *args)
time_t cached_time
Time this cache entry was created.
static PyObject * findFace(PyObject *self, PyObject *args)
battleground, by Andreas Vogl
inserts an invisible, weightless force into a player with a specified string.
#define MOVE_SWIM
Swimming object.
const CFConstant cstDirection[]
CF_PLUGIN int closePlugin(void)
called before the plugin gets unloaded from memory.
static PyObject * getParties(PyObject *self, PyObject *args)
#define NDI_ALL_DMS
Inform all logged in DMs.
#define MOVE_FLY_LOW
Low flying object.
Structure used to build up dialog information when a player says something.
static PyObject * findAnimation(PyObject *self, PyObject *args)
inserts an invisible, weightless force into a player with a specified string WHEN TRIGGERED...
static PyObject * readyMap(PyObject *self, PyObject *args)
static PyObject * CFPythonError
#define EVENT_MAPRESET
A map is resetting.
uint64_t command_registration
Identifier when registering a command.
void cf_cost_string_from_value(uint64_t cost, int largest_coin, char *buffer, int length)
Wrapper for cost_string_from_value modified to take a char* and length instead of a StringBuffer...
mapstruct * cf_map_get_map(const char *name, int flags)
Wrapper for ready_map_name().
void cf_system_get_object_vector(int property, std::vector< object *> *list)
#define EVENT_BORN
A new character has been created.
#define EVENT_GKILL
Triggered when anything got killed by anyone.
#define MOVE_FLYING
Combo of fly_low and fly_high.
CF_PLUGIN int cfpython_globalEventListener(int *type,...)
#define EVENT_CLOCK
Global time event.
const CFConstant cstAttackMovement[]
#define PACEH
The monster will pace back and forth until attacked.
static PyObject * log_message(PyObject *self, PyObject *args)
#define NDI_GREEN
SeaGreen.
static PyObject * unregisterGEvent(PyObject *self, PyObject *args)
#define EVENT_TRIGGER
Button pushed, lever pulled, etc.
#define EVENT_DESTROY
Object destroyed (includes map reset/swapout)
void cf_system_register_global_event(int event, const char *name, f_plug_event hook)
#define EVENT_MAPREADY
A map is ready, either first load or after reload.
static PyObject * getMapHasBeenLoaded(PyObject *self, PyObject *args)
static PyObject * getPlayers(PyObject *self, PyObject *args)
object * ob
The object representing the player.
#define EVENT_TELL
A player 'tell' something.
#define EVENT_TIMER
Timer connected triggered it.
#define EVENT_MAPLEAVE
A player left a map.
static PyObject * getScriptName(PyObject *self, PyObject *args)
#define AT_FIRE
Can ignite objects (4)
void cf_system_unregister_global_event(int event, const char *name)
#define NDI_LT_GREEN
DarkSeaGreen, which is actually paler than seagreen - also background color.
static PyObject * PyInit_Crossfire(void)
time_t used_time
Last use of this cache entry.
char * cf_get_maps_directory(const char *name, char *buf, int size)
Wrapper for create_pathname().
void cf_system_get_party_vector(int property, std::vector< partylist *> *list)
#define AT_PHYSICAL
Basic attack (1)
static void cfpython_init_types(PyObject *m)
Set up the various types (map, object, archetype and so on) as well as some constants, and Crossfire.error.
#define EVENT_PLAYER_DEATH
Global Death event.
static PyCodeObject * compilePython(char *filename)
Outputs the compiled bytecode for a given python file, using in-memory caching of bytecode...
static const char * getGlobalEventPath(int code)
static FILE * cfpython_pyfile_asfile(PyObject *obj)
Return a file object from a Python file (as needed for compilePython() and postInitPlugin()) ...
PyTypeObject Crossfire_PartyType
static PyObject * getReturnValue(PyObject *self, PyObject *args)
static PyObject * createCFObjectByName(PyObject *self, PyObject *args)
#define ATNR_COUNTERSPELL
LogLevel
Log levels for the LOG() function.
#define EVENT_USER
User-defined event.
static void pushContext(CFPContext *context)
Object owned by a player which can convert a monster into a peaceful being incapable of attack...
int cf_find_face(const char *name, int error)
Wrapper for find_face().
static void addSimpleConstants(PyObject *module, const char *name, const CFConstant *constants)
Do half the job of addConstants.
void cf_system_get_region_vector(int property, std::vector< region *> *list)
can add a skill to player's inventory -bt.
#define WAITATT
Wait for player to approach then hit, move if hit.
static PyObject * getPeriodofdayName(PyObject *self, PyObject *args)
#define EVENT_ATTACKS
Weapon or arrow hitting something.
static PyObject * getTempDirectory(PyObject *self, PyObject *args)
#define EVENT_BOUGHT
Object is being bought by player.
#define ALLRUN
Always run, never attack good for sim.
static char ** getEventFiles(CFPContext *context)
Get the list of script files to run for the specified global event context.
#define EVENT_GSOLD
Player sold object in shop, but global.
#define AT_DRAIN
Victim loses 2% exp, attacker gains half of that (128)
static const flag_definition flags[]
Flag mapping.
static void initContextStack(void)
void replace(const char *src, const char *key, const char *replacement, char *result, size_t resultsize)
Replace in string src all occurrences of key by replacement.
#define EVENT_CLOSE
Container closed.
const char * cf_re_cmp(const char *str, const char *regexp)
Wrapper for re_cmp().
static PyObject * getConfigDirectory(PyObject *self, PyObject *args)
static PyObject * getMapDirectory(PyObject *self, PyObject *args)
#define CFAPI_SYSTEM_PLAYERS
#define EVENT_MAPENTER
A player entered a map.
#define RUSH
Rush toward player blindly, similiar to dumb monster.
#define AT_POISON
Some damage each turn thereafter (1024)
#define WAIT2
Monster does not try to move towards player if far.
static PyObject * shared_data
Mark Wedel (mark@pyramid.com) Shop inventories.
static event_registration m
#define MAX_NPC
How many NPCs maximum will reply to the player.
CF_PLUGIN void * getPluginProperty(int *type,...)
The server calls this function to get information about the plugin, notably the name and version...
Also see SKILL_TOOL (74) below.
static PyObject * getLocalDirectory(PyObject *self, PyObject *args)
sstring file
Script full path.
sstring name
The name of the object, obviously...
Only for debugging purposes.
static PyObject * getWhoIsThird(PyObject *self, PyObject *args)
#define RANDO2
Constantly move in a different random direction.
#define AT_SLOW
Speed is reduced (2048)
static PyObject * getWeekdayName(PyObject *self, PyObject *args)
static PyObject * getArchetypes(PyObject *self, PyObject *args)
PyTypeObject Crossfire_ArchetypeType
#define ATNR_CANCELLATION
const CFConstant cstMessageFlag[]
struct dirent * readdir(DIR *)
static PyObject * cfpython_openpyfile(char *filename)
Open a file in the way we need it for compilePython() and postInitPlugin().
mapstruct * cf_map_has_been_loaded(const char *name)
Wrapper for has_been_loaded().
reply_type message_type
A reply_type value for message.
const char * cf_get_directory(int id)
Gets a directory Crossfire uses.
#define EVENT_TIME
Triggered each time the object can react/move.
static PyObject * getPlayerDirectory(PyObject *self, PyObject *args)
const CFConstant cstReplyTypes[]
#define AT_MAGIC
All magic spells, but not prayers (2)
static PyObject * getWhatIsMessage(PyObject *self, PyObject *args)
PyTypeObject Crossfire_ObjectType
static const char * GEPaths[]
Lauwenmark: an invisible object holding a plugin event hook.
static PyObject * matchString(PyObject *self, PyObject *args)
#define DISTATT
Move toward a player if far, but maintain some space, attack from a distance - good for missile users...
static PyObject * getDataDirectory(PyObject *self, PyObject *args)
See Monster (Grimreaper).
#define NDI_UNIQUE
Print immediately, don't buffer.
command_registration cf_system_register_command_extra(const char *name, const char *extra, command_function_extra func, uint8_t command_type, float time)
#define EVENT_MAPLOAD
A map is loaded (pristine state)
#define MOVE_FLY_HIGH
High flying object.
sstring npc_msgs[MAX_NPC]
What the NPCs will say.
A force, holding the effect of a resistance potion.
#define EVENT_APPLY
Object applied-unapplied.
CF_PLUGIN char SvnRevPlugin[]
static pycode_cache_entry pycode_cache[PYTHON_CACHE_SIZE]
Cached compiled scripts.
static PyObject * registerGEvent(PyObject *self, PyObject *args)
#define PACEH2
The monster will pace as above but the length of the pace area is longer and the monster stops before...
#define EVENT_MUZZLE
A player was Muzzled (no_shout set).
metals, minerals, dragon scales
static void set_exception(const char *fmt,...)
Set up an Python exception object.
CFPContext * current_context
#define PACEV
The monster will pace back and forth until attacked.
#define CFAPI_SYSTEM_PARTIES
#define CIRCLE2
Same as CIRCLE1 but a larger circle is used.
#define CFAPI_SYSTEM_REGIONS
CFPContext * context_stack
const CFConstant cstEventType[]
const char * cf_get_periodofday_name(int index)
#define AT_CONFUSION
Movement/attack directions become random (32)
#define EVENT_SHOUT
A player 'shout' something.
static PyObject * getRegions(PyObject *self, PyObject *args)
PyTypeObject Crossfire_RegionType
void cf_system_get_archetype_vector(int property, std::vector< archetype *> *list)
#define MOVE_BOAT
Boats/sailing.
One compiled script, cached in memory.
static std::unordered_map< std::string, mapzone * > maps
All defined maps, with the path as key.
#define COMMAND_TYPE_NORMAL
Standard commands.
static PyObject * getMaps(PyObject *self, PyObject *args)
#define AT_ACID
Random equipped item might corrode when hit (64)
const CFConstant cstType[]
#define AT_DEATH
Chance of instant death, otherwise nothing (131072) peterm@soda.berkeley.edu.
#define EVENT_THROW
Object is thrown.
object * cf_create_object_by_name(const char *name)
Wrapper for create_archetype() and create_archetype_by_object_name().
static CFPContext * popContext(void)
#define AT_WEAPONMAGIC
Direct damage, very special, use with care (256)
static PyObject * npcSay(PyObject *self, PyObject *args)
#define ATNR_LIFE_STEALING
void(* f_plug_api)(int *type,...)
General API function.
static PyObject * catcher
A Python object receiving the contents of Python's stderr, and used to output to the Crossfire log in...
static PyObject * createCFObject(PyObject *self, PyObject *args)
#define DISTHIT
Attack from a distance if hit as recommended by Frank.
#define AT_PARALYZE
Speed is reduced to zero (4096)
PyMethodDef CFPythonMethods[]
#define EVENT_DROP
Object dropped on the floor.
static PyObject * getFriendlyList(PyObject *self, PyObject *args)
#define EVENT_GBOUGHT
Player bought object in shop, but global.
#define NAME_MAX
NAME_MAX used by random maps may not be defined on pure ansi systems.
#define EVENT_DEATH
Player or monster dead.