obj_num
room_num struct obj_flag_data struct obj_affected_type char char char char struct extra_descr_data struct char_data struct char_data sh_int struct obj_data struct obj_data struct obj_data struct obj_data byte byte |
item_number;
in_room; obj_flags; affected[MAX_OBJ_AFFECT]; *name; *description; *short_description; *action_description; *ex_description; *carried_by; *worn_by; worn_on; *in_obj; *contains; *next_content; *next; obj_level; condition; |
/* Where in data-base */
/* In what room -1 when conta/carr */ /* Object information*/ /* affects */ /* Title of object :get etc.*/ /* When in room */ /* when worn/carry/in cont.*/ /* What to write when used */ /* extra descriptions */ /* Carried by :NULL in room/conta */ /* Worn by? */ /* Worn where? */ /* In what object NULL when none */ /* Contains objects */ /* For 'contains' lists */ /* For the object list */ /* For leveling objects */ |
struct room_data
{
room_num
sh_int int char char struct extra_descr_data struct room_direction_data int byte struct obj_data
|
number;
zone; sector_type; *name; *description; *ex_description; *dir_option[NUM_OF_DIRS]; room_flags; light; SPECIAL(*func); *contents; *people; |
/* Rooms number (vnum)*/
/* Room zone (for resetting) */ /* sector type (move/hide) */ /* Rooms name 'You are ...' */ /* Shown when entered */ /* for examine/look */ /* Directions */ /* DEATH,DARK ... etc */ /* Number of lightsources in room */ /* List of items in room */
|
struct char_data
{
int
sh_int room_num room_num struct char_player_data struct char_ability_data struct char_ability_data struct char_spec_ability_data struct char_point_data struct char_special_data struct player_special_data struct mob_special_data struct affected_type struct obj_data struct obj_data struct descriptor_data struct char_data struct char_data struct char_data struct follow_type struct char_data struct comm_mess struct comm_mess struct comm_mess struct comm_mess |
pfilepos;
nr; in_room; was_in_room; player; real_abils; aff_abils; spec_abils; points; char_specials; *player_specials; mob_specials; *affected; *equipment[NUM_WEARS]; *carrying; *desc; *next_in_room; *next; *next_fighting; *followers; *master; *gossip_mem; *tell_mem; *gsay_mem; *wnet_mem; |
/* playerfile pos */
/* Mob's rnum */ /* Location (real room number) */ /* location for linkdead people */ /* Normal data */ /* Abilities without modifiers */ /* Abils with spells/stones/etc */ /* XXX - Ghwerigova tajna znacka...*/ /* Points */ /* PC/NPC specials */ /* PC specials */ /* NPC specials */ /* affected by what spells */ /* Equipment array */ /* Head of list */ /* NULL for mobiles */ /* For room->people - list */ /* For either monster or ppl-list */ /* For fighting list */ /* List of chars followers */ /* Who is char following? */
|
#define SPECIAL(name)
int (name)(struct char_data *ch, void *me, int cmd, char *argument)
#define ACMD(name)
void (name)(struct char_data *ch, char *argument, int cmd, int subcmd)
#define CMD_IS(cmd_name) (!strcmp(cmd_name, cmd_info[cmd].command))
#define ASPELL(spellname) void spellname(int level,
struct char_data *ch, struct char_data *victim, struct obj_data *obj)
#define LVL_IMPL 47
#define LVL_GRGOD 46
#define LVL_GOD 45
#define LVL_IMMORT 44
#define LVL_GOVERNOR 43
#define LVL_RULER 42
#define LVL_LORD 41
#define PULSE_ZONE (10 RL_SEC)
#define PULSE_MOBILE (10 RL_SEC)
#define PULSE_VIOLENCE (2 RL_SEC)
#define MAX_STRING_LENGTH 8192 * 8 /* Enlarged
by Ghwerig */
#define MAX_INPUT_LENGTH 256 /* Max
length per *line* of input */
#define MAX_RAW_INPUT_LENGTH 512 /* Max size of
*raw* input */
char
char char int int int void int void void void void void void struct char_data struct char_data struct char_data struct obj_data struct obj_data struct obj_data int |
*one_argument(char *argument, char
*first_arg);
*any_one_arg(char *argument, char *first_arg); *two_arguments(char *argument, char *first_arg, char *second_arg); is_abbrev(char *arg1, char *arg2); is_number(char *str); call_magic(struct char_data *ch, struct char_data *vict, struct obj_data *obj, int spell, int lvl, int type); mag_objectmagic(struct char_data *ch, struct obj_data *obj, char *argument); cast_spell(struct char_data *ch, struct char_data *tch, struct obj_data *tobj, int spellnum); send_to_all(char *messg); send_to_char(char *messg, struct char_data *ch); send_to_room(char *messg, int room); send_to_other(char *messg,struct descriptor_data *d); send_to_outdoor(char *messg); act(char *str, int hide_invisible, struct char_data *ch, struct obj_data *obj, void *vict_obj, int type); *get_player_vis(struct char_data * ch, char *name, int inroom); *get_char_room_vis(struct char_data * ch, char *name); *get_char_vis(struct char_data * ch, char *name); *get_obj_in_list_vis(struct char_data * ch, char *name, *get_obj_vis(struct char_data * ch, char *name); *get_object_in_equip_vis(struct char_data * ch, generic_find(char *arg, int bitvect, struct char_data * ch, struct char_data ** tch, struct obj_data ** tobj |
send_to_char() je asi nejčastěji
používaná v kombinaci:
sprintf(buf,"Tohle je řetězec coby parametr %s a tohle je číslo cobz
parametr %d.",string,number);
send_to_char(buf,ch);
act() má spousty chytrých parametrů,
díky kterým umožňuje snadno řešit problémy anglické gramatiky, ale zároveň
je kvůli své univerzálnosti pomalejší, než obzčejné send_to_char(); Pokud
nepotřebujeme využít některou ze speciálních vlastností funkce act(), je
lepší použít send_to_char(), popř. v kombinaci se sprintf().
type:
|
control characters:
|
hide_invisible:
TRUE=>kdo chara nevidí, tomu se hláška nepošle |
$F používá pro tisk neco jako while(is_alpha(ptr)),
ale tiskne max. 30 pismen!
TO_SLEEP posílá řetězec i spící
postavě.
control characters s malým písmenem
($x) se vztahují na chara, s velkým písmenem ($X) se vztahují
na vict.
Poslání hlášky typu "Zlej_mob te praštil!" charovi:
sprintf(buf,"%s te praštil!\r\n",GET_NAME(zlej_mob));
send_to_char(buf,ch); //proměnná buf je GLOBÁLNÍ a je dostatečně dlouhá nebo pomocí act(), ale ten se hodí spíš pro gramatické problémy typu
his/her, protože jeho provedení zdržuje:
|
Posílání dlouhého výpisu (napr. locate xxx):
inicializujte si buffer pomocí sprintf(buf,"");
přidávejte kousky řetězce pomocí strcat(buf); a nakonec celý buffer vypište pomocí page_string(buf); |
Zjištění pointeru na room, kde stojí char:
world[ch->in_room] //samotne ch->in_room vraci vnum roomu |
Projetí všech lidí v roomu, kde stojí char:
for( vict=world[ch->in_room].people; vict ; vict=vict->next_in_room ) ... |
Projetí celého inv/eq chara:
for( obj=ch->carrying; obj; obj=obj->next ) ...
// pro inventář
for( i=0; i<NUM_WEARS; i++ ) obj=ch->equipment[i]; // pro equipment |
Zjištění všech přilogovaných hráčů, kteří jsou schopni vnimat ( tj. ne linkless/v OLC ):
for( d=descriptor_list ; d ; d=d->next )
{ if( !d->connected || (d->connected==CON_EDIT) || !d->character) continue; ... } |
Vypsání chybové hlášky immum a do logfilu:
mudlog("[SYSERR]: Stal se průšvih ve funkci foo()!",BRF,LVL_GOD,TRUE);
POZOR!!! Nepište na konci \r\n, mudlog to zařídí sám! |
Hazeni kostkou/číslo z intervalu:
dice(kolikrát_se_má_hodit,kolikastěnnou_kostkou);
number(interval_od,interval_do); |
Teleportace chara do roomu s vnumem XXX:
stop_fighting_at_room(ch,ch->in_room);
char_from_room(ch); char_to_room(ch,real_room(XXX)); // real_room() konvertuje VNUM->RNUM look_at_room(ch); |
Test ekvivalence řetězců:
if(!strcmp(buf,"správný řetězec"));
if(is_abbrev(buf,"správný řetězec")); // is_abbrev() je lepší, protože stačí zadat neúplný řetězec |
Testy na napsaný příkaz ve specprocech:
if(!cmd) ... // nebyl napsán žádný příkaz - volalo
se kvuli ticku
if(CMD_IS("command_name")) ... // byl napsán příkaz "command_name" - nutno zadat úplné znění řetězce (viz. interpreter.c) je to náš příkaz => otestujeme si argument(y): zbytek_argumentu=one_argument(argument,prvni_slovo);
(další slova argumentu jsou ukryta v promenne zbytek_argumentu, na kterou lze opet použít one_argument; pro 2 argumenty je lepší funkce two_arguments, což je makro, které dělá totéž, co one_argument(one_argument(arg,arg1),arg2);) POZOR NA DÉLKU BUFFERU PRO ARGUMENT!!!
|
Zjišťování pointeru na self ve specu:
(struct xxx_data *)me // kde xxx je bud char,
obj, nebo room
PŘETYPOVÁNÍ JE NUTNÉ - me je totiz void * |
Vraceni hodnoty ve specprocech:
return (TRUE);
Způsobí, že interpreter považuje vyhodnocení příkazu za hotové a sám už nehne ani prstem => příkaz je "požrán" specem - používá se JEN tehdy, když spec nahradí normalni efekt příkazu (jsou dokonce příkazy, které jsou určené jen pro použití ve specech, ty se poynaji podle toho, že při jiném použití házejí hlášku "You can't do that there." - to je efekt funkce ACMD(do_not_there);) POZOR!!! Vrácení omylem TRUE místo FALSE způsobí, že nebohému hráči, který napíše libovolný příkaz v dosahu specu, bude tento příkaz "vyhodnocen" specem, hráč bude fakticky "freeznut" a pomůže mu jen disconnect. (Ovšem po reconnectu se octne v naprosto stejné situaci.) Pokud se nemají na tuto "mucholapku" postupně chytit všichni hráči včetně GODů ihned po napsání 1.příkazu, je nutné MUD shodit, return value přepsat, překompilovat a znova MUD nahodit. *grin* (už se mi to stalo) return (FALSE);
Pokud potřebujete ve svém specu použít příkaz, který není v tabulce platných příkazů, je nutné ho do tabulky doplnit a jako funkci, která příkaz bežně obslouží uvést do_not_there. |
Zpět na hlavní stránku | Informace pro buildery | Informace pro hráče | Seznámení s Murphym |