/*
 * tngp/world.h
 *
 * Copyright (C) 2022 bzt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * @brief Game world related definitions
 *
 */

#define WORLD_MAXPRX 16
#define WORLD_NUMCRDS 10
#define WORLD_NUMCRON 16
#define WORLD_NUMALRT 16
#define WORLD_ATTRMAX 99999
#define WORLD_QTYMAX 99999
#define WORLD_STATEMAGIC    "TNG Saved Game\n"

/* for serialize and deserialize state calls */
enum { SERTYPE_CLIENT, SERTYPE_SERVER, SERTYPE_LOGIN };
#define SPRPERLYR 20
enum { SPR_UI, SPR_TILE, SPR_CHR, SPR_PRT, SPR_BG, SPR_NPC, SPR_SWR };
enum { COLOR_TABN, COLOR_TABI, COLOR_DLGT, COLOR_FG, COLOR_SEL, COLOR_BTNN, COLOR_BTNS, COLOR_BTNP, COLOR_BTNI, COLOR_CHAT,
    COLOR_TITLE, COLOR_TITSH, COLOR_MENUN, COLOR_MENUS, COLOR_MENUP, COLOR_MENUI, COLOR_MENUT, COLOR_GRFG, COLOR_GRBG,
    COLOR_CRD_HDR, COLOR_CRD_NAME, COLOR_LAST };
enum { FNT_TABN, FNT_TABI, FNT_DLGT, FNT_TXT, FNT_SEL, FNT_BTN, FNT_TITLE, FNT_MENU, FNT_INV, FNT_ALERT, FNT_CRD_HDR,
    FNT_CRD_NAME, FNT_LAST };
enum {
    E_PTR, E_CLK, E_NOALLOW, E_ACTION, E_LOADING,                                       /* cursors */
    E_CHK0, E_CHK1,                                                                     /* checkbox */
    E_OPTPREV, E_OPTPREVPRESS, E_OPTBG, E_OPTNEXT, E_OPTNEXTPRESS,                      /* option box */
    E_SLDL, E_SLDBTN, E_SLDBG, E_SLDR,                                                  /* slider */
    E_SCRL, E_SCRHBG, E_SCRR, E_SCRU, E_SCRVBG, E_SCRD, E_SCRBTN,                       /* scroll bars */
    E_WINNL, E_WINNBG, E_WINNR,                                                         /* normal window tab */
    E_WINIL, E_WINIBG, E_WINIR,                                                         /* inactive window tab */
    E_WINTL, E_WINTBG, E_WINTR,                                                         /* window top */
    E_WINML, E_WINBG, E_WINMR,                                                          /* window middle */
    E_WINBL, E_WINBBG, E_WINBR,                                                         /* window bottom */
    E_DLGNL, E_DLGNBG, E_DLGNR,                                                         /* dialog tab */
    E_DLGOL, E_DLGOBG, E_DLGOR,                                                         /* dialog option */
    E_DLGTL, E_DLGTBG, E_DLGTR,                                                         /* dialog top */
    E_DLGML, E_DLGBG, E_DLGMR,                                                          /* dialog middle */
    E_DLGBL, E_DLGBBG, E_DLGBR,                                                         /* dialog bottom */
    E_BTNNL, E_BTNNBG, E_BTNNR,                                                         /* normal button */
    E_BTNSL, E_BTNSBG, E_BTNSR,                                                         /* selected button */
    E_BTNPL, E_BTNPBG, E_BTNPR,                                                         /* pressed button */
    E_BTNIL, E_BTNIBG, E_BTNIR,                                                         /* inactive button */
    E_INPL, E_INPBG, E_INPR,                                                            /* chat input */
    E_APPICO,                                                                           /* application icon */
    E_LAST
};
enum { PAD_TABN, PAD_TABI, PAD_DLGT, PAD_V, PAD_H, PAD_BTNT, PAD_MENU, PAD_LAST };
enum { MENU_N, MENU_S, MENU_P, MENU_I, MENU_T, MENU_LAST };
enum { EATTR_LIGHT, EATTR_WEIGHT, EATTR_SPEED, EATTR_LEVELUP };
enum { ALERT_QSTNEW, ALERT_QSTCOMP, ALERT_QSTFAIL };
enum { ATTR_PRI, ATTR_CHRVAR, ATTR_CHRCALC, ATTR_GLOBVAR, ATTR_GLOBCALC };
enum { REL_EQ, REL_NE, REL_GE, REL_GT, REL_LE, REL_LT, REL_SET = 0xff };
enum { CSPR_IDLE, CSPR_WALK, CSPR_CLIMB, CSPR_JUMP, CSPR_RUN, CSPR_SWIM, CSPR_FLY, CSPR_BLOCK, CSPR_HURT, CSPR_DIE, CSPR_ACTION };
enum { DIR_SO, DIR_SW, DIR_WE, DIR_NW, DIR_NO, DIR_NE, DIR_EA, DIR_SE };
enum { EVT_ONCLICK, EVT_ONTOUCH, EVT_ONLEAVE, EVT_ONAPPROACH, EVT_ONACTION1, EVT_ONACTION2, EVT_ONACTION3, EVT_ONACTION4,
    EVT_ONACTION5, EVT_ONACTION6, EVT_ONACTION7, EVT_ONACTION8, EVT_ONACTION9, EVT_ONUSING1, EVT_ONUSING2, EVT_ONUSING3,
    EVT_ONTIMER, EVT_ONSELL, EVT_ONBUY };
enum { MAPS_LYR_GRD1, MAPS_LYR_GRD2, MAPS_LYR_GRD3, MAPS_LYR_GRD4,
    MAPS_LYR_OBJECTS, MAPS_LYR_NPCS, MAPS_LYR_SPWN,
    MAPS_LYR_ROOF1, MAPS_LYR_ROOF2, MAPS_LYR_ROOF3, MAPS_LYR_ROOF4,
    MAPS_LYR_NUM };
enum { MAP_NW, MAP_N, MAP_NE, MAP_W, MAP_MAIN, MAP_E, MAP_SW, MAP_S, MAP_SE };
enum { ENG_LIGHT, ENG_WEIGHT, ENG_SPEED, ENG_LVLUP };

enum {
    GAME_TITLE,
    GAME_LOADGAME,
    GAME_NEWGAME,
    GAME_CONFIG,
    GAME_EXIT,
    GAME_CHARGEN,
    GAME_USERNAME,
    GAME_PASSWORD,
    GAME_REMAIN,
    GAME_CREATE,
    GAME_BACK,
    GAME_EXISTS,
    GAME_OKAY,
    GAME_SAVEDGAMES,
    GAME_LOAD,
    GAME_LOGTOSERVER,
    GAME_LOGIN,
    GAME_BADUSER,
    GAME_CHAT,
    GAME_SAVE,
    GAME_MENU,
    GAME_INV,
    GAME_SKILLS,
    GAME_QUESTS,
    GAME_SELL,
    GAME_BUY,
    GAME_NOMODIFY,
    GAME_REQUIRES,
    GAME_PROVIDES,
    GAME_AMMO,
    GAME_CRD_GAME,
    GAME_CRD_ART,
    GAME_CRD_DESIGN,
    GAME_CRD_ANIMS,
    GAME_CRD_FONTS,
    GAME_CRD_MUSIC,
    GAME_CRD_SOUND,
    GAME_CRD_VOICE,
    GAME_CRD_TR,
    GAME_CRD_PROG
};

typedef struct {
    FILE *f[3];                             /* file descriptors */
    uint64_t offs[3];                       /* current offsets */
    char *sts;                              /* strings */
    char encrypted;                         /* boolean */
    int ofs[8];                             /* index offsets */
    int stslen;                             /* length of string section */
} world_tng_t;

typedef struct {
    char id[3];                             /* ISO language code */
    int tng;                                /* which tng stores this translation */
    uint64_t offs;                          /* dictionary offset */
    uint32_t size;                          /* dictionary size */
    tng_asset_desc_t *spcassets;            /* array of speech assets */
} world_langopt_t;

typedef struct {
    int tng;                                /* which tng stores this asset */
    uint64_t offs;                          /* asset offset */
    uint32_t size;                          /* asset (compressed) size in file */
    char *name;                             /* name, pointer into sts, do not free */
} world_asset_t;

typedef struct {
    int atlasid;                            /* sprite atlas id */
    int x;                                  /* position on atlas */
    int y;
    int w;                                  /* size on atlas */
    int h;
    int l;                                  /* left margin */
    int t;                                  /* top margin */
    uint8_t op;                             /* operator */
} world_sprmap_t;

typedef struct {
    int w, h, f, t;                         /* width, height, number of frames, playback type */
    world_sprmap_t *data;                   /* frame descriptors (select area on atlas) */
} world_sprite_t;

typedef struct {
    uint8_t style;                          /* bold or italic bitmask */
    uint8_t size;                           /* 8 .. 192 */
    int fnt;                                /* font index */
} world_font_t;

typedef struct {
    int cat, idx;                           /* sprite category and index */
} world_spridx_t;

typedef struct {
    uint8_t type;                           /* relation type */
    int attr;                               /* attribute index */
    int value;                              /* attribute value */
} world_charattr_t;

typedef struct {
    int qty;                                /* quantity */
    world_spridx_t obj;                     /* object */
} world_inv_t;

typedef struct {
    int name;                               /* translatable name, text index */
    int desc;                               /* translatable description, text index */
    int na, ni, ns;                         /* number of attributes, inventory items, sprites */
    world_charattr_t *atr;                  /* attributes */
    world_inv_t *inv;                       /* starter inventory items */
    world_spridx_t *spr;                    /* sprites */
} world_charopt_t;

typedef struct {
    char *name;                             /* name, pointer into sts, do not free */
    int trname;                             /* translatable name, text index */
    int numopts;                            /* number of options in this group */
    world_spridx_t pal;                     /* palette sprite */
    world_charopt_t *opts;                  /* options */
} world_chargrp_t;

typedef struct {
    int16_t dx, dy;                         /* delta values */
    int t;                                  /* time interval */
    world_spridx_t spr;                     /* sprite */
} world_menuprx_t;

typedef struct {
    world_spridx_t l, m, r;                 /* left, middle, right sprites */
} world_menu_t;

typedef struct {
    uint8_t type;                           /* progressbar type */
    int l, t, valueattr, maxattr;           /* left, top, attribute to represent */
    world_spridx_t fg, bg;                  /* sprites */
    int y, w, h;                            /* used by hud */
} world_pbar_t;

typedef struct {
    uint8_t type;                           /* attribute type */
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    int defval;                             /* default value */
    int idx;                                /* index to world.globals or character specific attribute array */
    int bclen;                              /* bytecode length */
    uint8_t *bc;                            /* bytecode */
    int tng;                                /* expansion set reference for the bytecode */
} world_attr_t;

typedef struct {
    uint32_t color;                         /* text color */
    int snd;                                /* sound effect */
    int trname;                             /* translated name */
} world_alert_t;

typedef struct {
    int num;                                /* number of names */
    char **names;                           /* names */
} world_crd_t;

typedef struct {
    uint8_t type;                           /* chooser option type, stack */
    uint8_t keep;                           /* keep chooser running */
    union {
        struct { int x1, y1, x2, y2; } coord;   /* for type 13 */
        struct { world_spridx_t n, s, p; } spr; /* for the other types */
    } data;
    world_charattr_t req1;                  /* required attribute1 */
    world_charattr_t req2;                  /* required attribute2 */
    world_charattr_t prov;                  /* provided attribute */
    SDL_Rect dst;                           /* position on screen */
} world_chropt_t;

typedef struct {
    char *name;                             /* internal name */
    int l, t, h, v;                         /* left, top margins, horizontal, vertical paddings */
    int numopts;                            /* number of chooser options */
    world_chropt_t *opts;                   /* chooser options */
} world_chooser_t;

typedef struct {
    uint32_t s, e;                          /* start end in hsec */
    uint32_t fi, fo;                        /* fade in, fade out in hsec */
    uint32_t color;                         /* one fill color */
    world_spridx_t spr;                     /* slideshow image */
} world_slide_t;

typedef struct {
    uint32_t s;                             /* start in hsec */
    int spc;                                /* speech recording */
} world_speech_t;

typedef struct {
    uint32_t s, e;                          /* start end in hsec */
    uint32_t fi, fo;                        /* fade in, fade out in hsec */
    int x, y, a;                            /* subtitle position and alignment */
    uint32_t color;                         /* color */
    world_font_t fnt;                       /* font */
    int txt;                                /* translated subtitle text */
} world_sub_t;

typedef struct {
    char *name;                             /* internal name */
    int pomov, pomus, plmov, plmus;         /* play one movie and music, play in a loop movie and music */
    int numimg;                             /* number of slides */
    world_slide_t *img;                     /* slides */
    int numspc;                             /* number of speech records */
    world_speech_t *spc;                    /* speech records */
    int numsub;                             /* number of subtitles */
    world_sub_t *sub;                       /* subtitles */
    int bclen;                              /* bytecode length */
    uint8_t *bc;                            /* bytecode */
    int tng;                                /* expansion set reference for the bytecode */
} world_cutscn_t;

typedef struct {
    int chance;                             /* chance in percentage */
    int freq;                               /* resupply frequency in hsec */
    int qty;                                /* quantity */
    world_spridx_t obj;                     /* object */
} world_npcinv_t;

typedef struct {
    uint8_t type;                           /* event handler type (0..16, for NPCs 0..18) */
    int param;                              /* event handler paramerer */
    int bclen;                              /* bytecode length */
    uint8_t *bc;                            /* bytecode */
    int tng;                                /* expansion set reference for the bytecode */
} world_evthandler_t;

typedef struct {
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    uint8_t behave;                         /* default behaviour */
    int speed;                              /* speed percentage */
    int dirchange;                          /* direction change freq in hsec */
    char patrol;                            /* patrol path id */
    int numattrs;                           /* number of default attributes */
    world_charattr_t *attrs;                /* attributes */
    int numinv;                             /* number of default inventory items */
    world_npcinv_t *inv;                    /* default inventory */
    int numspr;                             /* number of animation sprites */
    world_spridx_t *spr;                    /* animation sprites */
    int numevt;                             /* number of event handlers */
    world_evthandler_t *evt;                /* event handlers */
} world_npctype_t;

typedef struct {
    world_charattr_t req;                   /* required player attribute */
    int attr;                               /* provided NPC attribute */
    int value;                              /* provided value */
    world_spridx_t swn;                     /* spawning animation sprite */
    world_spridx_t npc;                     /* NPC type sprite */
} world_npckind_t;

typedef struct {
    char *name;                             /* internal name */
    int num;                                /* number of NPCs this spawner spawns */
    int curr;                               /* number of currently spawned NPCs */
    int freq;                               /* respawn frequency in 1/100th sec */
    int numkinds;                           /* number of NPC kinds */
    world_npckind_t *kinds;                 /* kind of NPCs to spawn */
} world_spawner_t;

typedef struct {
    int name;                               /* translated option name (to match with world_charopt_t) */
    world_spridx_t spr[2 * SPRPERLYR];      /* sprites, 0..19 behind sprite per action + portrait, 20..39 above */
} world_sprmod_t;

typedef struct {
    int trname;                             /* translated name */
    int collw, collh;                       /* collision mask size */
    uint8_t *coll;                          /* collision mask */
    uint8_t defact;                         /* default action group (0xff - none) */
    world_spridx_t invspr;                  /* in inventory sprite */
    int invsnd;                             /* inventory placement sound */
    int price;                              /* base price */
    world_spridx_t unit;                    /* price unit */
    uint8_t pricecat;                       /* price category, freely choosable */
    world_spridx_t prjspr;                  /* projectile sprite */
    int prjdur;                             /* projectile animation duration */
    world_spridx_t ammo;                    /* projectile ammo object */
    uint8_t layer;                          /* sprite layering order */
    uint32_t eqmask;                        /* equipment position bitmask (0xffffffff skill) */
    world_spridx_t eqspr[32];               /* when equipted sprites */
    int numsnd;                             /* number of sound effects */
    int *snd;                               /* sound effects */
    int numreq;                             /* number of required attributes to equip */
    world_charattr_t *req;                  /* required attributes */
    int nummod;                             /* number of attribute modifiers when equipped */
    world_charattr_t *mod;                  /* attribute modifiers */
    int numspr;                             /* number of character option modifiers */
    world_sprmod_t *spr;                    /* character option sprite modifiers */
    int numevt;                             /* number of event handlers */
    world_evthandler_t *evt;                /* event handlers */
} world_object_t;

typedef struct {
    world_charattr_t req;                   /* required attribute */
    int attr;                               /* provided attribute */
    int value;                              /* provided value */
    int spc;                                /* spoken answer */
    int trname;                             /* text answer */
} world_answer_t;

typedef struct {
    uint8_t type;                           /* dialog type (1: portrait on left) */
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    int desc;                               /* translated description */
    int spc;                                /* spoken description */
    world_spridx_t spr;                     /* dialog portrait sprite */
    int numanswers;                         /* number of answers */
    world_answer_t *answers;                /* answer options */
} world_dialog_t;

typedef struct {
    int qty;                                /* produced quantity */
    world_spridx_t obj;                     /* produced object sprite id */
    world_inv_t ing[16];                    /* ingredients, 16 * (qty, object id) pairs */
} world_recipie_t;

typedef struct {
    uint8_t type;                           /* craft type (1: ingredient order irrelevant) */
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    int desc;                               /* translated description */
    int snd;                                /* sound effect */
    world_spridx_t spr;                     /* dialog portrait sprite */
    int numrecipies;                        /* number of recipies */
    world_recipie_t *recipies;              /* recipies */
} world_craft_t;

typedef struct {
    int speed;                              /* tile speed modifier (percentage) */
    int snd;                                /* tile on walk sound effect */
} world_tile_t;

typedef struct {
    uint8_t type;                           /* quest type */
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    int desc;                               /* translated description */
    int completed;                          /* the player who completed the quest */
    int bclen;                              /* bytecode length */
    uint8_t *bc;                            /* bytecode */
    int tng;                                /* expansion set reference for the bytecode */
} world_quest_t;

typedef struct {
    uint8_t type;                           /* parallax type (0: foreground, 1: background) */
    int8_t sx, dx, sy, dy;                  /* speed and delta values */
    int t;                                  /* time interval */
    world_spridx_t spr;                     /* sprite */
    int x, y;                               /* not stored, only used by game_parallax */
    uint32_t last;                          /* not stored, last update time */
} world_mapprx_t;

typedef struct {
    int id;                                 /* internal id */
    char *name;                             /* internal name */
    int trname;                             /* translated name */
    int neightbors[6];                      /* neightboring maps (see map_maps in map.c) */
    int daylen;                             /* daytime length in minutes */
    world_spridx_t dayspr;                  /* ambient light sprite */
    int bgmus;                              /* background music index */
    int numprx;                             /* number of parallaxes */
    world_mapprx_t *prx;                    /* parallaxes */
    int numpaths;                           /* number of patrol paths */
    uint16_t **paths;                       /* patrol paths, 0: id, 1: len, 2: x1, 3: y1, 4: x2, 5: y2... */
    uint16_t *tiles;                        /* numlayer * mapsize * mapsize, sprite indeces with fixed category */
    uint8_t *coll;                          /* collision mask layer */
} world_map_t;

typedef struct {
    int value;                              /* re-run interval in 1/100 sec or range attribute index */
    int bclen;                              /* bytecode length */
    uint8_t *bc;                            /* bytecode */
    int tng;                                /* expansion set reference for the bytecode */
} world_script_t;

/* common to players and NPCs */
typedef struct {
    int map, x, y;                          /* position on map and direction */
    uint8_t d, behave, transport;           /* direction, current behaviour, transportation method */
    char altitude;                          /* altitude */
    int *attrs;                             /* character specific attributes */
    int numinv;                             /* number of inventory items */
    world_inv_t *inv;                       /* inventory */
    int numskl;                             /* number of skills */
    world_inv_t *skills;                    /* skill list */
    int numqst;                             /* number of quests */
    int *quests;                            /* quest list */
} world_entity_t;

/* players only */
typedef struct {
    char *name;                             /* user name */
    uint8_t pass[32];                       /* password hash (or zero, if user added, but not registered) */
    uint64_t created, logind, logoutd, lastd;/* dates in UNIX timestamp */
    int *opts;                              /* character option values and palette indeces */
    uint16_t equip[32];                     /* equipted object sprites */
    uint16_t belt[32];                      /* items on belt */
    world_entity_t data;
#ifdef NETQ_H                               /* --- networking stuff --- */
    uint8_t banned, lang[2];                /* banned flag, altitude and language code */
    uint8_t fam, remote_ip[16];             /* remote address (family and ip) */
    uint16_t remote_port;                   /* remote port (both address and port are in network byte order) */
    uint8_t mask[264];                      /* encryption mask */
    netq_t nq;                              /* simple network queue */
#endif
} world_player_t;

/* NPC only */
typedef struct {
    int type;                               /* NPC type */
    int spawner;                            /* spawner reference */
    world_entity_t data;
    int numcmd;                             /* number of movement commands in queue */
} world_npc_t;

/* players, other clients (multiplayer only) */
typedef struct {
    int idx;                                /* internal id on server */
    int next;                               /* next client on the same tile */
    char *name;                             /* user name */
    uint32_t lastd;                         /* last updated */
    int *opts;                              /* character option values and palette indeces */
    uint16_t equip[32];                     /* equipted object sprites */
    world_entity_t data;
} world_client_t;

typedef struct {
    world_map_t *maps[9];                   /* maps */
    int cx, cy;                             /* displayed with centre at */
    int tx, ty;                             /* target centre */
    uint32_t d;                             /* daytime */
    int numnpc;                             /* number of npcs */
    world_npc_t *npc;                       /* npcs */
    int numplrs;                            /* number of players on scene */
    world_client_t *plrs;                   /* other player clients */
    int *list;                              /* list of entities per tile */
    int numprx;                             /* number of parallaxes */
    SDL_Texture **prx;                      /* parallax textures */
    SDL_Point *prxdst;                      /* parallax size */
} world_scene_t;

typedef struct {
    /* common */
    tng_hdr_t hdr;
    uint64_t asiz;
    int gpl, noreg, type, tilew, tileh, mapsize, numngh;
    int numtng, numlang, numtext, numspc, numfont, nummusic, numsound, nummovie, numchr, numcut, numchar, numnpc, numswr;
    int numdlg, numcft, numqst, nummap, numatl, numspr[5], langidx;
    world_tng_t *tng;
    world_langopt_t *lang;
    char **langname, *textbuf, **text;
    world_asset_t *speech, *font, *music, *sound, *movie, *map, *atl, *bg;
    world_chargrp_t *chars;
    world_sprite_t *spr[5];
    /* UI elements */
    uint32_t colors[COLOR_LAST];
    world_font_t fonts[FNT_LAST];
    int16_t padtop[PAD_LAST];
    int onselsnd, onclksnd, onerrsnd;
    world_spridx_t uispr[E_LAST];
    /* main menu */
    int intro, hasmenu, hastitle, bgmusic, bgmovie;
    char *url;
    world_spridx_t bgimage, titimg;
    world_menuprx_t menuprx[WORLD_MAXPRX];
    world_menu_t menubtn[MENU_LAST];
    /* HUD */
    world_spridx_t navcirc, navbtns, itembarbg, itembarfg, statusbarbg, statusbarfg, invicon, inviconp, invslot, invslots;
    world_spridx_t equipimg;
    uint8_t item_n, item_w, item_h, item_l, item_t, item_g, item_p, item_c, inv_w, inv_h, inv_l, inv_t;
    uint16_t equippos[64];
    int numpbar;
    world_pbar_t *pbars;
    /* alerts */
    int alert_dt, alert_fi, alert_fo, numalr;
    world_alert_t alerts[WORLD_NUMALRT];
    /* credits */
    int crdmusic;
    world_spridx_t crdimage;
    world_crd_t crds[WORLD_NUMCRDS];
    /* startup and timer scripts */
    world_script_t cron[WORLD_NUMCRON];
    /* attributes */
    int freetotal, freeattrs, engattr[4], numattrs, numpris, numchrattrs, numglobals, *globals;
    world_attr_t *attrs;
    /* default actions */
    world_script_t defact[9];
    /* route choosers */
    world_chooser_t *choosers;
    /* cutscenes */
    world_cutscn_t *cutscns;
    /* NPC types */
    world_npctype_t *npctypes;
    /* NPC spawners */
    world_spawner_t *spawners;
    /* tiles meta */
    world_tile_t **tiles;
    /* objects meta */
    world_object_t **objects;
    /* conversational dialogs */
    world_dialog_t *dialogs;
    /* crafting dialogs */
    world_craft_t *crafts;
    /* quests */
    world_quest_t *quests;
    /* map neightbors (server only) */
    int *mapngh;

    /*** dynamic resources ***/
    int numdenylist;
    uint8_t *denylist;
    int numplayers;
    world_player_t *players;
    int numnpcs;
    world_npc_t *npcs;
    /* modified objects layers */
    uint16_t **objlyr;
} world_t;

extern world_t world;

void world_seektng(int idx, int strm, uint64_t offs);
int  world_readtng(int idx, int strm, void *buff, int len);
int  world_eofasset(int strm, world_asset_t *asset);
int  world_loadtng(char *fn);
void world_loadtext(int lng);
int  world_load(char *fn);
void world_init(char *detlng);
void world_free();
void world_freemap(world_map_t *map);
void world_loadneightbors();
int  world_serializeinv(int idx, uint8_t *buf, int maxlen);
uint8_t *world_serializemap(world_map_t *map, int *len);
world_map_t *world_deserializemap(uint8_t *buf, int len, int idx);
world_map_t *world_loadmap(int id);
uint8_t *world_getmap(int id, int *len);
void world_flush();
void world_playerdel(int idx);
int  world_playercleanup(uint64_t t);
void world_hashpass(char *pass, uint8_t *hash);
int  world_register(char *user, uint8_t *pass, int *opts, int *attrs);
char *world_parsestr(char *str, char *user, int *attrs);
uint8_t *world_serializestate(int type, int useridx, int *len);
int  world_savestate(char *fn, uint8_t *prvw, int plen, uint32_t playedsec);
int  world_deserializestate(uint8_t *comp, int size);
int  world_loadstate(char *fn);
void world_quest(world_entity_t *ent, int idx, int complete, int script);
int  world_item(int plr, int dqty, int idx);
