Středověká kráskaTipy pro codery

Mramorová oddělovací lišta

 

Gotický ornament Nejdůležitější datové typy, makra a funkce:

struct obj_data
{
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
struct char_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 */
/* List of NPC / PC 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:
  • TO_ROOM
  • TO_VICT
  • TO_NOTVICT
  • TO_CHAR
  • TO_ALL
  • TO_SLEEP
  • control characters:
  • $n GET_NAME(ch)
  • $m GET_SEX(ch) => "him"/"her"/"it"
  • $s          -"-                 "his"/"her"/"its"
  • $o GET_NAME(obj) / "something"
  • $p obj->short_description / "something"
  • $a "an"/"a"
  • $T tiskne neform. řetězec vict_obj; nejde $t
  • $F tiskne 1.slovo řetězce vict_obj; nejde $f
  • $$ tiskne znak '$'
  • 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.
     

    Gotický ornament  Nejčastěji používané techniky:


    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:
    act("$N te prastil!",TRUE,ch,NULL, zlej_mob,TO_CHAR);

    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);
    if(is_abbrev(prvni_slovo,"slovo")) ... // 1.slovo argumentu sedí

    (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!!!
    krátký buffer => někdo může shodit MUD zadáním dlouheho argumentu => rezervujete radši MAX_INPUT_LENGTH

     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);
    Způsobí, že interpreter zkusí provést příkaz sám, tj. myslí si, že spec na tenhle příkaz nezareagoval. Nenajde-li příkaz ve své tabulce platných příkazů, hodí normální hlášku, že příkazu nerozumí. ("Huh?")

    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.

    Mramorová oddělovací lišta
     
     
    Zpět na hlavní stránku  Informace pro buildery Informace pro hráče Seznámení s Murphym