 |
Crossfire Server, Trunk
1.75.0
|
Go to the documentation of this file.
36 #define MAXITEMLEN 300
50 unsigned int flags = 0;
123 int flags, len, anim_speed;
150 len = strlen(item_n);
155 len = strlen(item_n);
158 strncpy(item_n+len+1, item_p, 127);
160 item_n[len+1+127] = 0;
161 len += strlen(item_n+1+len)+1;
175 anim_speed = (int)(1.0/
FABS(head->
speed));
177 if (anim_speed > 255)
195 int got_one = 0, start_look = 0, end_look = 0, objects_sent = 0;
200 LOG(
llevDebug,
"esrv_draw_look called when update_look was not set\n");
237 snprintf(
buf,
sizeof(
buf),
"Click here to see previous group of items");
283 snprintf(
buf,
sizeof(
buf),
"Click here to see next group of items");
317 int got_one = 0, start_look = 0, end_look = 0, objects_sent = 0;
336 snprintf(
buf,
sizeof(
buf),
"Click here to see previous group of items");
364 snprintf(
buf,
sizeof(
buf),
"Click here to see next group of items");
481 strlcpy(item_n, custom_name,
sizeof(item_n)-1);
482 strlcpy(item_p, custom_name,
sizeof(item_p));
485 len = strlen(item_n)+1;
486 snprintf(item_n+len,
sizeof(item_n)-len,
"%s", item_p);
487 len += strlen(item_n+len);
507 if (anim_speed > 255)
611 if (pl->
count == count)
615 if (op->count == count)
619 if (tmp->count == count)
626 if (
HEAD(op)->count == count)
630 if (tmp->count == count)
638 if (tmp->count == count)
650 if (len <= 0 || !
buf) {
658 LOG(
llevDebug,
"Player '%s' tried to examine the unknown object (%ld)\n", pl->
ob->
name, tag);
672 if (!
buf || len <= 0) {
688 if (tag&0x80000000) {
701 LOG(
llevDebug,
"Player '%s' tried to apply the unknown object (%d)\n", pl->
ob->
name, tag);
724 "Could not find object to lock/unlock");
730 "Can't lock/unlock an item on the ground");
733 if (op->
env != pl->
ob) {
735 "Can't lock/unlock an item not directly in your inventory");
743 "Unlocked %s.",
name);
781 "Could not find object to mark");
855 "You see nothing there.");
873 if (len <= 0 || !
buf) {
879 if (!(cp = strchr(
buf,
' '))) {
886 "You can't see there from where you're standing.");
892 "You can't see there from where you're standing.");
904 LOG(
llevDebug,
"Player '%s' tried to move an unknown object (%lu)\n", pl->
name, (
unsigned long)tag);
914 if (op->
map && !op->
env) {
948 LOG(
llevDebug,
"Player '%s' tried to move object to the unknown location (%d)\n", pl->
name,
to);
965 object *scroll, *
spell, *marked, *inscription, *currentspell;
966 tag_t tscroll, tspell, tmarked;
992 LOG(
llevDebug,
"Player %s sent an invalid scroll for inscribe command.\n", pl->
ob->
name);
998 LOG(
llevDebug,
"Player %s sent an invalid spell for inscribe command.\n", pl->
ob->
name);
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
#define MAP_CLIENT_X
This determines the maximum map size the client can request (and thus what the server will send to th...
void SockList_AddInt(SockList *sl, uint32_t data)
Adds a 32 bit value.
#define NS_FACESENT_FACE
Bitmask for the faces_sent[] array - what portion of the face have we sent?
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
void esrv_move_object(object *pl, tag_t to, tag_t tag, long nrof)
Move an object to a new location.
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
@ llevError
Error, serious thing.
#define FABS(x)
Decstations have trouble with fabs()...
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
void mark_item_cmd(uint8_t *data, int len, player *pl)
Client wants to mark some object.
@ FLESH
animal 'body parts' -b.t.
uint16_t container_position
Start of container contents to send to client.
uint16_t client_type
Public type information.
object * inv
Pointer to the first object in the inventory.
uint16_t look_position
Start of drawing of look window.
#define MSG_TYPE_SKILL
Messages related to skill use.
#define QUERY_FLAG(xyz, p)
Socket structure, represents a client-server connection.
object * object_merge(object *op, object *top)
This function goes through all objects below and including top, and merges op to the first matching o...
uint32_t mark_count
Count of marked object.
bool pick_up(object *op, object *alt)
Try to pick up an item.
uint8_t num_look_objects
The maximum number of objects to show on the ground view; this number includes the prev/next group fa...
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
float speed
Frequency of object 'moves' relative to server tick rate.
int16_t invisible
How much longer the object will be invis.
object * ob
The object representing the player.
object * transport
Transport the player is in.
struct mapstruct * map
Pointer to the map in which this object is present.
void do_dump(object *who, object *what)
int write_on_item(object *pl, const char *params, object *skill)
Implement the 'inscription' skill, which checks for the required skills and marked items before runni...
uint32_t update_inventory
If true, we need to send the inventory list.
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
@ SKILL
Also see SKILL_TOOL (74) below.
void examine_cmd(char *buf, int len, player *pl)
Client wants to examine some object.
tag_t count
Unique object number for this object.
static const flag_definition flags[]
Flag mapping.
#define MSG_TYPE_COMMAND_EXAMINE
Player examining something.
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
#define FLAG_BLESSED
Item has a blessing, opposite of cursed/damned.
#define MSG_TYPE_COMMAND_ERROR
Bad syntax/can't use command.
#define FLAG_INV_LOCKED
Item will not be dropped from inventory.
void SockList_Reset(SockList *sl)
Resets the length of the stored data for writing.
char path[HUGE_BUF]
Filename of the map.
#define FLAG_APPLIED
Object is ready for use by living.
object * above
Pointer to the object stacked above this one.
#define HUGE_BUF
Used for messages - some can be quite long.
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
#define FLAG_NO_PICK
Object can't be picked up.
Plugin animator file specs[Config] name
#define FLAG_IS_FLOOR
Can't see what's underneath this object.
uint32_t update_look
If true, we need to send the look window.
size_t SockList_Avail(const SockList *sl)
Returns the available bytes in a SockList instance.
#define LOOK_OBJ(ob)
This returns TRUE if the object is something that should be displayed in the look window.
int16_t y
Position in the map for this object.
static event_registration m
uint8_t mapy
How large a map the client wants.
#define MAP_IN_MEMORY
Map is fully loaded.
struct player * contr
Pointer to the player which control this object.
void lock_item_cmd(uint8_t *data, int len, player *pl)
Client wants to apply some object.
static void add_object_to_socklist(socket_struct *ns, SockList *sl, object *head)
Used in the send_look to put object head into SockList sl for socket ns.
uint8_t anim_speed
Ticks between animation-frames.
void esrv_send_face(socket_struct *ns, const Face *face, int nocache)
Sends a face to a client if they are in pixmap mode, nothing gets sent in bitmap mode.
void query_name(const object *op, char *buf, size_t size)
Describes an item.
int8_t blocked_los[MAP_CLIENT_X][MAP_CLIENT_Y]
Array showing what spaces the player can see.
#define FLAG_KNOWN_BLESSED
Item is known to be blessed.
#define FLAG_KNOWN_CURSED
The object is known to be cursed.
uint16_t number
This is the image unique identifier.
object * ranges[range_size]
Object for each range.
#define FOR_OB_AND_BELOW_FINISH()
Finishes FOR_OB_AND_BELOW_PREPARE().
#define HEAD(op)
Returns the head part of an object.
void SockList_AddShort(SockList *sl, uint16_t data)
Adds a 16 bit value.
int transport_can_hold(const object *transport, const object *op, int nrof)
Can transport hold object op? This is a pretty trivial function, but in the future,...
object * below
Pointer to the object stacked below this one.
void query_short_name(const object *op, char *buf, size_t size)
query_short_name(object) is similar to query_name(), but doesn't contain any information about object...
void SockList_AddChar(SockList *sl, unsigned char c)
Adds an 8 bit value.
const Face * face
Face with colors.
int out_of_map(mapstruct *m, int x, int y)
Return 1 if coordinates X and Y are out of the map M, taking into account tiling.
static bool player_can_see(player *pl, int dx, int dy)
int is_identified(const object *op)
Return true if the item is identified, either because it is of a type that doesn't ever need identifi...
uint8_t type
PLAYER, BULLET, etc.
void esrv_send_inventory(object *pl, object *op)
Sends inventory of a container.
#define FLAG_DAMNED
The object is very cursed.
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
static object * esrv_get_ob_from_count(object *pl, tag_t count)
Takes a player and object count (tag) and returns the actual object pointer, or null if it can't be f...
uint32_t tag_t
Object tag, unique during the whole game.
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
This is basically the same as out_of_map above(), but instead we return NULL if no map is valid (coor...
#define FOR_OB_AND_BELOW_PREPARE(op_)
Constructs a loop iterating over an object and all objects below it in the same pile.
const Animations * animation
Animation of this item, NULL if not animated.
void SockList_Init(SockList *sl)
Initializes the SockList instance.
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in of these the most important may be the signs all a player must do is apply the handle In the case of the player must move items over the button to hold it down Some of the larger buttons may need very large items to be moved onto before they can be activated Gates and locked but be for you could fall down into a pit full of ghosts or dragons and not be able to get back out Break away sometimes it may be worth a player s time to test the walls of a map for secret doors Fire such as missile weapons and spells you will notice them going up in smoke ! So be careful not to destroy valuable items Spellbooks sometimes a player can learn the other times they cannot There are many different types of books and scrolls out there Improve item have lower weight
bool player_can_find(object *op, object *ob)
Return true if player 'op' can see object 'op' for purpose of locating items for partial item matchin...
object * find_skill_by_name(object *who, const char *name)
This returns the skill pointer of the given name (the one that accumulates exp, has the level,...
static std::shared_ptr< inja::Environment > env
Rendering environment.
#define MAX_BUF
Used for all kinds of things.
object * drop_object(object *op, object *tmp, uint32_t nrof)
Try to drop an object on the floor.
int32_t last_weight
Last weight as sent to client; -1 means do not send weight.
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
#define FLAG_CLIENT_SENT
We use it to detect cases were the server is trying to send an upditem when we have not actually sent...
#define MSG_TYPE_COMMAND_FAILURE
Failed result from command.
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
#define FLAG_KNOWN_MAGICAL
The object is known to be magical.
object * mark
Marked object.
#define FLAG_REMOVED
Object is not in any map or invenory.
#define FLAG_WIZ
Object has special privilegies.
void esrv_send_animation(socket_struct *ns, const Animations *anim)
Need to send an animation sequence to the client.
#define NDI_UNIQUE
Print immediately, don't buffer.
sstring name
The name of the object, obviously...
#define MSG_TYPE_SKILL_FAILURE
Failure in using skill.
void esrv_send_item(object *pl, object *op)
Sends item's info to player.
void esrv_del_item(player *pl, object *ob)
Tells the client to delete an item.
int object_can_pick(const object *who, const object *item)
Finds out if an object can be picked up.
void esrv_draw_look(object *pl)
Send the look window.
object * env
Pointer to the object which is the environment.
const typedef char * sstring
static object * ob_if_can_find(object *op, object *ob)
Return object 'ob' if player 'op' can find it, otherwise return NULL.
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 8 bit length field.
uint32_t in_memory
Combination of IN_MEMORY_xxx flags.
int apply_by_living(object *pl, object *op, int aflag, int quiet)
Living thing is applying an object.
sstring object_get_value(const object *op, const char *const key)
Get an extra value by key.
void look_at(object *op, int dx, int dy)
Prints items on the specified square.
#define CLEAR_FLAG(xyz, p)
#define WEIGHT(op)
Returns the weight of the given object.
uint16_t num
Where we are in the array.
uint8_t anims_sent[MAXANIMNUM]
What animations we sent.
uint8_t * faces_sent
This is a bitmap on sent face status.
void apply_cmd(char *buf, int len, player *pl)
Client wants to apply some object.
#define MAXITEMLEN
This is the maximum number of bytes we expect any one item to take up.
====Textual A command containing textual data has data fields separated by one ASCII space character. word::A sequence of ASCII characters that does not contain the space or nul character. This is to distinguish it from the _string_, which may contain space characters. Not to be confused with a machine word. int::A _word_ containing the textual representation of an integer. Not to be confused with any of the binary integers in the following section. Otherwise known as the "string value of integer data". Must be parsed, e.g. using `atoi()` to get the actual integer value. string::A sequence of ASCII characters. This must only appear at the end of a command, since spaces are used to separate fields of a textual message.=====Binary All multi-byte integers are transmitted in network byte order(MSB first). int8::1-byte(8-bit) integer int16::2-byte(16-bit) integer int32::4-byte(32-bit) integer lstring::A length-prefixed string, which consists of an `int8` followed by that many bytes of the actual string. This is used to transmit a string(that may contain spaces) in the middle of binary data. l2string::Like _lstring_, but is prefixed with an `int16` to support longer strings Implementation Notes ~~~~~~~~~~~~~~~~~~~~ - Typical implementations read two bytes to determine the length of the subsequent read for the actual message, then read and parse the data from each message according to the commands described below. To send a message, the sender builds the message in a buffer, counts the length of the message, sends the length, and finally sends the actual message. TIP:Incorrectly transmitting or receiving the `length` field can lead to apparent "no response" issues as the client or server blocks to read the entire length of the message. - Since the protocol is highly interactive, it may be useful to set `TCP_NODELAY` on both the client and server. - If you are using a language with a buffered output stream, remember to flush the stream after a complete message. - If the connection is lost(which will also happen if the output buffer overflowing), the player is saved and the server cleans up. This does open up some abuses, but there is no perfect solution here. - The server only reads data from the socket if the player has an action. This isn 't really good, since many of the commands below might not be actual commands for the player. The alternative is to look at the data, and if it is a player command and there isn 't time, store it away to be processed later. But this increases complexity, in that the server must start buffering the commands. Fortunately, for now, there are few such client commands. Commands -------- In the documentation below, `S->C` represents a message to the client from the server, and `C->S` represents a message to the server from the client. Commands are documented in a brief format like:C->S:version< csval >[scval[vinfo]] Fields are enclosed like `< this >`. Optional fields are denoted like `[this]`. Spaces that appear in the command are literal, i.e. the<< _version > > command above uses spaces to separate its fields, but the command below does not:C->S:accountlogin< name >< password > As described in<< _messages > >, if a command contains data, then the command is separated from the data by a literal space. Many of the commands below refer to 'object tags'. Whenever the server creates an object, it creates a unique tag for that object(starting at 1 when the server is first run, and ever increasing.) Tags are unique, but are not consistent between runs. Thus, the client can not store tags when it exits and hope to re-use them when it joins the server at a later time - tags are only valid for the current connection. The protocol commands are broken into various sections which based somewhat on what the commands are for(ie, item related commands, map commands, image commands, etc.) In this way, all the commands related to similar functionality is in the same place. Initialization ~~~~~~~~~~~~~~ version ^^^^^^^ C->S:version< csval >[scval[vinfo]] S->C:version< csval >[scval[vinfo]] Used by the client and server to exchange which version of the Crossfire protocol they understand. Neither send this in response to the other - they should both send this shortly after a connection is established. csval::int, version level of C->S communications scval::int, version level of S->C communications vinfo::string, that is purely for informative that general client/server info(ie, javaclient, x11client, winclient, sinix server, etc). It is purely of interest of server admins who can see what type of clients people are using.=====Version ID If a new command is added to the protocol in the C->S direction, then the version number in csval will get increased. Likewise, the same is true for the scval. The version are currently integers, in the form ABCD. A=1, and will likely for quite a while. This will only really change if needed from rollover of B. B represents major protocol changes - if B mismatches, the clients will be totally unusable. Such an example would be change of map or item sending commands(either new commands or new format.) C represents more minor but still significant changes - clients might still work together, but some features that used to work may now fail due to the mismatch. An example may be a change in the meaning of some field in some command - providing the field is the same size, it still should be decoded properly, but the meaning won 't be processed properly. D represents very minor changes or new commands. Things should work no worse if D does not match, however if they do match, some new features might be included. An example of the would be the C->S mark command to mark items. Server not understanding this just means that the server can not process it, and will ignore it.=====Handling As far as the client is concerned, its _scval_ must be at least equal to the server, and its _csval_ should not be newer than the server. The server does not care about the version command it receives right now - all it currently does is log mismatches. In theory, the server should keep track of what the client has, and adjust the commands it sends respectively in the S->C direction. The server is resilant enough that it won 't crash with a version mismatch(however, client may end up sending commands that the server just ignores). It is really up to the client to enforce versioning and quit if the versions don 't match. NOTE:Since all packets have the length as the first 2 bytes, all that either the client or server needs to be able to do is look at the first string and see if it understands it. If not, it knows how many bytes it can skip. As such, exact version matches should not be necessary for proper operation - however, both the client and server needs to be coded to handle such cases.=====History _scval_ and _vinfo_ were added in version 1020. Before then, there was only one version sent in the version command. NOTE:For the most part, this has been obsoleted by the setup command which always return status and whether it understood the command or not. However there are still some cases where using this versioning is useful - an example it the addition of the requestinfo/replyinfo commands - the client wants to wait for acknowledge of all the replyinfo commands it has issued before sending the addme command. However, if the server doesn 't understand these options, the client will never get a response. With the versioning, the client can look at the version and know if it should wait for a response or if the server will never send back. setup ^^^^^ C->S, S->C:setup< option1 >< value1 >< option2 >< value2 > ... Sent by the client to request protocol option changes. This can be at any point during the life of a connection, but usually sent at least once right after the<< _version > > command. The server responds with a message in the same format confirming what configuration options were set. The server only sends a setup command in response to one from the client. The sc_version should be updated in the server if commands have been obsoleted such that old clients may not be able to play. option::word, name of configuration option value::word, value of configuration option. May need further parsing according to the setup options below=====Setup Options There are really 2 set of setup commands here:. Those that control preferences of the client(how big is the map, what faceset to use, etc). . Those that describe capabilities of the client(client supports this protocol command or that) .Setup Options[options="autowidth,header"]|===========================|Command|Description|beat|Ask the server to enable heartbeat support. When heartbeat is enabled, the client must send the server a command every three seconds. If no commands need to be sent, use the `beat` no-op command. Clients that do not contact the server within the interval are assumed to have a temporary connection failure.|bot(0/1 value)|If set to 1, the client will not be considered a player when updating information to the metaserver. This is to avoid having a server with many bots appear more crowded than others.|darkness(0/1 value)|If set to 1(default), the server will send darkness information in the map protocol commands. If 0, the server will not include darkness, thus saving a minor amount of bandwidth. Since the client is free to ignore the darkness information, this does not allow the client to cheat. In the case of the old 'map' protocol command, turning darkness off will result in the masking faces not getting sent to the client.|extended_stats(0/1 value)|If set to 1, the server will send the CS_STAT_RACE_xxx and CS_STAT_BASE_xxx values too, so the client can display various status related to statistics. Default is 0.|facecache(0/1)|Determines if the client is caching images(1) or wants the images sent to it without caching them(0). Default is 0. This replaces the setfacemode command.|faceset(8 bit)|Faceset the client wishes to use. If the faceset is not valid, the server returns the faceset the client will be using(default 0).|loginmethod(8 bit)|Client sends this to server to note login support. This is basically used as a subset of the csversion/scversion to find out what level of login support the server and client support. Current defined values:0:no advanced support - only legacy login method 1:account based login(described more below) 2:new character creation support This list may grow - for example, advanced character creation could become a feature.|map2cmd:(1)|This indicates client support for the map2 protocol command. See the map2 protocol details above for the main differences. Obsolete:This is the only supported mode now, but many clients use it as a sanity check for protocol versions, so the server still replies. It doesn 't do anything with the data|mapsize(int x) X(int y)|Sets the map size to x X y. Note the spaces here are only for clarity - there should be no spaces when actually sent(it should be 11x11 or 25x25). The default map size unless changed is 11x11. The minimum map size the server will allow is 9x9(no technical reason this could be smaller, but I don 't think the game would be smaller). The maximum map size supported in the current protocol is 63x63. However, each server can have its maximum map size sent to most any value. If the client sends an invalid mapsize command or a mapsize of 0x0, the server will respond with a mapsize that is the maximum size the server supports. Thus, if the client wants to know the maximum map size, it can just do a 'mapsize 0x0' or 'mapsize' and it will get the maximum size back. The server will constrain the provided mapsize x &y to the configured minumum and maximums. For example, if the maximum map size is 25x25, the minimum map size is 9x9, and the client sends a 31x7 mapsize request, the mapsize will be set to 25x9 and the server will send back a mapsize 25x9 setup command. When the values are valid, the server will send back a mapsize XxY setup command. Note that this is from its parsed values, so it may not match stringwise with what the client sent, but will match 0 wise. For example, the client may send a 'mapsize 025X025' command, in which case the server will respond with a 'mapsize 25x25' command - the data is functionally the same. The server will send an updated map view when this command is sent.|notifications(int value)|Value indicating what notifications the client accepts. It is incremental, a value means "all notifications till this level". The following levels are supported:1:quest-related notifications("addquest" and "updquest") 2:knowledge-related notifications("addknowledge") 3:character status flags(overloaded, blind,...)|num_look_objects(int value)|The maximum number of objects shown in the ground view. If more objects are present, fake objects are created for selecting the previous/next group of items. Defaults to 50 if not set. The server may adjust the given value to a suitable one data
int GetInt_String(const unsigned char *data)
Basically does the reverse of SockList_AddInt, but on strings instead.
uint32_t count
Any numbers typed before a command.
#define FLAG_ANIMATE
The object looks at archetype for faces.
object * container
Current container being used.
void look_at_cmd(char *buf, int len, player *pl)
Client wants to look at some object.
void inscribe_scroll_cmd(char *buf, int len, player *pl)
void inventory(object *op, object *inv)
Prints object's inventory.
#define FLAG_UNPAID
Object hasn't been paid for yet.
uint32_t nrof
Number of objects.
socket_struct * socket
Socket information for this player.
void query_base_name(const object *op, int plural, char *buf, size_t size)
Query a short name for the item.
static unsigned int query_flags(const object *op)
This is a similar to query_name, but returns flags to be sended to client.
#define FLAG_NO_SKILL_IDENT
If set, item cannot be identified w/ a skill.
#define FLAG_CURSED
The object is cursed.
void examine(object *op, object *tmp)
Player examines some object.
int sack_can_hold(const object *pl, const object *sack, const object *op, uint32_t nrof)
Check if an item op can be put into a sack.
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
Contains the base information we use to make up a packet we want to send.
#define CUSTOM_NAME_FIELD
Key in an object for the player-assigned custom name.
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
#define MAX_LIGHT_RADII
Max radii for 'light' object, really large values allow objects that can slow down the game.
@ llevDebug
Only for debugging purposes.
void SockList_AddPrintf(SockList *sl, const char *format,...)
Adds a printf like formatted string.
#define FLAG_IDENTIFIED
Item is identifiable (e.g.
void put_object_in_sack(object *op, object *sack, object *tmp, uint32_t nrof)
Something tries to put an object into another.