mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-27 06:36:33 +01:00
Update game to use TOML format for persistent data
This commit is contained in:
parent
18c92e2357
commit
2dcf2d7311
209 changed files with 12983 additions and 1982 deletions
|
|
@ -16,6 +16,8 @@ file(GLOB CIRCLE_SOURCES
|
|||
)
|
||||
|
||||
add_executable(circle ${CIRCLE_SOURCES})
|
||||
target_sources(circle PRIVATE ${CMAKE_SOURCE_DIR}/third_party/tomlc99/toml.c)
|
||||
target_include_directories(circle PRIVATE ${CMAKE_SOURCE_DIR}/third_party/tomlc99)
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(circle wsock32.lib)
|
||||
|
|
@ -23,4 +25,4 @@ if(MSVC)
|
|||
set_target_properties(circle PROPERTIES
|
||||
VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/.."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ PROFILE =
|
|||
|
||||
BINDIR = ../bin
|
||||
|
||||
CFLAGS = -g -O2 $(MYFLAGS) $(PROFILE)
|
||||
CFLAGS = -g -O2 $(MYFLAGS) $(PROFILE) -I../third_party/tomlc99
|
||||
|
||||
LIBS = -lcrypt
|
||||
|
||||
SRCFILES := $(shell ls *.c | sort)
|
||||
SRCFILES := $(shell ls *.c | sort) ../third_party/tomlc99/toml.c
|
||||
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
|
||||
|
||||
default: all
|
||||
|
|
@ -47,13 +47,14 @@ $%.o: %.c
|
|||
|
||||
clean:
|
||||
rm -f *.o depend
|
||||
rm -f ../third_party/tomlc99/toml.o
|
||||
rm -f ./tests/*.o depend
|
||||
|
||||
# Dependencies for the object files (automagically generated with
|
||||
# gcc -MM)
|
||||
|
||||
depend:
|
||||
$(CC) -MM *.c > depend
|
||||
$(CC) $(CFLAGS) -MM *.c > depend
|
||||
|
||||
-include depend
|
||||
|
||||
|
|
|
|||
|
|
@ -16,11 +16,11 @@ PROFILE =
|
|||
|
||||
BINDIR = ../bin
|
||||
|
||||
CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE)
|
||||
CFLAGS = @CFLAGS@ $(MYFLAGS) $(PROFILE) -I../third_party/tomlc99
|
||||
|
||||
LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
|
||||
|
||||
SRCFILES := $(shell ls *.c | sort)
|
||||
SRCFILES := $(shell ls *.c | sort) ../third_party/tomlc99/toml.c
|
||||
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
|
||||
|
||||
default: all
|
||||
|
|
@ -46,6 +46,7 @@ $%.o: %.c
|
|||
|
||||
clean:
|
||||
rm -f *.o depend
|
||||
rm -f ../third_party/tomlc99/toml.o
|
||||
rm -f ./tests/*.o depend
|
||||
|
||||
# Dependencies for the object files (automagically generated with
|
||||
|
|
|
|||
126
src/accounts.c
126
src/accounts.c
|
|
@ -12,6 +12,8 @@
|
|||
#include "utils.h"
|
||||
#include "db.h"
|
||||
#include "accounts.h"
|
||||
#include "toml.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
static void set_account_name(struct account_data *account, const char *name)
|
||||
{
|
||||
|
|
@ -28,6 +30,31 @@ static void set_account_name(struct account_data *account, const char *name)
|
|||
account->name = strdup(tmp);
|
||||
}
|
||||
|
||||
static char *toml_dup_string(toml_table_t *tab, const char *key)
|
||||
{
|
||||
toml_datum_t d = toml_string_in(tab, key);
|
||||
|
||||
if (!d.ok)
|
||||
return NULL;
|
||||
|
||||
return d.u.s;
|
||||
}
|
||||
|
||||
static void toml_set_account_pc_name(struct account_data *account, const char *value)
|
||||
{
|
||||
char tmp[MAX_INPUT_LENGTH];
|
||||
|
||||
if (!value || !*value)
|
||||
return;
|
||||
|
||||
strlcpy(tmp, value, sizeof(tmp));
|
||||
CAP(tmp);
|
||||
|
||||
if (account->pc_name)
|
||||
free(account->pc_name);
|
||||
account->pc_name = strdup(tmp);
|
||||
}
|
||||
|
||||
int account_has_pc(const struct account_data *account, const char *pc_name)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -77,9 +104,11 @@ struct account_data *account_load(const char *name)
|
|||
struct account_data *account;
|
||||
FILE *fl;
|
||||
char filename[PATH_MAX];
|
||||
char line[MAX_INPUT_LENGTH + 1];
|
||||
char tag[6];
|
||||
int i;
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_array_t *arr = NULL;
|
||||
char *value = NULL;
|
||||
int i, count;
|
||||
|
||||
if (!name || !*name)
|
||||
return NULL;
|
||||
|
|
@ -91,29 +120,55 @@ struct account_data *account_load(const char *name)
|
|||
if (!fl)
|
||||
return NULL;
|
||||
|
||||
tab = toml_parse_file(fl, errbuf, sizeof(errbuf));
|
||||
fclose(fl);
|
||||
if (!tab) {
|
||||
log("SYSERR: Couldn't parse account file %s: %s.", filename, errbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
account = account_create(NULL);
|
||||
|
||||
while (get_line(fl, line)) {
|
||||
tag_argument(line, tag);
|
||||
value = toml_dup_string(tab, "name");
|
||||
if (value) {
|
||||
set_account_name(account, value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "Name"))
|
||||
set_account_name(account, line);
|
||||
else if (!strcmp(tag, "Pass"))
|
||||
strlcpy(account->passwd, line, sizeof(account->passwd));
|
||||
else if (!strcmp(tag, "Mail")) {
|
||||
if (account->email)
|
||||
free(account->email);
|
||||
account->email = strdup(line);
|
||||
} else if (!strcmp(tag, "Char"))
|
||||
account_add_pc(account, line);
|
||||
else if (!strcmp(tag, "Curr")) {
|
||||
if (account->pc_name)
|
||||
free(account->pc_name);
|
||||
account->pc_name = strdup(line);
|
||||
value = toml_dup_string(tab, "password");
|
||||
if (value) {
|
||||
strlcpy(account->passwd, value, sizeof(account->passwd));
|
||||
free(value);
|
||||
}
|
||||
|
||||
value = toml_dup_string(tab, "email");
|
||||
if (value) {
|
||||
if (account->email)
|
||||
free(account->email);
|
||||
account->email = value;
|
||||
}
|
||||
|
||||
value = toml_dup_string(tab, "current_pc");
|
||||
if (value) {
|
||||
toml_set_account_pc_name(account, value);
|
||||
free(value);
|
||||
}
|
||||
|
||||
arr = toml_array_in(tab, "pcs");
|
||||
if (arr) {
|
||||
count = toml_array_nelem(arr);
|
||||
for (i = 0; i < count; i++) {
|
||||
toml_datum_t d = toml_string_at(arr, i);
|
||||
if (!d.ok) {
|
||||
log("SYSERR: Invalid account character entry %d in %s.", i, filename);
|
||||
continue;
|
||||
}
|
||||
account_add_pc(account, d.u.s);
|
||||
free(d.u.s);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fl);
|
||||
toml_free(tab);
|
||||
|
||||
if (!account->name)
|
||||
set_account_name(account, name);
|
||||
|
|
@ -151,14 +206,33 @@ int account_save(const struct account_data *account)
|
|||
return 0;
|
||||
}
|
||||
|
||||
fprintf(fl, "Name: %s\n", account->name);
|
||||
fprintf(fl, "Pass: %s\n", account->passwd);
|
||||
fprintf(fl, "name = ");
|
||||
toml_write_string(fl, account->name);
|
||||
fprintf(fl, "\n");
|
||||
fprintf(fl, "password = ");
|
||||
toml_write_string(fl, account->passwd);
|
||||
fprintf(fl, "\n");
|
||||
if (account->email && *account->email)
|
||||
fprintf(fl, "Mail: %s\n", account->email);
|
||||
{
|
||||
fprintf(fl, "email = ");
|
||||
toml_write_string(fl, account->email);
|
||||
fprintf(fl, "\n");
|
||||
}
|
||||
if (account->pc_name && *account->pc_name)
|
||||
fprintf(fl, "Curr: %s\n", account->pc_name);
|
||||
for (i = 0; i < account->pc_count; i++)
|
||||
fprintf(fl, "Char: %s\n", account->pc_list[i]);
|
||||
{
|
||||
fprintf(fl, "current_pc = ");
|
||||
toml_write_string(fl, account->pc_name);
|
||||
fprintf(fl, "\n");
|
||||
}
|
||||
if (account->pc_count > 0) {
|
||||
fprintf(fl, "pcs = [\n");
|
||||
for (i = 0; i < account->pc_count; i++) {
|
||||
fprintf(fl, " ");
|
||||
toml_write_string(fl, account->pc_list[i]);
|
||||
fprintf(fl, "%s\n", (i + 1 < account->pc_count) ? "," : "");
|
||||
}
|
||||
fprintf(fl, "]\n");
|
||||
}
|
||||
|
||||
fclose(fl);
|
||||
return 1;
|
||||
|
|
|
|||
12
src/db.h
12
src/db.h
|
|
@ -54,11 +54,11 @@
|
|||
#error "Unknown path components."
|
||||
#endif
|
||||
|
||||
#define SUF_OBJS "objs"
|
||||
#define SUF_OBJS "objs.toml"
|
||||
#define SUF_TEXT "text"
|
||||
#define SUF_MEM "mem"
|
||||
#define SUF_PLR "plr"
|
||||
#define SUF_ACCT "acc"
|
||||
#define SUF_MEM "mem.toml"
|
||||
#define SUF_PLR "plr.toml"
|
||||
#define SUF_ACCT "acc.toml"
|
||||
|
||||
#if defined(CIRCLE_AMIGA)
|
||||
#define EXE_FILE "/bin/circle" /* maybe use argv[0] but it's not reliable */
|
||||
|
|
@ -77,8 +77,8 @@
|
|||
#endif
|
||||
|
||||
/* names of various files and directories */
|
||||
#define INDEX_FILE "index" /* index of world files */
|
||||
#define MINDEX_FILE "index.mini" /* ... and for mini-mud-mode */
|
||||
#define INDEX_FILE "index.toml" /* index of world files */
|
||||
#define MINDEX_FILE "index.mini.toml" /* ... and for mini-mud-mode */
|
||||
#define WLD_PREFIX LIB_WORLD"wld"SLASH /* room definitions */
|
||||
#define MOB_PREFIX LIB_WORLD"mob"SLASH /* monster prototypes */
|
||||
#define OBJ_PREFIX LIB_WORLD"obj"SLASH /* object prototypes */
|
||||
|
|
|
|||
18
src/dg_olc.c
18
src/dg_olc.c
|
|
@ -113,6 +113,7 @@ ACMD(do_oasis_trigedit)
|
|||
void script_save_to_disk(FILE *fp, void *item, int type)
|
||||
{
|
||||
struct trig_proto_list *t;
|
||||
int first = 1;
|
||||
|
||||
if (type==MOB_TRIGGER)
|
||||
t = ((struct char_data *)item)->proto_script;
|
||||
|
|
@ -125,11 +126,18 @@ void script_save_to_disk(FILE *fp, void *item, int type)
|
|||
return;
|
||||
}
|
||||
|
||||
while (t)
|
||||
{
|
||||
fprintf(fp,"T %d\n", t->vnum);
|
||||
if (!t)
|
||||
return;
|
||||
|
||||
fprintf(fp, "triggers = [");
|
||||
while (t) {
|
||||
if (!first)
|
||||
fputs(", ", fp);
|
||||
fprintf(fp, "%d", t->vnum);
|
||||
first = 0;
|
||||
t = t->next;
|
||||
}
|
||||
fputs("]\n", fp);
|
||||
}
|
||||
|
||||
static void trigedit_setup_new(struct descriptor_data *d)
|
||||
|
|
@ -852,9 +860,9 @@ void trigedit_save(struct descriptor_data *d)
|
|||
fclose(trig_file);
|
||||
|
||||
#ifdef CIRCLE_MAC
|
||||
snprintf(buf, sizeof(buf), "%s:%d.trg", TRG_PREFIX, zone);
|
||||
snprintf(buf, sizeof(buf), "%s:%d.toml", TRG_PREFIX, zone);
|
||||
#else
|
||||
snprintf(buf, sizeof(buf), "%s/%d.trg", TRG_PREFIX, zone);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", TRG_PREFIX, zone);
|
||||
#endif
|
||||
|
||||
remove(buf);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "genzon.h" /* for real_zone_by_thing */
|
||||
#include "act.h"
|
||||
#include "modify.h"
|
||||
#include "toml.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
#define PULSES_PER_MUD_HOUR (SECS_PER_MUD_HOUR*PASSES_PER_SEC)
|
||||
|
||||
|
|
@ -2826,11 +2828,11 @@ static struct cmdlist_element *find_done(struct cmdlist_element *cl)
|
|||
void read_saved_vars(struct char_data *ch)
|
||||
{
|
||||
FILE *file;
|
||||
long context;
|
||||
char fn[127];
|
||||
char input_line[1024], *temp, *p;
|
||||
char varname[32];
|
||||
char context_str[16];
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_array_t *arr = NULL;
|
||||
int i, count;
|
||||
|
||||
/* If getting to the menu from inside the game, the vars aren't removed. So
|
||||
* let's not allocate them again. */
|
||||
|
|
@ -2851,22 +2853,44 @@ void read_saved_vars(struct char_data *ch)
|
|||
log("%s had no variable file", GET_NAME(ch));
|
||||
return;
|
||||
}
|
||||
/* walk through each line in the file parsing variables */
|
||||
do {
|
||||
if (get_line(file, input_line)>0) {
|
||||
p = temp = strdup(input_line);
|
||||
temp = any_one_arg(temp, varname);
|
||||
temp = any_one_arg(temp, context_str);
|
||||
skip_spaces(&temp); /* temp now points to the rest of the line */
|
||||
|
||||
context = atol(context_str);
|
||||
add_var(&(SCRIPT(ch)->global_vars), varname, temp, context);
|
||||
free(p); /* plug memory hole */
|
||||
}
|
||||
} while( !feof(file) );
|
||||
|
||||
/* close the file and return */
|
||||
tab = toml_parse_file(file, errbuf, sizeof(errbuf));
|
||||
fclose(file);
|
||||
if (!tab) {
|
||||
log("SYSERR: Could not parse variable file %s: %s", fn, errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
arr = toml_array_in(tab, "var");
|
||||
if (!arr) {
|
||||
toml_free(tab);
|
||||
return;
|
||||
}
|
||||
|
||||
count = toml_array_nelem(arr);
|
||||
for (i = 0; i < count; i++) {
|
||||
toml_table_t *var_tab = toml_table_at(arr, i);
|
||||
toml_datum_t name;
|
||||
toml_datum_t value;
|
||||
toml_datum_t context;
|
||||
|
||||
if (!var_tab)
|
||||
continue;
|
||||
|
||||
name = toml_string_in(var_tab, "name");
|
||||
value = toml_string_in(var_tab, "value");
|
||||
context = toml_int_in(var_tab, "context");
|
||||
|
||||
if (!name.ok || !value.ok)
|
||||
continue;
|
||||
|
||||
add_var(&(SCRIPT(ch)->global_vars), name.u.s, value.u.s,
|
||||
context.ok ? (long)context.u.i : 0);
|
||||
free(name.u.s);
|
||||
free(value.u.s);
|
||||
}
|
||||
|
||||
toml_free(tab);
|
||||
}
|
||||
|
||||
/* save a characters variables out to disk */
|
||||
|
|
@ -2901,7 +2925,12 @@ void save_char_vars(struct char_data *ch)
|
|||
* future. */
|
||||
while (vars) {
|
||||
if (*vars->name != '-') /* don't save if it begins with - */
|
||||
fprintf(file, "%s %ld %s\n", vars->name, vars->context, vars->value);
|
||||
{
|
||||
fprintf(file, "[[var]]\n");
|
||||
toml_write_kv_string(file, "name", vars->name);
|
||||
fprintf(file, "context = %ld\n", vars->context);
|
||||
toml_write_kv_string(file, "value", vars->value);
|
||||
}
|
||||
vars = vars->next;
|
||||
}
|
||||
|
||||
|
|
|
|||
144
src/genmob.c
144
src/genmob.c
|
|
@ -17,6 +17,7 @@
|
|||
#include "genzon.h"
|
||||
#include "dg_olc.h"
|
||||
#include "spells.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
/* local functions */
|
||||
static void extract_mobile_all(mob_vnum vnum);
|
||||
|
|
@ -312,10 +313,9 @@ int save_mobiles(zone_rnum rznum)
|
|||
if (write_mobile_record(i, &mob_proto[rmob], mobfd) < 0)
|
||||
log("SYSERR: GenOLC: Error writing mobile #%d.", i);
|
||||
}
|
||||
fputs("$\n", mobfd);
|
||||
written = ftell(mobfd);
|
||||
fclose(mobfd);
|
||||
snprintf(usedfname, sizeof(usedfname), "%s%d.mob", MOB_PREFIX, vznum);
|
||||
snprintf(usedfname, sizeof(usedfname), "%s%d.toml", MOB_PREFIX, vznum);
|
||||
remove(usedfname);
|
||||
rename(mobfname, usedfname);
|
||||
|
||||
|
|
@ -407,7 +407,6 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
char ldesc[MAX_STRING_LENGTH];
|
||||
char ddesc[MAX_STRING_LENGTH];
|
||||
char bdesc[MAX_STRING_LENGTH];
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
int has_bdesc = 0;
|
||||
|
||||
ldesc[MAX_STRING_LENGTH - 1] = '\0';
|
||||
|
|
@ -429,94 +428,71 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
} else
|
||||
bdesc[0] = '\0';
|
||||
|
||||
int n;
|
||||
if (has_bdesc) {
|
||||
n = snprintf(buf, MAX_STRING_LENGTH,
|
||||
"#%d\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"B\n"
|
||||
"%s%c\n",
|
||||
mvnum,
|
||||
GET_NAME(mob), STRING_TERMINATOR,
|
||||
GET_KEYWORDS(mob), STRING_TERMINATOR,
|
||||
GET_SDESC(mob), STRING_TERMINATOR,
|
||||
ldesc, STRING_TERMINATOR,
|
||||
ddesc, STRING_TERMINATOR,
|
||||
bdesc, STRING_TERMINATOR);
|
||||
} else {
|
||||
n = snprintf(buf, MAX_STRING_LENGTH,
|
||||
"#%d\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n",
|
||||
mvnum,
|
||||
GET_NAME(mob), STRING_TERMINATOR,
|
||||
GET_KEYWORDS(mob), STRING_TERMINATOR,
|
||||
GET_SDESC(mob), STRING_TERMINATOR,
|
||||
ldesc, STRING_TERMINATOR,
|
||||
ddesc, STRING_TERMINATOR);
|
||||
}
|
||||
fprintf(fd, "[[mob]]\n");
|
||||
fprintf(fd, "vnum = %d\n", mvnum);
|
||||
toml_write_kv_string(fd, "name", GET_NAME(mob));
|
||||
toml_write_kv_string(fd, "keywords", GET_KEYWORDS(mob));
|
||||
toml_write_kv_string(fd, "short", GET_SDESC(mob));
|
||||
toml_write_kv_string(fd, "long", ldesc);
|
||||
toml_write_kv_string(fd, "description", ddesc);
|
||||
if (has_bdesc)
|
||||
toml_write_kv_string_opt(fd, "background", bdesc);
|
||||
|
||||
if (n >= MAX_STRING_LENGTH) {
|
||||
mudlog(BRF, LVL_BUILDER, TRUE,
|
||||
"SYSERR: Could not save mobile #%d due to size (%d > maximum of %d)",
|
||||
mvnum, n, MAX_STRING_LENGTH);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
fprintf(fd, "%s", convert_from_tabs(buf));
|
||||
|
||||
/* --- FLAGS/AFFECT/ALIGN line --- */
|
||||
fprintf(fd,
|
||||
"%d %d %d %d %d %d %d %d %d E\n",
|
||||
fprintf(fd, "flags = [%d, %d, %d, %d]\n",
|
||||
MOB_FLAGS(mob)[0], MOB_FLAGS(mob)[1],
|
||||
MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3],
|
||||
MOB_FLAGS(mob)[2], MOB_FLAGS(mob)[3]);
|
||||
fprintf(fd, "aff_flags = [%d, %d, %d, %d]\n",
|
||||
AFF_FLAGS(mob)[0], AFF_FLAGS(mob)[1],
|
||||
AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3],
|
||||
GET_ALIGNMENT(mob));
|
||||
AFF_FLAGS(mob)[2], AFF_FLAGS(mob)[3]);
|
||||
fprintf(fd, "alignment = %d\n", GET_ALIGNMENT(mob));
|
||||
toml_write_kv_string(fd, "mob_type", "enhanced");
|
||||
|
||||
/* --- Level, hitdice, mana, move --- */
|
||||
fprintf(fd, "%d %dd%d+%d\n",
|
||||
GET_LEVEL(mob),
|
||||
GET_HIT(mob),
|
||||
GET_MANA(mob),
|
||||
GET_STAMINA(mob));
|
||||
fprintf(fd, "\n[mob.simple]\n");
|
||||
fprintf(fd, "level = %d\n", GET_LEVEL(mob));
|
||||
fprintf(fd, "hit_dice = %d\n", GET_HIT(mob));
|
||||
fprintf(fd, "mana_dice = %d\n", GET_MANA(mob));
|
||||
fprintf(fd, "stamina_dice = %d\n", GET_STAMINA(mob));
|
||||
fprintf(fd, "pos = %d\n", GET_POS(mob));
|
||||
fprintf(fd, "default_pos = %d\n", GET_DEFAULT_POS(mob));
|
||||
fprintf(fd, "sex = %d\n", GET_SEX(mob));
|
||||
|
||||
/* --- Position / default position / sex --- */
|
||||
fprintf(fd, "%d %d %d\n",
|
||||
GET_POS(mob),
|
||||
GET_DEFAULT_POS(mob),
|
||||
GET_SEX(mob));
|
||||
fprintf(fd, "\n[mob.enhanced]\n");
|
||||
fprintf(fd, "class = %d\n", GET_CLASS(mob));
|
||||
fprintf(fd, "species = %d\n", GET_SPECIES(mob));
|
||||
fprintf(fd, "age = %d\n", GET_ROLEPLAY_AGE(mob));
|
||||
fprintf(fd, "attack_type = %d\n", mob->mob_specials.attack_type);
|
||||
|
||||
/* --- Enhanced (E-spec + Skills) --- */
|
||||
if (write_mobile_espec(mvnum, mob, fd) < 0)
|
||||
log("SYSERR: GenOLC: Error writing E-specs for mobile #%d.", mvnum);
|
||||
fprintf(fd, "\n[mob.enhanced.abilities]\n");
|
||||
fprintf(fd, "str = %d\n", GET_STR(mob));
|
||||
fprintf(fd, "dex = %d\n", GET_DEX(mob));
|
||||
fprintf(fd, "con = %d\n", GET_CON(mob));
|
||||
fprintf(fd, "int = %d\n", GET_INT(mob));
|
||||
fprintf(fd, "wis = %d\n", GET_WIS(mob));
|
||||
fprintf(fd, "cha = %d\n", GET_CHA(mob));
|
||||
|
||||
fprintf(fd, "\n[mob.enhanced.saving_throws]\n");
|
||||
fprintf(fd, "str = %d\n", GET_SAVE(mob, ABIL_STR));
|
||||
fprintf(fd, "dex = %d\n", GET_SAVE(mob, ABIL_DEX));
|
||||
fprintf(fd, "con = %d\n", GET_SAVE(mob, ABIL_CON));
|
||||
fprintf(fd, "int = %d\n", GET_SAVE(mob, ABIL_INT));
|
||||
fprintf(fd, "wis = %d\n", GET_SAVE(mob, ABIL_WIS));
|
||||
fprintf(fd, "cha = %d\n", GET_SAVE(mob, ABIL_CHA));
|
||||
|
||||
/* Write NPC skills (if any set) */
|
||||
for (int s = 0; s < MAX_SKILLS; s++) {
|
||||
if (mob->mob_specials.skills[s] > 0)
|
||||
fprintf(fd, "Skill %d %d\n", s, mob->mob_specials.skills[s]);
|
||||
if (mob->mob_specials.skills[s] > 0) {
|
||||
fprintf(fd, "\n[[mob.enhanced.skills]]\n");
|
||||
fprintf(fd, "id = %d\n", s);
|
||||
fprintf(fd, "level = %d\n", mob->mob_specials.skills[s]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write attack type (if set) */
|
||||
if (mob->mob_specials.attack_type > 0)
|
||||
fprintf(fd, "AtkT %d\n", mob->mob_specials.attack_type);
|
||||
|
||||
/* Single proper terminator */
|
||||
fprintf(fd, "E\n");
|
||||
|
||||
/* --- Loadout lines --- */
|
||||
/* --- Loadout entries --- */
|
||||
for (struct mob_loadout *e = mob->proto_loadout; e; e = e->next) {
|
||||
fprintf(fd, "L %d %d %d\n",
|
||||
(int)e->wear_pos,
|
||||
(int)e->vnum,
|
||||
MAX(1, e->quantity));
|
||||
fprintf(fd, "\n[[mob.loadout]]\n");
|
||||
fprintf(fd, "wear_pos = %d\n", (int)e->wear_pos);
|
||||
fprintf(fd, "vnum = %d\n", (int)e->vnum);
|
||||
fprintf(fd, "quantity = %d\n", MAX(1, e->quantity));
|
||||
}
|
||||
|
||||
/* --- DG Scripts --- */
|
||||
|
|
@ -528,10 +504,11 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
struct skin_yield_entry *sy;
|
||||
|
||||
if (rmob != NOBODY && mob_index[rmob].skin_yields) {
|
||||
fprintf(fd, "Y\n");
|
||||
for (sy = mob_index[rmob].skin_yields; sy; sy = sy->next)
|
||||
fprintf(fd, "%d %d\n", sy->obj_vnum, sy->dc);
|
||||
fprintf(fd, "0 0\n");
|
||||
for (sy = mob_index[rmob].skin_yields; sy; sy = sy->next) {
|
||||
fprintf(fd, "\n[[mob.skin_yield]]\n");
|
||||
fprintf(fd, "obj_vnum = %d\n", sy->obj_vnum);
|
||||
fprintf(fd, "dc = %d\n", sy->dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -540,6 +517,7 @@ int write_mobile_record(mob_vnum mvnum, struct char_data *mob, FILE *fd)
|
|||
log("SYSERR: GenOLC: Error writing MobProgs for mobile #%d.", mvnum);
|
||||
#endif
|
||||
|
||||
fputc('\n', fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
104
src/genobj.c
104
src/genobj.c
|
|
@ -19,6 +19,7 @@
|
|||
#include "handler.h"
|
||||
#include "interpreter.h"
|
||||
#include "boards.h" /* for board_info */
|
||||
#include "toml_utils.h"
|
||||
|
||||
|
||||
/* local functions */
|
||||
|
|
@ -178,10 +179,7 @@ obj_rnum index_object(struct obj_data *obj, obj_vnum ovnum, obj_rnum ornum)
|
|||
|
||||
int save_objects(zone_rnum zone_num)
|
||||
{
|
||||
char filename[128], buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
|
||||
char ebuf1[MAX_STRING_LENGTH], ebuf2[MAX_STRING_LENGTH], ebuf3[MAX_STRING_LENGTH], ebuf4[MAX_STRING_LENGTH];
|
||||
char wbuf1[MAX_STRING_LENGTH], wbuf2[MAX_STRING_LENGTH], wbuf3[MAX_STRING_LENGTH], wbuf4[MAX_STRING_LENGTH];
|
||||
char pbuf1[MAX_STRING_LENGTH], pbuf2[MAX_STRING_LENGTH], pbuf3[MAX_STRING_LENGTH], pbuf4[MAX_STRING_LENGTH];
|
||||
char filename[128], buf[MAX_STRING_LENGTH];
|
||||
int counter, counter2, realcounter;
|
||||
FILE *fp;
|
||||
struct obj_data *obj;
|
||||
|
|
@ -210,54 +208,33 @@ int save_objects(zone_rnum zone_num)
|
|||
} else
|
||||
*buf = '\0';
|
||||
|
||||
int n = snprintf(buf2, MAX_STRING_LENGTH,
|
||||
"#%d\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n",
|
||||
|
||||
GET_OBJ_VNUM(obj),
|
||||
(obj->name && *obj->name) ? obj->name : "undefined",
|
||||
(obj->short_description && *obj->short_description) ? obj->short_description : "undefined",
|
||||
(obj->description && *obj->description) ? obj->description : "undefined",
|
||||
buf);
|
||||
|
||||
if(n >= MAX_STRING_LENGTH) {
|
||||
mudlog(BRF,LVL_BUILDER,TRUE,
|
||||
"SYSERR: Could not save object #%d due to size (%d > maximum of %d).",
|
||||
GET_OBJ_VNUM(obj), n, MAX_STRING_LENGTH);
|
||||
continue;
|
||||
fprintf(fp, "[[object]]\n");
|
||||
fprintf(fp, "vnum = %d\n", GET_OBJ_VNUM(obj));
|
||||
toml_write_kv_string(fp, "name", (obj->name && *obj->name) ? obj->name : "undefined");
|
||||
toml_write_kv_string(fp, "short", (obj->short_description && *obj->short_description) ? obj->short_description : "undefined");
|
||||
toml_write_kv_string(fp, "description", (obj->description && *obj->description) ? obj->description : "undefined");
|
||||
toml_write_kv_string(fp, "main_description", buf);
|
||||
fprintf(fp, "type = %d\n", GET_OBJ_TYPE(obj));
|
||||
fprintf(fp, "extra_flags = [%d, %d, %d, %d]\n",
|
||||
GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1],
|
||||
GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);
|
||||
fprintf(fp, "wear_flags = [%d, %d, %d, %d]\n",
|
||||
GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1],
|
||||
GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);
|
||||
fprintf(fp, "affect_flags = [%d, %d, %d, %d]\n",
|
||||
GET_OBJ_AFFECT(obj)[0], GET_OBJ_AFFECT(obj)[1],
|
||||
GET_OBJ_AFFECT(obj)[2], GET_OBJ_AFFECT(obj)[3]);
|
||||
fprintf(fp, "values = [");
|
||||
for (counter2 = 0; counter2 < NUM_OBJ_VAL_POSITIONS; counter2++) {
|
||||
if (counter2)
|
||||
fputs(", ", fp);
|
||||
fprintf(fp, "%d", GET_OBJ_VAL(obj, counter2));
|
||||
}
|
||||
|
||||
fprintf(fp, "%s", convert_from_tabs(buf2));
|
||||
|
||||
sprintascii(ebuf1, GET_OBJ_EXTRA(obj)[0]);
|
||||
sprintascii(ebuf2, GET_OBJ_EXTRA(obj)[1]);
|
||||
sprintascii(ebuf3, GET_OBJ_EXTRA(obj)[2]);
|
||||
sprintascii(ebuf4, GET_OBJ_EXTRA(obj)[3]);
|
||||
sprintascii(wbuf1, GET_OBJ_WEAR(obj)[0]);
|
||||
sprintascii(wbuf2, GET_OBJ_WEAR(obj)[1]);
|
||||
sprintascii(wbuf3, GET_OBJ_WEAR(obj)[2]);
|
||||
sprintascii(wbuf4, GET_OBJ_WEAR(obj)[3]);
|
||||
sprintascii(pbuf1, GET_OBJ_AFFECT(obj)[0]);
|
||||
sprintascii(pbuf2, GET_OBJ_AFFECT(obj)[1]);
|
||||
sprintascii(pbuf3, GET_OBJ_AFFECT(obj)[2]);
|
||||
sprintascii(pbuf4, GET_OBJ_AFFECT(obj)[3]);
|
||||
|
||||
fprintf(fp, "%d %s %s %s %s %s %s %s %s %s %s %s %s\n"
|
||||
"%d %d %d %d\n"
|
||||
"%d %d %d %d %d\n",
|
||||
|
||||
GET_OBJ_TYPE(obj),
|
||||
ebuf1, ebuf2, ebuf3, ebuf4,
|
||||
wbuf1, wbuf2, wbuf3, wbuf4,
|
||||
pbuf1, pbuf2, pbuf3, pbuf4,
|
||||
GET_OBJ_VAL(obj, 0), GET_OBJ_VAL(obj, 1),
|
||||
GET_OBJ_VAL(obj, 2), GET_OBJ_VAL(obj, 3),
|
||||
GET_OBJ_WEIGHT(obj), GET_OBJ_COST(obj),
|
||||
GET_OBJ_COST_PER_DAY(obj), GET_OBJ_LEVEL(obj), GET_OBJ_TIMER(obj)
|
||||
);
|
||||
fputs("]\n", fp);
|
||||
fprintf(fp, "weight = %d\n", GET_OBJ_WEIGHT(obj));
|
||||
fprintf(fp, "cost = %d\n", GET_OBJ_COST(obj));
|
||||
fprintf(fp, "level = %d\n", GET_OBJ_LEVEL(obj));
|
||||
fprintf(fp, "timer = %d\n", GET_OBJ_TIMER(obj));
|
||||
|
||||
/* Do we have script(s) attached? */
|
||||
script_save_to_disk(fp, obj, OBJ_TRIGGER);
|
||||
|
|
@ -272,24 +249,25 @@ int save_objects(zone_rnum zone_num)
|
|||
}
|
||||
strncpy(buf, ex_desc->description, sizeof(buf) - 1);
|
||||
strip_cr(buf);
|
||||
fprintf(fp, "E\n"
|
||||
"%s~\n"
|
||||
"%s~\n", ex_desc->keyword, buf);
|
||||
fprintf(fp, "\n[[object.extra_desc]]\n");
|
||||
toml_write_kv_string(fp, "keyword", ex_desc->keyword);
|
||||
toml_write_kv_string(fp, "description", buf);
|
||||
}
|
||||
}
|
||||
/* Do we have affects? */
|
||||
for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++)
|
||||
if (obj->affected[counter2].modifier)
|
||||
fprintf(fp, "A\n"
|
||||
"%d %d\n", obj->affected[counter2].location,
|
||||
obj->affected[counter2].modifier);
|
||||
for (counter2 = 0; counter2 < MAX_OBJ_AFFECT; counter2++) {
|
||||
if (obj->affected[counter2].modifier) {
|
||||
fprintf(fp, "\n[[object.affect]]\n");
|
||||
fprintf(fp, "location = %d\n", obj->affected[counter2].location);
|
||||
fprintf(fp, "modifier = %d\n", obj->affected[counter2].modifier);
|
||||
}
|
||||
}
|
||||
fputc('\n', fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the final line, close the file. */
|
||||
fprintf(fp, "$~\n");
|
||||
fclose(fp);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.obj", OBJ_PREFIX, zone_table[zone_num].number);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", OBJ_PREFIX, zone_table[zone_num].number);
|
||||
remove(buf);
|
||||
rename(filename, buf);
|
||||
|
||||
|
|
@ -615,4 +593,4 @@ void clamp_armor_values(struct obj_data *obj) {
|
|||
GET_OBJ_VAL(obj, VAL_ARMOR_MAGIC_BONUS) = v;
|
||||
|
||||
/* flags are a bitvector; leave as-is (OLC will manage legal bits) */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/genolc.c
20
src/genolc.c
|
|
@ -313,7 +313,7 @@ ACMD(do_export_zone)
|
|||
#else /* all other configurations */
|
||||
zone_rnum zrnum;
|
||||
zone_vnum zvnum;
|
||||
char sysbuf[MAX_INPUT_LENGTH];
|
||||
char sysbuf[MAX_STRING_LENGTH];
|
||||
char zone_name[READ_SIZE], fixed_file_name[READ_SIZE];
|
||||
int success, errorcode = 0;
|
||||
|
||||
|
|
@ -384,7 +384,7 @@ ACMD(do_export_zone)
|
|||
|
||||
|
||||
/* Tar the new copy. */
|
||||
snprintf(sysbuf, sizeof(sysbuf), "tar -cf %s%s.tar %sqq.info %sqq.wld %sqq.zon %sqq.mob %sqq.obj %sqq.trg %sqq.shp", path, fixed_file_name, path, path, path, path, path, path, path);
|
||||
snprintf(sysbuf, sizeof(sysbuf), "tar -cf %s%s.tar %sqq.info %sqq.wld.toml %sqq.zon.toml %sqq.mob.toml %sqq.obj.toml %sqq.trg.toml %sqq.shp.toml %sqq.qst.toml", path, fixed_file_name, path, path, path, path, path, path, path, path);
|
||||
errorcode = system(sysbuf);
|
||||
if (errorcode) {
|
||||
send_to_char(ch, "Failed to tar files.\r\n");
|
||||
|
|
@ -425,8 +425,8 @@ static int export_info_file(zone_rnum zrnum)
|
|||
fprintf(info_file, "Implementation:\n");
|
||||
fprintf(info_file, "1. All the files have been QQ'ed. This means all occurences of the zone number\n");
|
||||
fprintf(info_file, " have been changed to QQ. In other words, if you decide to have this zone as\n");
|
||||
fprintf(info_file, " zone 123, replace all occurences of QQ with 123 and rename the qq.zon file\n");
|
||||
fprintf(info_file, " to 123.zon (etc.). And of course add 123.zon to the respective index file.\n");
|
||||
fprintf(info_file, " zone 123, replace all occurences of QQ with 123 and rename the qq.wld.toml file\n");
|
||||
fprintf(info_file, " to 123.toml (etc.). And of course add 123.toml to the respective index file.\n");
|
||||
if (zone_exits) {
|
||||
fprintf(info_file, "2. Exits out of this zone have been ZZ'd. So all doors leading out have ZZ??\n");
|
||||
fprintf(info_file, " instead of the room vnum (?? are numbers 00 - 99).\n");
|
||||
|
|
@ -481,7 +481,7 @@ static int export_save_shops(zone_rnum zrnum)
|
|||
FILE *shop_file;
|
||||
struct shop_data *shop;
|
||||
|
||||
if (!(shop_file = fopen("world/export/qq.shp", "w"))) {
|
||||
if (!(shop_file = fopen("world/export/qq.shp.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_shops : Cannot open shop file!");
|
||||
return FALSE;
|
||||
} else if (fprintf(shop_file, "CircleMUD v3.0 Shop File~\n") < 0) {
|
||||
|
|
@ -571,7 +571,7 @@ static int export_save_mobiles(zone_rnum rznum)
|
|||
mob_vnum i;
|
||||
mob_rnum rmob;
|
||||
|
||||
if (!(mob_file = fopen("world/export/qq.mob", "w"))) {
|
||||
if (!(mob_file = fopen("world/export/qq.mob.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_mobiles : Cannot open file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -648,7 +648,7 @@ static int export_save_zone(zone_rnum zrnum)
|
|||
int subcmd;
|
||||
FILE *zone_file;
|
||||
|
||||
if (!(zone_file = fopen("world/export/qq.zon", "w"))) {
|
||||
if (!(zone_file = fopen("world/export/qq.zon.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_zone : Cannot open file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -783,7 +783,7 @@ static int export_save_objects(zone_rnum zrnum)
|
|||
struct obj_data *obj;
|
||||
struct extra_descr_data *ex_desc;
|
||||
|
||||
if (!(obj_file = fopen("world/export/qq.obj", "w"))) {
|
||||
if (!(obj_file = fopen("world/export/qq.obj.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_objects : Cannot open file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -889,7 +889,7 @@ static int export_save_rooms(zone_rnum zrnum)
|
|||
char buf[MAX_STRING_LENGTH];
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
|
||||
if (!(room_file = fopen("world/export/qq.wld", "w"))) {
|
||||
if (!(room_file = fopen("world/export/qq.wld.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_rooms : Cannot open file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1028,7 +1028,7 @@ static int export_save_triggers(zone_rnum zrnum)
|
|||
FILE *trig_file;
|
||||
char bitBuf[MAX_INPUT_LENGTH];
|
||||
|
||||
if (!(trig_file = fopen("world/export/qq.trg", "w"))) {
|
||||
if (!(trig_file = fopen("world/export/qq.trg.toml", "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: export_save_triggers : Cannot open file!");
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
72
src/genqst.c
72
src/genqst.c
|
|
@ -16,6 +16,7 @@
|
|||
#include "quest.h"
|
||||
#include "genolc.h"
|
||||
#include "genzon.h" /* for create_world_index */
|
||||
#include "toml_utils.h"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
|
@ -176,10 +177,9 @@ int delete_quest(qst_rnum rnum)
|
|||
int save_quests(zone_rnum zone_num)
|
||||
{
|
||||
FILE *sf;
|
||||
char filename[128], oldname[128], quest_flags[MAX_STRING_LENGTH];
|
||||
char filename[128], oldname[128];
|
||||
char quest_desc[MAX_STRING_LENGTH], quest_info[MAX_STRING_LENGTH];
|
||||
char quest_done[MAX_STRING_LENGTH], quest_quit[MAX_STRING_LENGTH];
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
int i, num_quests = 0;
|
||||
|
||||
#if CIRCLE_UNSIGNED_INDEX
|
||||
|
|
@ -219,53 +219,37 @@ int save_quests(zone_rnum zone_num)
|
|||
strip_cr(quest_done);
|
||||
strip_cr(quest_quit);
|
||||
/* Save the quest details to the file. */
|
||||
sprintascii(quest_flags, QST_FLAGS(rnum));
|
||||
int n = snprintf(buf, MAX_STRING_LENGTH,
|
||||
"#%d\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%d %d %s %d %d %d %d\n"
|
||||
"%d %d %d %d %d %d %d\n"
|
||||
"%d %d %d\n"
|
||||
"S\n",
|
||||
QST_NUM(rnum),
|
||||
QST_NAME(rnum) ? QST_NAME(rnum) : "Untitled", STRING_TERMINATOR,
|
||||
quest_desc, STRING_TERMINATOR,
|
||||
quest_info, STRING_TERMINATOR,
|
||||
quest_done, STRING_TERMINATOR,
|
||||
quest_quit, STRING_TERMINATOR,
|
||||
QST_TYPE(rnum),
|
||||
QST_MASTER(rnum) == NOBODY ? -1 : QST_MASTER(rnum),
|
||||
quest_flags,
|
||||
QST_TARGET(rnum) == NOTHING ? -1 : QST_TARGET(rnum),
|
||||
QST_PREV(rnum) == NOTHING ? -1 : QST_PREV(rnum),
|
||||
QST_NEXT(rnum) == NOTHING ? -1 : QST_NEXT(rnum),
|
||||
QST_PREREQ(rnum) == NOTHING ? -1 : QST_PREREQ(rnum),
|
||||
QST_POINTS(rnum), QST_PENALTY(rnum), QST_MINLEVEL(rnum),
|
||||
QST_MAXLEVEL(rnum), QST_TIME(rnum),
|
||||
QST_RETURNMOB(rnum) == NOBODY ? -1 : QST_RETURNMOB(rnum),
|
||||
QST_QUANTITY(rnum), QST_COINS(rnum), QST_EXP(rnum), QST_OBJ(rnum)
|
||||
);
|
||||
|
||||
if(n < MAX_STRING_LENGTH) {
|
||||
fprintf(sf, "%s", convert_from_tabs(buf));
|
||||
num_quests++;
|
||||
} else {
|
||||
mudlog(BRF,LVL_BUILDER,TRUE,
|
||||
"SYSERR: Could not save quest #%d due to size (%d > maximum of %d).",
|
||||
QST_NUM(rnum), n, MAX_STRING_LENGTH);
|
||||
}
|
||||
fprintf(sf, "[[quest]]\n");
|
||||
fprintf(sf, "vnum = %d\n", QST_NUM(rnum));
|
||||
toml_write_kv_string(sf, "name", QST_NAME(rnum) ? QST_NAME(rnum) : "Untitled");
|
||||
toml_write_kv_string(sf, "description", quest_desc);
|
||||
toml_write_kv_string(sf, "info", quest_info);
|
||||
toml_write_kv_string(sf, "done", quest_done);
|
||||
toml_write_kv_string(sf, "quit", quest_quit);
|
||||
fprintf(sf, "type = %d\n", QST_TYPE(rnum));
|
||||
fprintf(sf, "quest_master = %d\n", QST_MASTER(rnum) == NOBODY ? -1 : QST_MASTER(rnum));
|
||||
fprintf(sf, "flags = %d\n", (int)QST_FLAGS(rnum));
|
||||
fprintf(sf, "target = %d\n", QST_TARGET(rnum) == NOTHING ? -1 : QST_TARGET(rnum));
|
||||
fprintf(sf, "prev_quest = %d\n", QST_PREV(rnum) == NOTHING ? -1 : QST_PREV(rnum));
|
||||
fprintf(sf, "next_quest = %d\n", QST_NEXT(rnum) == NOTHING ? -1 : QST_NEXT(rnum));
|
||||
fprintf(sf, "prereq = %d\n", QST_PREREQ(rnum) == NOTHING ? -1 : QST_PREREQ(rnum));
|
||||
fprintf(sf, "values = [%d, %d, %d, %d, %d, %d, %d]\n",
|
||||
QST_POINTS(rnum), QST_PENALTY(rnum), QST_MINLEVEL(rnum),
|
||||
QST_MAXLEVEL(rnum), QST_TIME(rnum),
|
||||
QST_RETURNMOB(rnum) == NOBODY ? -1 : QST_RETURNMOB(rnum),
|
||||
QST_QUANTITY(rnum));
|
||||
fprintf(sf, "[quest.rewards]\n");
|
||||
fprintf(sf, "coins = %d\n", QST_COINS(rnum));
|
||||
fprintf(sf, "exp = %d\n", QST_EXP(rnum));
|
||||
fprintf(sf, "obj_vnum = %d\n", QST_OBJ(rnum) == NOTHING ? -1 : QST_OBJ(rnum));
|
||||
fputc('\n', sf);
|
||||
num_quests++;
|
||||
}
|
||||
}
|
||||
/* Write the final line and close it. */
|
||||
fprintf(sf, "$~\n");
|
||||
fclose(sf);
|
||||
|
||||
/* Old file we're replacing. */
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.qst",
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.toml",
|
||||
QST_PREFIX, zone_table[zone_num].number);
|
||||
remove(oldname);
|
||||
rename(filename, oldname);
|
||||
|
|
|
|||
106
src/genshp.c
106
src/genshp.c
|
|
@ -14,6 +14,7 @@
|
|||
#include "genolc.h"
|
||||
#include "genshp.h"
|
||||
#include "genzon.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
/* NOTE (gg): Didn't modify sedit much. Don't consider it as 'recent' as the
|
||||
* other editors with regard to updates or style. */
|
||||
|
|
@ -345,7 +346,7 @@ int save_shops(zone_rnum zone_num)
|
|||
{
|
||||
int i, j, rshop, num_shops = 0;
|
||||
FILE *shop_file;
|
||||
char fname[128], oldname[128], buf[MAX_STRING_LENGTH];
|
||||
char fname[128], oldname[128];
|
||||
struct shop_data *shop;
|
||||
|
||||
#if CIRCLE_UNSIGNED_INDEX
|
||||
|
|
@ -361,77 +362,68 @@ int save_shops(zone_rnum zone_num)
|
|||
if (!(shop_file = fopen(fname, "w"))) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: OLC: Cannot open shop file!");
|
||||
return FALSE;
|
||||
} else if (fprintf(shop_file, "CircleMUD v3.0 Shop File~\n") < 0) {
|
||||
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: OLC: Cannot write to shop file!");
|
||||
fclose(shop_file);
|
||||
return FALSE;
|
||||
}
|
||||
/* Search database for shops in this zone. */
|
||||
for (i = genolc_zone_bottom(zone_num); i <= zone_table[zone_num].top; i++) {
|
||||
if ((rshop = real_shop(i)) != NOWHERE) {
|
||||
fprintf(shop_file, "#%d~\n", i);
|
||||
shop = shop_index + rshop;
|
||||
|
||||
/* Save the products. */
|
||||
for (j = 0; S_PRODUCT(shop, j) != NOTHING; j++)
|
||||
fprintf(shop_file, "%d\n", obj_index[S_PRODUCT(shop, j)].vnum);
|
||||
fprintf(shop_file, "-1\n");
|
||||
fprintf(shop_file, "[[shop]]\n");
|
||||
fprintf(shop_file, "vnum = %d\n", i);
|
||||
|
||||
/* Save the rates. */
|
||||
fprintf(shop_file, "%1.2f\n"
|
||||
"%1.2f\n",
|
||||
S_BUYPROFIT(shop),
|
||||
S_SELLPROFIT(shop));
|
||||
fprintf(shop_file, "products = [");
|
||||
for (j = 0; S_PRODUCT(shop, j) != NOTHING; j++) {
|
||||
if (j)
|
||||
fputs(", ", shop_file);
|
||||
fprintf(shop_file, "%d", obj_index[S_PRODUCT(shop, j)].vnum);
|
||||
}
|
||||
fputs("]\n", shop_file);
|
||||
|
||||
/* Save the buy types and namelists. */
|
||||
for (j = 0;S_BUYTYPE(shop, j) != NOTHING; j++)
|
||||
fprintf(shop_file, "%d%s\n",
|
||||
S_BUYTYPE(shop, j),
|
||||
S_BUYWORD(shop, j) ? S_BUYWORD(shop, j) : "");
|
||||
fprintf(shop_file, "-1\n");
|
||||
fprintf(shop_file, "buy_profit = %1.2f\n", S_BUYPROFIT(shop));
|
||||
fprintf(shop_file, "sell_profit = %1.2f\n", S_SELLPROFIT(shop));
|
||||
|
||||
/* Save messages. Added some defaults as sanity checks. */
|
||||
sprintf(buf,
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%d\n"
|
||||
"%ld\n"
|
||||
"%d\n"
|
||||
"%d\n",
|
||||
S_NOITEM1(shop) ? S_NOITEM1(shop) : "%s Ke?!",
|
||||
S_NOITEM2(shop) ? S_NOITEM2(shop) : "%s Ke?!",
|
||||
S_NOBUY(shop) ? S_NOBUY(shop) : "%s Ke?!",
|
||||
S_NOCASH1(shop) ? S_NOCASH1(shop) : "%s Ke?!",
|
||||
S_NOCASH2(shop) ? S_NOCASH2(shop) : "%s Ke?!",
|
||||
S_BUY(shop) ? S_BUY(shop) : "%s Ke?! %d?",
|
||||
S_SELL(shop) ? S_SELL(shop) : "%s Ke?! %d?",
|
||||
S_BROKE_TEMPER(shop),
|
||||
S_BITVECTOR(shop),
|
||||
S_KEEPER(shop) == NOBODY ? -1 : mob_index[S_KEEPER(shop)].vnum,
|
||||
S_NOTRADE(shop)
|
||||
);
|
||||
|
||||
fputs(convert_from_tabs(buf), shop_file);
|
||||
for (j = 0; S_BUYTYPE(shop, j) != NOTHING; j++) {
|
||||
fprintf(shop_file, "\n[[shop.buy_type]]\n");
|
||||
fprintf(shop_file, "type = %d\n", S_BUYTYPE(shop, j));
|
||||
toml_write_kv_string_opt(shop_file, "keyword", S_BUYWORD(shop, j));
|
||||
}
|
||||
|
||||
/* Save the rooms. */
|
||||
for (j = 0;S_ROOM(shop, j) != NOWHERE; j++)
|
||||
fprintf(shop_file, "%d\n", S_ROOM(shop, j));
|
||||
fprintf(shop_file, "-1\n");
|
||||
fprintf(shop_file, "\n[shop.messages]\n");
|
||||
toml_write_kv_string(shop_file, "no_such_item1", S_NOITEM1(shop) ? S_NOITEM1(shop) : "");
|
||||
toml_write_kv_string(shop_file, "no_such_item2", S_NOITEM2(shop) ? S_NOITEM2(shop) : "");
|
||||
toml_write_kv_string(shop_file, "do_not_buy", S_NOBUY(shop) ? S_NOBUY(shop) : "");
|
||||
toml_write_kv_string(shop_file, "missing_cash1", S_NOCASH1(shop) ? S_NOCASH1(shop) : "");
|
||||
toml_write_kv_string(shop_file, "missing_cash2", S_NOCASH2(shop) ? S_NOCASH2(shop) : "");
|
||||
toml_write_kv_string(shop_file, "message_buy", S_BUY(shop) ? S_BUY(shop) : "");
|
||||
toml_write_kv_string(shop_file, "message_sell", S_SELL(shop) ? S_SELL(shop) : "");
|
||||
|
||||
/* Save open/closing times. */
|
||||
fprintf(shop_file, "%d\n%d\n%d\n%d\n", S_OPEN1(shop), S_CLOSE1(shop),
|
||||
S_OPEN2(shop), S_CLOSE2(shop));
|
||||
fprintf(shop_file, "broke_temper = %d\n", S_BROKE_TEMPER(shop));
|
||||
fprintf(shop_file, "bitvector = %ld\n", S_BITVECTOR(shop));
|
||||
fprintf(shop_file, "keeper = %d\n",
|
||||
S_KEEPER(shop) == NOBODY ? -1 : mob_index[S_KEEPER(shop)].vnum);
|
||||
fprintf(shop_file, "trade_with = %d\n", S_NOTRADE(shop));
|
||||
|
||||
fprintf(shop_file, "rooms = [");
|
||||
for (j = 0; S_ROOM(shop, j) != NOWHERE; j++) {
|
||||
if (j)
|
||||
fputs(", ", shop_file);
|
||||
fprintf(shop_file, "%d", S_ROOM(shop, j));
|
||||
}
|
||||
fputs("]\n", shop_file);
|
||||
|
||||
fprintf(shop_file, "open1 = %d\n", S_OPEN1(shop));
|
||||
fprintf(shop_file, "close1 = %d\n", S_CLOSE1(shop));
|
||||
fprintf(shop_file, "open2 = %d\n", S_OPEN2(shop));
|
||||
fprintf(shop_file, "close2 = %d\n", S_CLOSE2(shop));
|
||||
fprintf(shop_file, "bank = %d\n", S_BANK(shop));
|
||||
fprintf(shop_file, "sort = %d\n", S_SORT(shop));
|
||||
|
||||
fputc('\n', shop_file);
|
||||
num_shops++;
|
||||
}
|
||||
}
|
||||
fprintf(shop_file, "$~\n");
|
||||
fclose(shop_file);
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.shp", SHP_PREFIX, zone_table[zone_num].number);
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.toml", SHP_PREFIX, zone_table[zone_num].number);
|
||||
remove(oldname);
|
||||
rename(fname, oldname);
|
||||
|
||||
|
|
|
|||
114
src/genwld.c
114
src/genwld.c
|
|
@ -18,6 +18,7 @@
|
|||
#include "shop.h"
|
||||
#include "dg_olc.h"
|
||||
#include "mud_event.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
|
||||
/* This function will copy the strings so be sure you free your own copies of
|
||||
|
|
@ -269,7 +270,6 @@ int save_rooms(zone_rnum rzone)
|
|||
char filename[128];
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
char buf2[MAX_STRING_LENGTH];
|
||||
|
||||
#if CIRCLE_UNSIGNED_INDEX
|
||||
if (rzone == NOWHERE || rzone > top_of_zone_table) {
|
||||
|
|
@ -301,96 +301,70 @@ int save_rooms(zone_rnum rzone)
|
|||
strncpy(buf, room->description ? room->description : "Empty room.", sizeof(buf)-1 );
|
||||
strip_cr(buf);
|
||||
|
||||
/* Save the numeric and string section of the file. */
|
||||
int n = snprintf(buf2, MAX_STRING_LENGTH, "#%d\n"
|
||||
"%s%c\n"
|
||||
"%s%c\n"
|
||||
"%d %d %d %d %d %d\n",
|
||||
room->number,
|
||||
room->name ? room->name : "Untitled", STRING_TERMINATOR,
|
||||
buf, STRING_TERMINATOR,
|
||||
zone_table[room->zone].number, room->room_flags[0], room->room_flags[1], room->room_flags[2],
|
||||
room->room_flags[3], room->sector_type
|
||||
);
|
||||
|
||||
if(n >= MAX_STRING_LENGTH) {
|
||||
mudlog(BRF,LVL_BUILDER,TRUE,
|
||||
"SYSERR: Could not save room #%d due to size (%d > maximum of %d).",
|
||||
room->number, n, MAX_STRING_LENGTH);
|
||||
continue;
|
||||
}
|
||||
fprintf(sf, "[[room]]\n");
|
||||
fprintf(sf, "vnum = %d\n", room->number);
|
||||
toml_write_kv_string(sf, "name", room->name ? convert_from_tabs(room->name) : "Untitled");
|
||||
toml_write_kv_string(sf, "description", convert_from_tabs(buf));
|
||||
fprintf(sf, "flags = [%d, %d, %d, %d]\n",
|
||||
room->room_flags[0], room->room_flags[1],
|
||||
room->room_flags[2], room->room_flags[3]);
|
||||
fprintf(sf, "sector = %d\n", room->sector_type);
|
||||
|
||||
fprintf(sf, "%s", convert_from_tabs(buf2));
|
||||
|
||||
/* Now you write out the exits for the room. */
|
||||
for (j = 0; j < DIR_COUNT; j++) {
|
||||
if (R_EXIT(room, j)) {
|
||||
int dflag;
|
||||
if (R_EXIT(room, j)->general_description) {
|
||||
strncpy(buf, R_EXIT(room, j)->general_description, sizeof(buf)-1);
|
||||
strip_cr(buf);
|
||||
} else
|
||||
*buf = '\0';
|
||||
if (R_EXIT(room, j)) {
|
||||
if (R_EXIT(room, j)->general_description) {
|
||||
strncpy(buf, R_EXIT(room, j)->general_description, sizeof(buf)-1);
|
||||
strip_cr(buf);
|
||||
} else
|
||||
*buf = '\0';
|
||||
|
||||
/* Figure out door flag. */
|
||||
if (IS_SET(R_EXIT(room, j)->exit_info, EX_ISDOOR)) {
|
||||
if (IS_SET(R_EXIT(room, j)->exit_info, EX_PICKPROOF))
|
||||
dflag = 2;
|
||||
else
|
||||
dflag = 1;
|
||||
|
||||
if (IS_SET(R_EXIT(room, j)->exit_info, EX_HIDDEN))
|
||||
dflag += 2;
|
||||
|
||||
} else
|
||||
dflag = 0;
|
||||
if (R_EXIT(room, j)->keyword)
|
||||
strncpy(buf1, R_EXIT(room, j)->keyword, sizeof(buf1)-1 );
|
||||
else
|
||||
*buf1 = '\0';
|
||||
|
||||
if (R_EXIT(room, j)->keyword)
|
||||
strncpy(buf1, R_EXIT(room, j)->keyword, sizeof(buf1)-1 );
|
||||
else
|
||||
*buf1 = '\0';
|
||||
|
||||
/* Now write the exit to the file. */
|
||||
fprintf(sf, "D%d\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%d %d %d\n", j, buf, buf1, dflag,
|
||||
R_EXIT(room, j)->key != NOTHING ? R_EXIT(room, j)->key : -1,
|
||||
R_EXIT(room, j)->to_room != NOWHERE ? world[R_EXIT(room, j)->to_room].number : -1);
|
||||
|
||||
}
|
||||
fprintf(sf, "\n[[room.exit]]\n");
|
||||
fprintf(sf, "dir = %d\n", j);
|
||||
toml_write_kv_string(sf, "description", convert_from_tabs(buf));
|
||||
toml_write_kv_string(sf, "keyword", buf1);
|
||||
fprintf(sf, "exit_info = %d\n", R_EXIT(room, j)->exit_info);
|
||||
fprintf(sf, "key = %d\n",
|
||||
R_EXIT(room, j)->key != NOTHING ? R_EXIT(room, j)->key : -1);
|
||||
fprintf(sf, "to_room = %d\n",
|
||||
R_EXIT(room, j)->to_room != NOWHERE ? world[R_EXIT(room, j)->to_room].number : -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (room->ex_description) {
|
||||
struct extra_descr_data *xdesc;
|
||||
|
||||
for (xdesc = room->ex_description; xdesc; xdesc = xdesc->next) {
|
||||
strncpy(buf, xdesc->description, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
strip_cr(buf);
|
||||
fprintf(sf, "E\n"
|
||||
"%s~\n"
|
||||
"%s~\n", xdesc->keyword, buf);
|
||||
}
|
||||
for (xdesc = room->ex_description; xdesc; xdesc = xdesc->next) {
|
||||
strncpy(buf, xdesc->description, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
strip_cr(buf);
|
||||
fprintf(sf, "\n[[room.extra_desc]]\n");
|
||||
toml_write_kv_string(sf, "keyword", xdesc->keyword);
|
||||
toml_write_kv_string(sf, "description", convert_from_tabs(buf));
|
||||
}
|
||||
}
|
||||
if (room->forage) {
|
||||
struct forage_entry *entry;
|
||||
fprintf(sf, "F\n");
|
||||
for (entry = room->forage; entry; entry = entry->next)
|
||||
fprintf(sf, "%d %d\n", entry->obj_vnum, entry->dc);
|
||||
fprintf(sf, "0 0\n");
|
||||
for (entry = room->forage; entry; entry = entry->next) {
|
||||
fprintf(sf, "\n[[room.forage]]\n");
|
||||
fprintf(sf, "obj_vnum = %d\n", entry->obj_vnum);
|
||||
fprintf(sf, "dc = %d\n", entry->dc);
|
||||
}
|
||||
}
|
||||
fprintf(sf, "S\n");
|
||||
script_save_to_disk(sf, room, WLD_TRIGGER);
|
||||
fputc('\n', sf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the final line and close it. */
|
||||
fprintf(sf, "$~\n");
|
||||
fclose(sf);
|
||||
|
||||
/* Old file we're replacing. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.wld", WLD_PREFIX, zone_table[rzone].number);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", WLD_PREFIX, zone_table[rzone].number);
|
||||
|
||||
remove(buf);
|
||||
rename(filename, buf);
|
||||
|
|
|
|||
250
src/genzon.c
250
src/genzon.c
|
|
@ -11,6 +11,8 @@
|
|||
#include "utils.h"
|
||||
#include "db.h"
|
||||
#include "genolc.h"
|
||||
#include "toml.h"
|
||||
#include "toml_utils.h"
|
||||
#include "genzon.h"
|
||||
#include "dg_scripts.h"
|
||||
|
||||
|
|
@ -89,7 +91,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
}
|
||||
|
||||
/* Create the zone file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.zon", ZON_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", ZON_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new zone file.");
|
||||
*error = "Could not write zone file.\r\n";
|
||||
|
|
@ -99,7 +101,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the room file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.wld", WLD_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", WLD_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new world file.");
|
||||
*error = "Could not write world file.\r\n";
|
||||
|
|
@ -109,7 +111,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the mobile file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.mob", MOB_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", MOB_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new mob file.");
|
||||
*error = "Could not write mobile file.\r\n";
|
||||
|
|
@ -119,7 +121,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the object file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.obj", OBJ_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", OBJ_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new obj file.");
|
||||
*error = "Could not write object file.\r\n";
|
||||
|
|
@ -129,7 +131,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the shop file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.shp", SHP_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", SHP_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new shop file.");
|
||||
*error = "Could not write shop file.\r\n";
|
||||
|
|
@ -139,7 +141,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the quests file */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.qst", QST_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", QST_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new quest file");
|
||||
*error = "Could not write quest file.\r\n";
|
||||
|
|
@ -149,7 +151,7 @@ zone_rnum create_new_zone(zone_vnum vzone_num, room_vnum bottom, room_vnum top,
|
|||
fclose(fp);
|
||||
|
||||
/* Create the trigger file. */
|
||||
snprintf(buf, sizeof(buf), "%s/%d.trg", TRG_PREFIX, vzone_num);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.toml", TRG_PREFIX, vzone_num);
|
||||
if (!(fp = fopen(buf, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Can't write new trigger file");
|
||||
*error = "Could not write trigger file.\r\n";
|
||||
|
|
@ -219,9 +221,12 @@ void create_world_index(int znum, const char *type)
|
|||
{
|
||||
FILE *newfile, *oldfile;
|
||||
char new_name[32], old_name[32], *prefix;
|
||||
int num, found = FALSE;
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
char buf1[MAX_STRING_LENGTH];
|
||||
char **files = NULL;
|
||||
char errbuf[256];
|
||||
char file_name[32];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_array_t *arr = NULL;
|
||||
int i, num, count, insert_at;
|
||||
|
||||
switch (*type) {
|
||||
case 'z':
|
||||
|
|
@ -250,44 +255,98 @@ void create_world_index(int znum, const char *type)
|
|||
return;
|
||||
}
|
||||
|
||||
snprintf(old_name, sizeof(old_name), "%s/index", prefix);
|
||||
snprintf(new_name, sizeof(new_name), "%s/newindex", prefix);
|
||||
snprintf(old_name, sizeof(old_name), "%s/index.toml", prefix);
|
||||
snprintf(new_name, sizeof(new_name), "%s/newindex.toml", prefix);
|
||||
snprintf(file_name, sizeof(file_name), "%d.toml", znum);
|
||||
|
||||
if (!(oldfile = fopen(old_name, "r"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to open %s.", old_name);
|
||||
return;
|
||||
} else if (!(newfile = fopen(new_name, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to open %s.", new_name);
|
||||
fclose(oldfile);
|
||||
}
|
||||
|
||||
tab = toml_parse_file(oldfile, errbuf, sizeof(errbuf));
|
||||
fclose(oldfile);
|
||||
if (!tab) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to parse %s: %s.", old_name, errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Index contents must be in order: search through the old file for the right
|
||||
* place, insert the new file, then copy the rest over. */
|
||||
snprintf(buf1, sizeof(buf1), "%d.%s", znum, type);
|
||||
while (get_line(oldfile, buf)) {
|
||||
if (*buf == '$') {
|
||||
/* The following used to add a blank line, thanks to Brian Taylor for the fix. */
|
||||
fprintf(newfile, "%s", (!found ? strncat(buf1, "\n$\n", sizeof(buf1) - strlen(buf1) - 1) : "$\n"));
|
||||
break;
|
||||
} else if (!found) {
|
||||
sscanf(buf, "%d", &num);
|
||||
if (num > znum) {
|
||||
found = TRUE;
|
||||
fprintf(newfile, "%s\n", buf1);
|
||||
} else if (num == znum) {
|
||||
/* index file already had an entry for this zone. */
|
||||
fclose(oldfile);
|
||||
fclose(newfile);
|
||||
remove(new_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(newfile, "%s\n", buf);
|
||||
arr = toml_array_in(tab, "files");
|
||||
if (!arr) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: %s missing 'files' array.", old_name);
|
||||
toml_free(tab);
|
||||
return;
|
||||
}
|
||||
|
||||
count = toml_array_nelem(arr);
|
||||
CREATE(files, char *, count + 1);
|
||||
for (i = 0; i < count; i++) {
|
||||
toml_datum_t d = toml_string_at(arr, i);
|
||||
if (!d.ok) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: %s has invalid 'files' entry at %d.", old_name, i);
|
||||
toml_free(tab);
|
||||
while (i-- > 0)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
return;
|
||||
}
|
||||
files[i] = d.u.s;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!strcmp(files[i], file_name)) {
|
||||
toml_free(tab);
|
||||
for (i = 0; i < count; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
return;
|
||||
}
|
||||
if (sscanf(files[i], "%d", &num) == 1 && num == znum) {
|
||||
toml_free(tab);
|
||||
for (i = 0; i < count; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
insert_at = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (sscanf(files[i], "%d", &num) == 1 && num > znum) {
|
||||
insert_at = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RECREATE(files, char *, count + 2);
|
||||
if (insert_at < count)
|
||||
memmove(&files[insert_at + 1], &files[insert_at], sizeof(char *) * (count - insert_at));
|
||||
files[insert_at] = strdup(file_name);
|
||||
count++;
|
||||
|
||||
if (!(newfile = fopen(new_name, "w"))) {
|
||||
mudlog(BRF, LVL_IMPL, TRUE, "SYSERR: OLC: Failed to open %s.", new_name);
|
||||
toml_free(tab);
|
||||
for (i = 0; i < count; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(newfile, "files = [\n");
|
||||
for (i = 0; i < count; i++) {
|
||||
fprintf(newfile, " ");
|
||||
toml_write_string(newfile, files[i]);
|
||||
fprintf(newfile, "%s\n", (i + 1 < count) ? "," : "");
|
||||
}
|
||||
fprintf(newfile, "]\n");
|
||||
|
||||
fclose(newfile);
|
||||
fclose(oldfile);
|
||||
toml_free(tab);
|
||||
for (i = 0; i < count; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
|
||||
/* Out with the old, in with the new. */
|
||||
remove(old_name);
|
||||
rename(new_name, old_name);
|
||||
|
|
@ -326,12 +385,9 @@ void remove_room_zone_commands(zone_rnum zone, room_rnum room_num)
|
|||
* field is also there. */
|
||||
int save_zone(zone_rnum zone_num)
|
||||
{
|
||||
int subcmd, arg1 = -1, arg2 = -1, arg3 = -1, flag_tot=0, i;
|
||||
int subcmd, arg1 = -1, arg2 = -1, arg3 = -1;
|
||||
char fname[128], oldname[128];
|
||||
const char *comment = NULL;
|
||||
FILE *zfile;
|
||||
char zbuf1[MAX_STRING_LENGTH], zbuf2[MAX_STRING_LENGTH];
|
||||
char zbuf3[MAX_STRING_LENGTH], zbuf4[MAX_STRING_LENGTH];
|
||||
|
||||
#if CIRCLE_UNSIGNED_INDEX
|
||||
if (zone_num == NOWHERE || zone_num > top_of_zone_table) {
|
||||
|
|
@ -348,67 +404,25 @@ int save_zone(zone_rnum zone_num)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
for (i=0; i<ZN_ARRAY_MAX; i++)
|
||||
flag_tot += zone_table[zone_num].zone_flags[(i)];
|
||||
|
||||
/* If zone flags or levels aren't set, there is no reason to save them! */
|
||||
if (flag_tot == 0 && zone_table[zone_num].min_level == -1 && zone_table[zone_num].max_level == -1)
|
||||
{
|
||||
/* Print zone header to file. */
|
||||
fprintf(zfile, "#%d\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%d %d %d %d\n",
|
||||
zone_table[zone_num].number,
|
||||
(zone_table[zone_num].builders && *zone_table[zone_num].builders)
|
||||
? zone_table[zone_num].builders : "None.",
|
||||
(zone_table[zone_num].name && *zone_table[zone_num].name)
|
||||
? convert_from_tabs(zone_table[zone_num].name) : "undefined",
|
||||
genolc_zone_bottom(zone_num),
|
||||
zone_table[zone_num].top,
|
||||
zone_table[zone_num].lifespan,
|
||||
zone_table[zone_num].reset_mode
|
||||
);
|
||||
} else {
|
||||
sprintascii(zbuf1, zone_table[zone_num].zone_flags[0]);
|
||||
sprintascii(zbuf2, zone_table[zone_num].zone_flags[1]);
|
||||
sprintascii(zbuf3, zone_table[zone_num].zone_flags[2]);
|
||||
sprintascii(zbuf4, zone_table[zone_num].zone_flags[3]);
|
||||
|
||||
/* Print zone header to file. */
|
||||
fprintf(zfile, "#%d\n"
|
||||
"%s~\n"
|
||||
"%s~\n"
|
||||
"%d %d %d %d %s %s %s %s %d %d\n", /* New tbaMUD data line */
|
||||
zone_table[zone_num].number,
|
||||
(zone_table[zone_num].builders && *zone_table[zone_num].builders)
|
||||
? zone_table[zone_num].builders : "None.",
|
||||
(zone_table[zone_num].name && *zone_table[zone_num].name)
|
||||
? convert_from_tabs(zone_table[zone_num].name) : "undefined",
|
||||
genolc_zone_bottom(zone_num),
|
||||
zone_table[zone_num].top,
|
||||
zone_table[zone_num].lifespan,
|
||||
zone_table[zone_num].reset_mode,
|
||||
zbuf1, zbuf2, zbuf3, zbuf4,
|
||||
zone_table[zone_num].min_level,
|
||||
zone_table[zone_num].max_level
|
||||
);
|
||||
}
|
||||
|
||||
/* Handy Quick Reference Chart for Zone Values.
|
||||
*
|
||||
* Field #1 Field #3 Field #4 Field #5
|
||||
* -------------------------------------------------
|
||||
* M (Mobile) Mob-Vnum Wld-Max Room-Vnum
|
||||
* O (Object) Obj-Vnum Wld-Max Room-Vnum
|
||||
* G (Give) Obj-Vnum Wld-Max Unused
|
||||
* E (Equip) Obj-Vnum Wld-Max EQ-Position
|
||||
* P (Put) Obj-Vnum Wld-Max Target-Obj-Vnum
|
||||
* D (Door) Room-Vnum Door-Dir Door-State
|
||||
* R (Remove) Room-Vnum Obj-Vnum Unused
|
||||
* T (Trigger) Trig-type Trig-Vnum Room-Vnum
|
||||
* V (var) Trig-type Context Room-Vnum Varname Value
|
||||
* ------------------------------------------------- */
|
||||
fprintf(zfile, "[[zone]]\n");
|
||||
fprintf(zfile, "vnum = %d\n", zone_table[zone_num].number);
|
||||
toml_write_kv_string(zfile, "builders",
|
||||
(zone_table[zone_num].builders && *zone_table[zone_num].builders)
|
||||
? zone_table[zone_num].builders : "None.");
|
||||
toml_write_kv_string(zfile, "name",
|
||||
(zone_table[zone_num].name && *zone_table[zone_num].name)
|
||||
? convert_from_tabs(zone_table[zone_num].name) : "undefined");
|
||||
fprintf(zfile, "bot = %d\n", genolc_zone_bottom(zone_num));
|
||||
fprintf(zfile, "top = %d\n", zone_table[zone_num].top);
|
||||
fprintf(zfile, "lifespan = %d\n", zone_table[zone_num].lifespan);
|
||||
fprintf(zfile, "reset_mode = %d\n", zone_table[zone_num].reset_mode);
|
||||
fprintf(zfile, "flags = [%d, %d, %d, %d]\n",
|
||||
zone_table[zone_num].zone_flags[0],
|
||||
zone_table[zone_num].zone_flags[1],
|
||||
zone_table[zone_num].zone_flags[2],
|
||||
zone_table[zone_num].zone_flags[3]);
|
||||
fprintf(zfile, "min_level = %d\n", zone_table[zone_num].min_level);
|
||||
fprintf(zfile, "max_level = %d\n", zone_table[zone_num].max_level);
|
||||
|
||||
for (subcmd = 0; ZCMD(zone_num, subcmd).command != 'S'; subcmd++) {
|
||||
switch (ZCMD(zone_num, subcmd).command) {
|
||||
|
|
@ -416,49 +430,41 @@ int save_zone(zone_rnum zone_num)
|
|||
arg1 = mob_index[ZCMD(zone_num, subcmd).arg1].vnum;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = world[ZCMD(zone_num, subcmd).arg3].number;
|
||||
comment = mob_proto[ZCMD(zone_num, subcmd).arg1].player.short_descr;
|
||||
break;
|
||||
case 'O':
|
||||
arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = world[ZCMD(zone_num, subcmd).arg3].number;
|
||||
comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description;
|
||||
break;
|
||||
case 'G':
|
||||
arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = -1;
|
||||
comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description;
|
||||
break;
|
||||
case 'E':
|
||||
arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = ZCMD(zone_num, subcmd).arg3;
|
||||
comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description;
|
||||
break;
|
||||
case 'P':
|
||||
arg1 = obj_index[ZCMD(zone_num, subcmd).arg1].vnum;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = obj_index[ZCMD(zone_num, subcmd).arg3].vnum;
|
||||
comment = obj_proto[ZCMD(zone_num, subcmd).arg1].short_description;
|
||||
break;
|
||||
case 'D':
|
||||
arg1 = world[ZCMD(zone_num, subcmd).arg1].number;
|
||||
arg2 = ZCMD(zone_num, subcmd).arg2;
|
||||
arg3 = ZCMD(zone_num, subcmd).arg3;
|
||||
comment = world[ZCMD(zone_num, subcmd).arg1].name;
|
||||
break;
|
||||
case 'R':
|
||||
arg1 = world[ZCMD(zone_num, subcmd).arg1].number;
|
||||
arg2 = obj_index[ZCMD(zone_num, subcmd).arg2].vnum;
|
||||
comment = obj_proto[ZCMD(zone_num, subcmd).arg2].short_description;
|
||||
arg3 = -1;
|
||||
break;
|
||||
case 'T':
|
||||
arg1 = ZCMD(zone_num, subcmd).arg1; /* trigger type */
|
||||
arg2 = trig_index[ZCMD(zone_num, subcmd).arg2]->vnum; /* trigger vnum */
|
||||
arg3 = world[ZCMD(zone_num, subcmd).arg3].number; /* room num */
|
||||
comment = GET_TRIG_NAME(trig_index[real_trigger(arg2)]->proto);
|
||||
break;
|
||||
case 'V':
|
||||
arg1 = ZCMD(zone_num, subcmd).arg1; /* trigger type */
|
||||
|
|
@ -472,17 +478,20 @@ int save_zone(zone_rnum zone_num)
|
|||
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: OLC: z_save_to_disk(): Unknown cmd '%c' - NOT saving", ZCMD(zone_num, subcmd).command);
|
||||
continue;
|
||||
}
|
||||
if (ZCMD(zone_num, subcmd).command != 'V')
|
||||
fprintf(zfile, "%c %d %d %d %d \t(%s)\n",
|
||||
ZCMD(zone_num, subcmd).command, ZCMD(zone_num, subcmd).if_flag, arg1, arg2, arg3, comment);
|
||||
else
|
||||
fprintf(zfile, "%c %d %d %d %d %s %s\n",
|
||||
ZCMD(zone_num, subcmd).command, ZCMD(zone_num, subcmd).if_flag, arg1, arg2, arg3,
|
||||
ZCMD(zone_num, subcmd).sarg1, ZCMD(zone_num, subcmd).sarg2);
|
||||
fprintf(zfile, "\n[[zone.command]]\n");
|
||||
fprintf(zfile, "command = \"%c\"\n", ZCMD(zone_num, subcmd).command);
|
||||
fprintf(zfile, "if_flag = %d\n", ZCMD(zone_num, subcmd).if_flag);
|
||||
fprintf(zfile, "arg1 = %d\n", arg1);
|
||||
fprintf(zfile, "arg2 = %d\n", arg2);
|
||||
fprintf(zfile, "arg3 = %d\n", arg3);
|
||||
if (ZCMD(zone_num, subcmd).command == 'V') {
|
||||
toml_write_kv_string(zfile, "sarg1", ZCMD(zone_num, subcmd).sarg1 ? ZCMD(zone_num, subcmd).sarg1 : "");
|
||||
toml_write_kv_string(zfile, "sarg2", ZCMD(zone_num, subcmd).sarg2 ? ZCMD(zone_num, subcmd).sarg2 : "");
|
||||
}
|
||||
fprintf(zfile, "line = %d\n", ZCMD(zone_num, subcmd).line);
|
||||
}
|
||||
fputs("S\n$\n", zfile);
|
||||
fclose(zfile);
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.zon", ZON_PREFIX, zone_table[zone_num].number);
|
||||
snprintf(oldname, sizeof(oldname), "%s/%d.toml", ZON_PREFIX, zone_table[zone_num].number);
|
||||
remove(oldname);
|
||||
rename(fname, oldname);
|
||||
|
||||
|
|
@ -586,4 +595,3 @@ void delete_zone_command(struct zone_data *zone, int pos)
|
|||
/* Ok, let's zap it. */
|
||||
remove_cmd_from_list(&zone->cmd, pos);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static int House_get_filename(room_vnum vnum, char *filename, size_t maxlen)
|
|||
if (vnum == NOWHERE)
|
||||
return (0);
|
||||
|
||||
snprintf(filename, maxlen, LIB_HOUSE"%d.house", vnum);
|
||||
snprintf(filename, maxlen, LIB_HOUSE"%d.house.toml", vnum);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -710,8 +710,6 @@ static int ascii_convert_house(struct char_data *ch, obj_vnum vnum)
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(out, "$~\n");
|
||||
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
|
|
|
|||
529
src/objsave.c
529
src/objsave.c
|
|
@ -22,6 +22,8 @@
|
|||
#include "config.h"
|
||||
#include "modify.h"
|
||||
#include "genolc.h" /* for strip_cr and sprintascii */
|
||||
#include "toml.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
/* these factors should be unique integers */
|
||||
#define CRYO_FACTOR 4
|
||||
|
|
@ -37,106 +39,84 @@ static int Crash_load_objs(struct char_data *ch);
|
|||
static int handle_obj(struct obj_data *obj, struct char_data *ch, int locate, struct obj_data **cont_rows);
|
||||
static void Crash_write_header(struct char_data *ch, FILE *fp, int savecode);
|
||||
|
||||
static int toml_get_int_default(toml_table_t *tab, const char *key, int def)
|
||||
{
|
||||
toml_datum_t d = toml_int_in(tab, key);
|
||||
|
||||
if (!d.ok)
|
||||
return def;
|
||||
|
||||
return (int)d.u.i;
|
||||
}
|
||||
|
||||
static char *toml_get_string_dup(toml_table_t *tab, const char *key)
|
||||
{
|
||||
toml_datum_t d = toml_string_in(tab, key);
|
||||
|
||||
if (!d.ok)
|
||||
return NULL;
|
||||
|
||||
return d.u.s;
|
||||
}
|
||||
|
||||
static void toml_read_int_array(toml_array_t *arr, int *out, int out_count, int def)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < out_count; i++)
|
||||
out[i] = def;
|
||||
|
||||
if (!arr)
|
||||
return;
|
||||
|
||||
for (i = 0; i < out_count; i++) {
|
||||
toml_datum_t d = toml_int_at(arr, i);
|
||||
if (d.ok)
|
||||
out[i] = (int)d.u.i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes one object record to FILE. Old name: Obj_to_store().
|
||||
* Updated to save all NUM_OBJ_VAL_POSITIONS values instead of only 4. */
|
||||
int objsave_save_obj_record(struct obj_data *obj, FILE *fp, int locate)
|
||||
{
|
||||
int i;
|
||||
char buf1[MAX_STRING_LENGTH + 1];
|
||||
struct obj_data *temp = NULL;
|
||||
int out_locate = (locate > 0) ? locate : 0;
|
||||
int nest = (locate < 0) ? -locate : 0;
|
||||
|
||||
/* Build a prototype baseline to diff against so we only emit changed fields */
|
||||
if (GET_OBJ_VNUM(obj) != NOTHING)
|
||||
temp = read_object(GET_OBJ_VNUM(obj), VIRTUAL);
|
||||
else {
|
||||
temp = create_obj();
|
||||
temp->item_number = NOWHERE;
|
||||
fprintf(fp, "\n[[object]]\n");
|
||||
fprintf(fp, "vnum = %d\n", GET_OBJ_VNUM(obj));
|
||||
fprintf(fp, "locate = %d\n", out_locate);
|
||||
fprintf(fp, "nest = %d\n", nest);
|
||||
|
||||
fprintf(fp, "values = [");
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
if (i > 0)
|
||||
fputs(", ", fp);
|
||||
fprintf(fp, "%d", GET_OBJ_VAL(obj, i));
|
||||
}
|
||||
fprintf(fp, "]\n");
|
||||
|
||||
if (obj->main_description) {
|
||||
strcpy(buf1, obj->main_description);
|
||||
fprintf(fp, "extra_flags = [%d, %d, %d, %d]\n",
|
||||
GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1],
|
||||
GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);
|
||||
fprintf(fp, "wear_flags = [%d, %d, %d, %d]\n",
|
||||
GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1],
|
||||
GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);
|
||||
|
||||
toml_write_kv_string_opt(fp, "name", obj->name);
|
||||
toml_write_kv_string_opt(fp, "short", obj->short_description);
|
||||
toml_write_kv_string_opt(fp, "description", obj->description);
|
||||
if (obj->main_description && *obj->main_description) {
|
||||
strlcpy(buf1, obj->main_description, sizeof(buf1));
|
||||
strip_cr(buf1);
|
||||
} else
|
||||
*buf1 = 0;
|
||||
|
||||
/* Header and placement */
|
||||
fprintf(fp, "#%d\n", GET_OBJ_VNUM(obj));
|
||||
|
||||
/* Top-level worn slots are positive (1..NUM_WEARS); inventory is 0.
|
||||
* Children use negative numbers from Crash_save recursion (…,-1,-2,…) — we map that to Nest. */
|
||||
if (locate > 0)
|
||||
fprintf(fp, "Loc : %d\n", locate);
|
||||
|
||||
if (locate < 0) {
|
||||
int nest = -locate; /* e.g. -1 => Nest:1, -2 => Nest:2, etc. */
|
||||
fprintf(fp, "Nest: %d\n", nest);
|
||||
} else {
|
||||
fprintf(fp, "Nest: %d\n", 0); /* top-level object (inventory or worn) */
|
||||
toml_write_kv_string(fp, "main_description", buf1);
|
||||
}
|
||||
|
||||
/* Save all object values (diffed against proto) */
|
||||
{
|
||||
bool diff = FALSE;
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
if (GET_OBJ_VAL(obj, i) != GET_OBJ_VAL(temp, i)) {
|
||||
diff = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (diff) {
|
||||
fprintf(fp, "Vals:");
|
||||
for (i = 0; i < NUM_OBJ_VAL_POSITIONS; i++)
|
||||
fprintf(fp, " %d", GET_OBJ_VAL(obj, i));
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Extra flags (array words) */
|
||||
if (GET_OBJ_EXTRA(obj) != GET_OBJ_EXTRA(temp))
|
||||
fprintf(fp, "Flag: %d %d %d %d\n",
|
||||
GET_OBJ_EXTRA(obj)[0], GET_OBJ_EXTRA(obj)[1],
|
||||
GET_OBJ_EXTRA(obj)[2], GET_OBJ_EXTRA(obj)[3]);
|
||||
|
||||
/* Names/descriptions */
|
||||
if (obj->name && (!temp->name || strcmp(obj->name, temp->name)))
|
||||
fprintf(fp, "Name: %s\n", obj->name);
|
||||
if (obj->short_description && (!temp->short_description ||
|
||||
strcmp(obj->short_description, temp->short_description)))
|
||||
fprintf(fp, "Shrt: %s\n", obj->short_description);
|
||||
if (obj->description && (!temp->description ||
|
||||
strcmp(obj->description, temp->description)))
|
||||
fprintf(fp, "Desc: %s\n", obj->description);
|
||||
if (obj->main_description && (!temp->main_description ||
|
||||
strcmp(obj->main_description, temp->main_description)))
|
||||
fprintf(fp, "ADes:\n%s~\n", buf1);
|
||||
|
||||
/* Core fields */
|
||||
if (GET_OBJ_TYPE(obj) != GET_OBJ_TYPE(temp))
|
||||
fprintf(fp, "Type: %d\n", GET_OBJ_TYPE(obj));
|
||||
if (GET_OBJ_WEIGHT(obj) != GET_OBJ_WEIGHT(temp))
|
||||
fprintf(fp, "Wght: %d\n", GET_OBJ_WEIGHT(obj));
|
||||
if (GET_OBJ_COST(obj) != GET_OBJ_COST(temp))
|
||||
fprintf(fp, "Cost: %d\n", GET_OBJ_COST(obj));
|
||||
|
||||
/* Permanent affects (array words) */
|
||||
if (GET_OBJ_AFFECT(obj)[0] != GET_OBJ_AFFECT(temp)[0] ||
|
||||
GET_OBJ_AFFECT(obj)[1] != GET_OBJ_AFFECT(temp)[1] ||
|
||||
GET_OBJ_AFFECT(obj)[2] != GET_OBJ_AFFECT(temp)[2] ||
|
||||
GET_OBJ_AFFECT(obj)[3] != GET_OBJ_AFFECT(temp)[3])
|
||||
fprintf(fp, "Perm: %d %d %d %d\n",
|
||||
GET_OBJ_AFFECT(obj)[0], GET_OBJ_AFFECT(obj)[1],
|
||||
GET_OBJ_AFFECT(obj)[2], GET_OBJ_AFFECT(obj)[3]);
|
||||
|
||||
/* Wear flags (array words) */
|
||||
if (GET_OBJ_WEAR(obj)[0] != GET_OBJ_WEAR(temp)[0] ||
|
||||
GET_OBJ_WEAR(obj)[1] != GET_OBJ_WEAR(temp)[1] ||
|
||||
GET_OBJ_WEAR(obj)[2] != GET_OBJ_WEAR(temp)[2] ||
|
||||
GET_OBJ_WEAR(obj)[3] != GET_OBJ_WEAR(temp)[3])
|
||||
fprintf(fp, "Wear: %d %d %d %d\n",
|
||||
GET_OBJ_WEAR(obj)[0], GET_OBJ_WEAR(obj)[1],
|
||||
GET_OBJ_WEAR(obj)[2], GET_OBJ_WEAR(obj)[3]);
|
||||
|
||||
/* (If you also persist applies, extra descs, scripts, etc., keep that code here unchanged) */
|
||||
fprintf(fp, "type = %d\n", GET_OBJ_TYPE(obj));
|
||||
fprintf(fp, "weight = %d\n", GET_OBJ_WEIGHT(obj));
|
||||
fprintf(fp, "cost = %d\n", GET_OBJ_COST(obj));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -266,10 +246,11 @@ int Crash_delete_file(char *name)
|
|||
int Crash_delete_crashfile(struct char_data *ch)
|
||||
{
|
||||
char filename[MAX_INPUT_LENGTH];
|
||||
int numread;
|
||||
FILE *fl;
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_table_t *header = NULL;
|
||||
int savecode;
|
||||
char line[READ_SIZE];
|
||||
|
||||
if (!get_filename(filename, sizeof(filename), CRASH_FILE, GET_NAME(ch)))
|
||||
return FALSE;
|
||||
|
|
@ -279,12 +260,19 @@ int Crash_delete_crashfile(struct char_data *ch)
|
|||
log("SYSERR: checking for crash file %s (3): %s", filename, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
numread = get_line(fl,line);
|
||||
tab = toml_parse_file(fl, errbuf, sizeof(errbuf));
|
||||
fclose(fl);
|
||||
|
||||
if (numread == FALSE)
|
||||
if (!tab)
|
||||
return FALSE;
|
||||
sscanf(line,"%d ",&savecode);
|
||||
|
||||
header = toml_table_in(tab, "header");
|
||||
if (!header) {
|
||||
toml_free(tab);
|
||||
return FALSE;
|
||||
}
|
||||
savecode = toml_get_int_default(header, "save_code", SAVE_UNDEF);
|
||||
toml_free(tab);
|
||||
|
||||
if (savecode == SAVE_CRASH)
|
||||
Crash_delete_file(GET_NAME(ch));
|
||||
|
|
@ -295,10 +283,11 @@ int Crash_delete_crashfile(struct char_data *ch)
|
|||
int Crash_clean_file(char *name)
|
||||
{
|
||||
char filename[MAX_INPUT_LENGTH], filetype[20];
|
||||
int numread;
|
||||
FILE *fl;
|
||||
int savecode, timed, netcost, coins, account, nitems;
|
||||
char line[READ_SIZE];
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_table_t *header = NULL;
|
||||
int savecode, timed;
|
||||
|
||||
if (!get_filename(filename, sizeof(filename), CRASH_FILE, name))
|
||||
return FALSE;
|
||||
|
|
@ -310,13 +299,20 @@ int Crash_clean_file(char *name)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
numread = get_line(fl,line);
|
||||
tab = toml_parse_file(fl, errbuf, sizeof(errbuf));
|
||||
fclose(fl);
|
||||
if (numread == FALSE)
|
||||
if (!tab)
|
||||
return FALSE;
|
||||
|
||||
sscanf(line, "%d %d %d %d %d %d",&savecode,&timed,&netcost,
|
||||
&coins,&account,&nitems);
|
||||
header = toml_table_in(tab, "header");
|
||||
if (!header) {
|
||||
toml_free(tab);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
savecode = toml_get_int_default(header, "save_code", SAVE_UNDEF);
|
||||
timed = toml_get_int_default(header, "timed", 0);
|
||||
toml_free(tab);
|
||||
|
||||
if ((savecode == SAVE_CRASH) ||
|
||||
(savecode == SAVE_LOGOUT) ||
|
||||
|
|
@ -403,7 +399,13 @@ static void Crash_write_header(struct char_data *ch, FILE *fp, int savecode)
|
|||
int account = ch ? GET_BANK_COINS(ch) : 0;
|
||||
int nitems = 0;
|
||||
|
||||
fprintf(fp, "%d %d %d %d %d %d\n", savecode, timed, netcost, coins, account, nitems);
|
||||
fprintf(fp, "[header]\n");
|
||||
fprintf(fp, "save_code = %d\n", savecode);
|
||||
fprintf(fp, "timed = %d\n", timed);
|
||||
fprintf(fp, "net_cost = %d\n", netcost);
|
||||
fprintf(fp, "coins = %d\n", coins);
|
||||
fprintf(fp, "account = %d\n", account);
|
||||
fprintf(fp, "item_count = %d\n", nitems);
|
||||
}
|
||||
|
||||
void Crash_crashsave(struct char_data *ch)
|
||||
|
|
@ -438,7 +440,6 @@ void Crash_crashsave(struct char_data *ch)
|
|||
}
|
||||
Crash_restore_weight(ch->carrying);
|
||||
|
||||
fprintf(fp, "$~\n");
|
||||
fclose(fp);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_CRASH);
|
||||
}
|
||||
|
|
@ -476,7 +477,6 @@ void Crash_idlesave(struct char_data *ch)
|
|||
}
|
||||
Crash_restore_weight(ch->carrying);
|
||||
|
||||
fprintf(fp, "$~\n");
|
||||
fclose(fp);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_CRASH);
|
||||
}
|
||||
|
|
@ -514,7 +514,6 @@ void Crash_rentsave(struct char_data *ch, int cost)
|
|||
}
|
||||
Crash_restore_weight(ch->carrying);
|
||||
|
||||
fprintf(fp, "$~\n");
|
||||
fclose(fp);
|
||||
REMOVE_BIT_AR(PLR_FLAGS(ch), PLR_CRASH);
|
||||
}
|
||||
|
|
@ -553,100 +552,32 @@ void Crash_save_all(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Load all objects from file into memory. Updated to load NUM_OBJ_VAL_POSITIONS values. */
|
||||
obj_save_data *objsave_parse_objects(FILE *fl)
|
||||
/* Load all objects from TOML into memory. */
|
||||
static obj_save_data *objsave_parse_objects_from_toml(toml_table_t *tab, const char *filename)
|
||||
{
|
||||
char line[MAX_STRING_LENGTH];
|
||||
|
||||
obj_save_data *head = NULL, *tail = NULL;
|
||||
toml_array_t *arr = NULL;
|
||||
int count, i;
|
||||
|
||||
/* State for the object we’re currently assembling */
|
||||
struct obj_data *temp = NULL;
|
||||
int pending_locate = 0; /* 0 = inventory, 1..NUM_WEARS = worn slot */
|
||||
int pending_nest = 0; /* 0 = top-level; >0 = inside container at level-1 */
|
||||
arr = toml_array_in(tab, "object");
|
||||
if (!arr)
|
||||
return NULL;
|
||||
|
||||
/* --- helpers (GCC nested functions OK in tbaMUD build) ---------------- */
|
||||
count = toml_array_nelem(arr);
|
||||
for (i = 0; i < count; i++) {
|
||||
toml_table_t *obj_tab = toml_table_at(arr, i);
|
||||
struct obj_data *temp = NULL;
|
||||
int locate, nest;
|
||||
int values[NUM_OBJ_VAL_POSITIONS];
|
||||
int flags[4];
|
||||
char *str = NULL;
|
||||
|
||||
/* append current object to the result list with proper locate */
|
||||
void commit_current(void) {
|
||||
if (!temp) return;
|
||||
if (!obj_tab)
|
||||
continue;
|
||||
|
||||
if (GET_OBJ_TYPE(temp) == ITEM_MONEY)
|
||||
update_money_obj(temp);
|
||||
|
||||
/* sanitize top-level locate range only; children will be negative later */
|
||||
int loc = pending_locate;
|
||||
if (pending_nest <= 0) {
|
||||
if (loc < 0 || loc > NUM_WEARS) {
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SAVE-LOAD: bad locate %d for vnum %d; defaulting to inventory.",
|
||||
loc, GET_OBJ_VNUM(temp));
|
||||
loc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert Nest>0 into negative locate for handle_obj()/cont_row */
|
||||
int effective_loc = (pending_nest > 0) ? -pending_nest : loc;
|
||||
|
||||
obj_save_data *node = NULL;
|
||||
CREATE(node, obj_save_data, 1);
|
||||
node->obj = temp;
|
||||
node->locate = effective_loc;
|
||||
node->next = NULL;
|
||||
|
||||
if (!head) head = node, tail = node;
|
||||
else tail->next = node, tail = node;
|
||||
|
||||
temp = NULL;
|
||||
pending_locate = 0;
|
||||
pending_nest = 0;
|
||||
}
|
||||
|
||||
/* split a line into normalized tag (no colon) and payload pointer */
|
||||
void split_tag_line(const char *src, char tag_out[6], const char **payload_out) {
|
||||
const char *s = src;
|
||||
|
||||
while (*s && isspace((unsigned char)*s)) s++; /* skip leading ws */
|
||||
|
||||
const char *te = s;
|
||||
while (*te && !isspace((unsigned char)*te) && *te != ':') te++;
|
||||
|
||||
size_t tlen = (size_t)(te - s);
|
||||
if (tlen > 5) tlen = 5;
|
||||
memcpy(tag_out, s, tlen);
|
||||
tag_out[tlen] = '\0';
|
||||
|
||||
const char *p = te;
|
||||
while (*p && isspace((unsigned char)*p)) p++;
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
while (*p && isspace((unsigned char)*p)) p++;
|
||||
}
|
||||
*payload_out = p;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
while (get_line(fl, line)) {
|
||||
if (!*line) continue;
|
||||
|
||||
/* New object header: "#<vnum>" (commit any previous one first) */
|
||||
if (*line == '#') {
|
||||
if (temp) commit_current();
|
||||
|
||||
long vnum = -1L;
|
||||
vnum = strtol(line + 1, NULL, 10);
|
||||
|
||||
if (vnum <= 0 && vnum != -1L) {
|
||||
mudlog(NRM, LVL_IMMORT, TRUE, "SAVE-LOAD: bad vnum header: '%s'", line);
|
||||
temp = NULL;
|
||||
pending_locate = 0;
|
||||
pending_nest = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Instantiate from prototype if available, else create a blank */
|
||||
if (vnum == -1L) {
|
||||
{
|
||||
int vnum = toml_get_int_default(obj_tab, "vnum", -1);
|
||||
if (vnum == -1) {
|
||||
temp = create_obj();
|
||||
temp->item_number = NOTHING;
|
||||
if (!temp->name) temp->name = strdup("object");
|
||||
|
|
@ -658,133 +589,122 @@ obj_save_data *objsave_parse_objects(FILE *fl)
|
|||
temp = read_object(rnum, REAL);
|
||||
} else {
|
||||
temp = create_obj();
|
||||
/* Do NOT assign GET_OBJ_VNUM(temp); item_number derives vnum. */
|
||||
if (!temp->name) temp->name = strdup("object");
|
||||
if (!temp->short_description) temp->short_description = strdup("an object");
|
||||
if (!temp->description) temp->description = strdup("An object lies here.");
|
||||
}
|
||||
}
|
||||
|
||||
pending_locate = 0;
|
||||
pending_nest = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Normal data line: TAG [ : ] payload */
|
||||
char tag[6];
|
||||
const char *payload = NULL;
|
||||
split_tag_line(line, tag, &payload);
|
||||
locate = toml_get_int_default(obj_tab, "locate", 0);
|
||||
if (locate < 0 || locate > NUM_WEARS)
|
||||
locate = 0;
|
||||
|
||||
if (!*tag) continue;
|
||||
if (!temp) {
|
||||
mudlog(NRM, LVL_IMMORT, TRUE, "SAVE-LOAD: data before header ignored: '%s'", line);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(tag, "Loc")) {
|
||||
pending_locate = (int)strtol(payload, NULL, 10);
|
||||
}
|
||||
else if (!strcmp(tag, "Nest")) {
|
||||
pending_nest = (int)strtol(payload, NULL, 10);
|
||||
if (pending_nest < 0) pending_nest = 0;
|
||||
if (pending_nest > MAX_BAG_ROWS) {
|
||||
nest = toml_get_int_default(obj_tab, "nest", 0);
|
||||
if (nest < 0)
|
||||
nest = 0;
|
||||
if (nest > MAX_BAG_ROWS) {
|
||||
if (filename)
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SAVE-LOAD: nest level %d too deep in %s; clamping to %d.",
|
||||
nest, filename, MAX_BAG_ROWS);
|
||||
else
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SAVE-LOAD: nest level %d too deep; clamping to %d.",
|
||||
pending_nest, MAX_BAG_ROWS);
|
||||
pending_nest = MAX_BAG_ROWS;
|
||||
}
|
||||
nest, MAX_BAG_ROWS);
|
||||
nest = MAX_BAG_ROWS;
|
||||
}
|
||||
else if (!strcmp(tag, "Vals")) {
|
||||
const char *p = payload;
|
||||
for (int i = 0; i < NUM_OBJ_VAL_POSITIONS; i++) {
|
||||
if (!*p) { GET_OBJ_VAL(temp, i) = 0; continue; }
|
||||
GET_OBJ_VAL(temp, i) = (int)strtol(p, (char **)&p, 10);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(tag, "Wght")) {
|
||||
GET_OBJ_WEIGHT(temp) = (int)strtol(payload, NULL, 10);
|
||||
}
|
||||
else if (!strcmp(tag, "Cost")) {
|
||||
GET_OBJ_COST(temp) = (int)strtol(payload, NULL, 10);
|
||||
}
|
||||
else if (!strcmp(tag, "Rent")) {
|
||||
/* Legacy tag ignored (cost-per-day no longer used). */
|
||||
}
|
||||
else if (!strcmp(tag, "Type")) {
|
||||
GET_OBJ_TYPE(temp) = (int)strtol(payload, NULL, 10);
|
||||
}
|
||||
else if (!strcmp(tag, "Wear")) {
|
||||
unsigned long words[4] = {0,0,0,0};
|
||||
const char *p = payload;
|
||||
for (int i = 0; i < 4 && *p; i++) words[i] = strtoul(p, (char **)&p, 10);
|
||||
|
||||
#if defined(TW_ARRAY_MAX) && defined(GET_OBJ_WEAR_AR)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i < TW_ARRAY_MAX) GET_OBJ_WEAR_AR(temp, i) = (bitvector_t)words[i];
|
||||
else if (words[i])
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SAVE-LOAD: Wear word %d (%lu) truncated (TW_ARRAY_MAX=%d).",
|
||||
i, words[i], TW_ARRAY_MAX);
|
||||
}
|
||||
#elif defined(GET_OBJ_WEAR_AR)
|
||||
for (int i = 0; i < 4; i++) GET_OBJ_WEAR_AR(temp, i) = (bitvector_t)words[i];
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp(tag, "Flag")) {
|
||||
unsigned long words[4] = {0,0,0,0};
|
||||
const char *p = payload;
|
||||
for (int i = 0; i < 4 && *p; i++) words[i] = strtoul(p, (char **)&p, 10);
|
||||
toml_read_int_array(toml_array_in(obj_tab, "values"), values, NUM_OBJ_VAL_POSITIONS, 0);
|
||||
for (int j = 0; j < NUM_OBJ_VAL_POSITIONS; j++)
|
||||
GET_OBJ_VAL(temp, j) = values[j];
|
||||
|
||||
#if defined(EF_ARRAY_MAX) && defined(GET_OBJ_EXTRA_AR)
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i < EF_ARRAY_MAX) GET_OBJ_EXTRA_AR(temp, i) = (bitvector_t)words[i];
|
||||
else if (words[i])
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SAVE-LOAD: Extra word %d (%lu) truncated (EF_ARRAY_MAX=%d).",
|
||||
i, words[i], EF_ARRAY_MAX);
|
||||
}
|
||||
#elif defined(GET_OBJ_EXTRA_AR)
|
||||
for (int i = 0; i < 4; i++) GET_OBJ_EXTRA_AR(temp, i) = (bitvector_t)words[i];
|
||||
#endif
|
||||
toml_read_int_array(toml_array_in(obj_tab, "extra_flags"), flags, 4, 0);
|
||||
for (int j = 0; j < 4; j++)
|
||||
GET_OBJ_EXTRA(temp)[j] = flags[j];
|
||||
|
||||
toml_read_int_array(toml_array_in(obj_tab, "wear_flags"), flags, 4, 0);
|
||||
for (int j = 0; j < 4; j++)
|
||||
GET_OBJ_WEAR(temp)[j] = flags[j];
|
||||
|
||||
str = toml_get_string_dup(obj_tab, "name");
|
||||
if (str) {
|
||||
if (temp->name)
|
||||
free(temp->name);
|
||||
temp->name = str;
|
||||
}
|
||||
else if (!strcmp(tag, "Name")) {
|
||||
if (temp->name) free(temp->name);
|
||||
temp->name = *payload ? strdup(payload) : strdup("object");
|
||||
|
||||
str = toml_get_string_dup(obj_tab, "short");
|
||||
if (str) {
|
||||
if (temp->short_description)
|
||||
free(temp->short_description);
|
||||
temp->short_description = str;
|
||||
}
|
||||
else if (!strcmp(tag, "Shrt")) {
|
||||
if (temp->short_description) free(temp->short_description);
|
||||
temp->short_description = *payload ? strdup(payload) : strdup("an object");
|
||||
|
||||
str = toml_get_string_dup(obj_tab, "description");
|
||||
if (str) {
|
||||
if (temp->description)
|
||||
free(temp->description);
|
||||
temp->description = str;
|
||||
}
|
||||
else if (!strcmp(tag, "Desc")) {
|
||||
if (temp->description) free(temp->description);
|
||||
temp->description = *payload ? strdup(payload) : strdup("An object lies here.");
|
||||
|
||||
str = toml_get_string_dup(obj_tab, "main_description");
|
||||
if (str) {
|
||||
if (temp->main_description)
|
||||
free(temp->main_description);
|
||||
temp->main_description = str;
|
||||
}
|
||||
else if (!strcmp(tag, "ADes")) {
|
||||
if (temp->main_description) free(temp->main_description);
|
||||
temp->main_description = *payload ? strdup(payload) : NULL;
|
||||
}
|
||||
else if (!strcmp(tag, "End")) {
|
||||
commit_current();
|
||||
}
|
||||
else {
|
||||
mudlog(NRM, LVL_IMMORT, TRUE, "SAVE-LOAD: unknown tag '%s'", tag);
|
||||
|
||||
GET_OBJ_TYPE(temp) = toml_get_int_default(obj_tab, "type", GET_OBJ_TYPE(temp));
|
||||
GET_OBJ_WEIGHT(temp) = toml_get_int_default(obj_tab, "weight", GET_OBJ_WEIGHT(temp));
|
||||
GET_OBJ_COST(temp) = toml_get_int_default(obj_tab, "cost", GET_OBJ_COST(temp));
|
||||
|
||||
if (GET_OBJ_TYPE(temp) == ITEM_MONEY)
|
||||
update_money_obj(temp);
|
||||
|
||||
{
|
||||
int effective_loc = (nest > 0) ? -nest : locate;
|
||||
obj_save_data *node = NULL;
|
||||
CREATE(node, obj_save_data, 1);
|
||||
node->obj = temp;
|
||||
node->locate = effective_loc;
|
||||
node->next = NULL;
|
||||
|
||||
if (!head)
|
||||
head = node, tail = node;
|
||||
else
|
||||
tail->next = node, tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp) commit_current();
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
obj_save_data *objsave_parse_objects(FILE *fl)
|
||||
{
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = toml_parse_file(fl, errbuf, sizeof(errbuf));
|
||||
obj_save_data *list = NULL;
|
||||
|
||||
if (!tab)
|
||||
return NULL;
|
||||
|
||||
list = objsave_parse_objects_from_toml(tab, NULL);
|
||||
toml_free(tab);
|
||||
return list;
|
||||
}
|
||||
|
||||
static int Crash_load_objs(struct char_data *ch) {
|
||||
FILE *fl;
|
||||
char filename[PATH_MAX];
|
||||
char line[READ_SIZE];
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
int i, orig_save_code, num_objs=0;
|
||||
struct obj_data *cont_row[MAX_BAG_ROWS];
|
||||
int savecode = SAVE_UNDEF;
|
||||
int timed=0,netcost=0,coins,account,nitems;
|
||||
int timed=0,netcost=0,coins=0,account=0,nitems=0;
|
||||
char errbuf[256];
|
||||
toml_table_t *tab = NULL;
|
||||
toml_table_t *header = NULL;
|
||||
obj_save_data *loaded, *current;
|
||||
|
||||
if (!get_filename(filename, sizeof(filename), CRASH_FILE, GET_NAME(ch)))
|
||||
|
|
@ -810,10 +730,28 @@ static int Crash_load_objs(struct char_data *ch) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (!get_line(fl, line))
|
||||
mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE, "Failed to read player's save code: %s.", GET_NAME(ch));
|
||||
else
|
||||
sscanf(line,"%d %d %d %d %d %d",&savecode, &timed, &netcost,&coins,&account,&nitems);
|
||||
tab = toml_parse_file(fl, errbuf, sizeof(errbuf));
|
||||
fclose(fl);
|
||||
if (!tab) {
|
||||
mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE,
|
||||
"Failed to parse player's object file %s: %s.", filename, errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
header = toml_table_in(tab, "header");
|
||||
if (!header) {
|
||||
mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE,
|
||||
"Player object file %s missing header.", filename);
|
||||
toml_free(tab);
|
||||
return 1;
|
||||
}
|
||||
|
||||
savecode = toml_get_int_default(header, "save_code", SAVE_UNDEF);
|
||||
timed = toml_get_int_default(header, "timed", 0);
|
||||
netcost = toml_get_int_default(header, "net_cost", 0);
|
||||
coins = toml_get_int_default(header, "coins", 0);
|
||||
account = toml_get_int_default(header, "account", 0);
|
||||
nitems = toml_get_int_default(header, "item_count", 0);
|
||||
|
||||
if (savecode == SAVE_LOGOUT || savecode == SAVE_TIMEDOUT) {
|
||||
mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(ch)), TRUE,
|
||||
|
|
@ -844,7 +782,8 @@ static int Crash_load_objs(struct char_data *ch) {
|
|||
break;
|
||||
}
|
||||
|
||||
loaded = objsave_parse_objects(fl);
|
||||
loaded = objsave_parse_objects_from_toml(tab, filename);
|
||||
toml_free(tab);
|
||||
for (current = loaded; current != NULL; current=current->next)
|
||||
num_objs += handle_obj(current->obj, ch, current->locate, cont_row);
|
||||
|
||||
|
|
@ -874,8 +813,6 @@ static int Crash_load_objs(struct char_data *ch) {
|
|||
mudlog(NRM, MAX(LVL_GOD, GET_INVIS_LEV(ch)), TRUE, "%s (level %d) has %d object%s.",
|
||||
GET_NAME(ch), GET_LEVEL(ch), num_objs, num_objs != 1 ? "s" : "");
|
||||
|
||||
fclose(fl);
|
||||
|
||||
if ((orig_save_code == SAVE_LOGOUT) || (orig_save_code == SAVE_CRYO))
|
||||
return 0;
|
||||
else
|
||||
|
|
|
|||
917
src/players.c
917
src/players.c
File diff suppressed because it is too large
Load diff
260
src/shop.c
260
src/shop.c
|
|
@ -25,6 +25,17 @@
|
|||
#include "modify.h"
|
||||
#include "spells.h" /* for skill_name() */
|
||||
#include "screen.h"
|
||||
#include "toml.h"
|
||||
|
||||
static char *toml_get_string_dup(toml_table_t *tab, const char *key)
|
||||
{
|
||||
toml_datum_t d = toml_string_in(tab, key);
|
||||
|
||||
if (!d.ok)
|
||||
return NULL;
|
||||
|
||||
return d.u.s;
|
||||
}
|
||||
|
||||
/* Global variables definitions used externally */
|
||||
/* Constant list for printing out who we sell to */
|
||||
|
|
@ -57,9 +68,11 @@ static int top(struct stack_data *stack); /**< @todo Move to utils.c */
|
|||
static int pop(struct stack_data *stack); /**< @todo Move to utils.c */
|
||||
static char *list_object(struct obj_data *obj, int cnt, int oindex, int shop_nr, struct char_data *keeper, struct char_data *seller);
|
||||
static void sort_keeper_objs(struct char_data *keeper, int shop_nr);
|
||||
#if 0
|
||||
static char *read_shop_message(int mnum, room_vnum shr, FILE *shop_f, const char *why);
|
||||
static int read_type_list(FILE *shop_f, struct shop_buy_data *list, int new_format, int max);
|
||||
static int read_list(FILE *shop_f, struct shop_buy_data *list, int new_format, int max, int type);
|
||||
#endif
|
||||
static void shopping_list(char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr);
|
||||
static void shopping_value(char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr);
|
||||
static void shopping_sell(char *arg, struct char_data *ch, struct char_data *keeper, int shop_nr);
|
||||
|
|
@ -78,6 +91,22 @@ static int is_ok(struct char_data *keeper, struct char_data *ch, int shop_nr);
|
|||
static void evaluate_operation(struct stack_data *ops, struct stack_data *vals);
|
||||
static int find_oper_num(char token);
|
||||
static int evaluate_expression(struct obj_data *obj, char *expr);
|
||||
|
||||
static float toml_get_float_default(toml_table_t *tab, const char *key, float def)
|
||||
{
|
||||
toml_datum_t v = toml_double_in(tab, key);
|
||||
if (!v.ok)
|
||||
return def;
|
||||
return (float)v.u.d;
|
||||
}
|
||||
|
||||
static int toml_get_int_default(toml_table_t *tab, const char *key, int def)
|
||||
{
|
||||
toml_datum_t v = toml_int_in(tab, key);
|
||||
if (!v.ok)
|
||||
return def;
|
||||
return (int)v.u.i;
|
||||
}
|
||||
static int trade_with(struct obj_data *item, int shop_nr);
|
||||
static int same_obj(struct obj_data *obj1, struct obj_data *obj2);
|
||||
static int shop_producing(struct obj_data *item, int shop_nr);
|
||||
|
|
@ -86,9 +115,11 @@ static char *times_message(struct obj_data *obj, char *name, int num);
|
|||
static int buy_price(struct obj_data *obj, int shop_nr, struct char_data *keeper, struct char_data *buyer);
|
||||
static int sell_price(struct obj_data *obj, int shop_nr, struct char_data *keeper, struct char_data *seller);
|
||||
static int ok_shop_room(int shop_nr, room_vnum room);
|
||||
#if 0
|
||||
static int add_to_shop_list(struct shop_buy_data *list, int type, int *len, int *val);
|
||||
static int end_read_list(struct shop_buy_data *list, int len, int error);
|
||||
static void read_line(FILE *shop_f, const char *string, void *data);
|
||||
#endif
|
||||
|
||||
/* Local file scope only variables */
|
||||
static int cmd_say;
|
||||
|
|
@ -1104,6 +1135,7 @@ int ok_damage_shopkeeper(struct char_data *ch, struct char_data *victim)
|
|||
}
|
||||
|
||||
/* val == obj_vnum and obj_rnum (?) */
|
||||
#if 0
|
||||
static int add_to_shop_list(struct shop_buy_data *list, int type, int *len, int *val)
|
||||
{
|
||||
if (*val != NOTHING && *val >= 0) { /* necessary after changing to unsigned v/rnums -- Welcor */
|
||||
|
|
@ -1140,7 +1172,9 @@ static void read_line(FILE *shop_f, const char *string, void *data)
|
|||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static int read_list(FILE *shop_f, struct shop_buy_data *list, int new_format,
|
||||
int max, int type)
|
||||
{
|
||||
|
|
@ -1160,7 +1194,9 @@ static int read_list(FILE *shop_f, struct shop_buy_data *list, int new_format,
|
|||
}
|
||||
return (end_read_list(list, len, error));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* END_OF inefficient. */
|
||||
static int read_type_list(FILE *shop_f, struct shop_buy_data *list,
|
||||
int new_format, int max)
|
||||
|
|
@ -1251,76 +1287,172 @@ static char *read_shop_message(int mnum, room_vnum shr, FILE *shop_f, const char
|
|||
}
|
||||
return (tbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *dup_shop_message(int mnum, room_vnum shr, const char *msg)
|
||||
{
|
||||
int cht, ss = 0, ds = 0, err = 0;
|
||||
char *tbuf;
|
||||
|
||||
if (!msg || !*msg)
|
||||
return NULL;
|
||||
|
||||
tbuf = strdup(msg);
|
||||
for (cht = 0; tbuf[cht]; cht++) {
|
||||
if (tbuf[cht] != '%')
|
||||
continue;
|
||||
|
||||
if (tbuf[cht + 1] == 's')
|
||||
ss++;
|
||||
else if (tbuf[cht + 1] == 'd' && (mnum == 5 || mnum == 6)) {
|
||||
if (ss == 0) {
|
||||
log("SYSERR: Shop #%d has %%d before %%s, message #%d.", shr, mnum);
|
||||
err++;
|
||||
}
|
||||
ds++;
|
||||
} else if (tbuf[cht + 1] != '%') {
|
||||
log("SYSERR: Shop #%d has invalid format '%%%c' in message #%d.", shr, tbuf[cht + 1], mnum);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss > 1 || ds > 1) {
|
||||
log("SYSERR: Shop #%d has too many specifiers for message #%d. %%s=%d %%d=%d", shr, mnum, ss, ds);
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
free(tbuf);
|
||||
return NULL;
|
||||
}
|
||||
return (tbuf);
|
||||
}
|
||||
|
||||
void boot_the_shops(FILE *shop_f, char *filename, int rec_count)
|
||||
{
|
||||
char *buf, buf2[256];
|
||||
int temp, count, new_format = FALSE;
|
||||
struct shop_buy_data list[MAX_SHOP_OBJ + 1];
|
||||
int done = FALSE;
|
||||
FILE *fp;
|
||||
toml_table_t *tab;
|
||||
toml_array_t *shops;
|
||||
char errbuf[200];
|
||||
int i;
|
||||
|
||||
snprintf(buf2, sizeof(buf2), "beginning of shop file %s", filename);
|
||||
(void)shop_f;
|
||||
|
||||
while (!done) {
|
||||
buf = fread_string(shop_f, buf2);
|
||||
if (*buf == '#') { /* New shop */
|
||||
sscanf(buf, "#%d\n", &temp);
|
||||
snprintf(buf2, sizeof(buf2), "shop #%d in shop file %s", temp, filename);
|
||||
free(buf); /* Plug memory leak! */
|
||||
top_shop++;
|
||||
if (!top_shop)
|
||||
CREATE(shop_index, struct shop_data, rec_count);
|
||||
SHOP_NUM(top_shop) = temp;
|
||||
temp = read_list(shop_f, list, new_format, MAX_PROD, LIST_PRODUCE);
|
||||
CREATE(shop_index[top_shop].producing, obj_vnum, temp);
|
||||
for (count = 0; count < temp; count++)
|
||||
SHOP_PRODUCT(top_shop, count) = BUY_TYPE(list[count]);
|
||||
|
||||
read_line(shop_f, "%f", &SHOP_BUYPROFIT(top_shop));
|
||||
read_line(shop_f, "%f", &SHOP_SELLPROFIT(top_shop));
|
||||
|
||||
temp = read_type_list(shop_f, list, new_format, MAX_TRADE);
|
||||
CREATE(shop_index[top_shop].type, struct shop_buy_data, temp);
|
||||
for (count = 0; count < temp; count++) {
|
||||
SHOP_BUYTYPE(top_shop, count) = BUY_TYPE(list[count]);
|
||||
SHOP_BUYWORD(top_shop, count) = BUY_WORD(list[count]);
|
||||
}
|
||||
|
||||
shop_index[top_shop].no_such_item1 = read_shop_message(0, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].no_such_item2 = read_shop_message(1, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].do_not_buy = read_shop_message(2, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].missing_cash1 = read_shop_message(3, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].missing_cash2 = read_shop_message(4, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].message_buy = read_shop_message(5, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
shop_index[top_shop].message_sell = read_shop_message(6, SHOP_NUM(top_shop), shop_f, buf2);
|
||||
read_line(shop_f, "%d", &SHOP_BROKE_TEMPER(top_shop));
|
||||
read_line(shop_f, "%ld", &SHOP_BITVECTOR(top_shop));
|
||||
read_line(shop_f, "%d", &SHOP_KEEPER(top_shop));
|
||||
|
||||
SHOP_KEEPER(top_shop) = real_mobile(SHOP_KEEPER(top_shop));
|
||||
read_line(shop_f, "%d", &SHOP_TRADE_WITH(top_shop));
|
||||
|
||||
temp = read_list(shop_f, list, new_format, 1, LIST_ROOM);
|
||||
CREATE(shop_index[top_shop].in_room, room_vnum, temp);
|
||||
for (count = 0; count < temp; count++)
|
||||
SHOP_ROOM(top_shop, count) = BUY_TYPE(list[count]);
|
||||
|
||||
read_line(shop_f, "%d", &SHOP_OPEN1(top_shop));
|
||||
read_line(shop_f, "%d", &SHOP_CLOSE1(top_shop));
|
||||
read_line(shop_f, "%d", &SHOP_OPEN2(top_shop));
|
||||
read_line(shop_f, "%d", &SHOP_CLOSE2(top_shop));
|
||||
|
||||
SHOP_BANK(top_shop) = 0;
|
||||
SHOP_SORT(top_shop) = 0;
|
||||
SHOP_FUNC(top_shop) = NULL;
|
||||
} else {
|
||||
if (*buf == '$') /* EOF */
|
||||
done = TRUE;
|
||||
else if (strstr(buf, VERSION3_TAG)) /* New format marker */
|
||||
new_format = TRUE;
|
||||
free(buf); /* Plug memory leak! */
|
||||
}
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
log("SYSERR: %s: %s", filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tab = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
fclose(fp);
|
||||
if (!tab) {
|
||||
log("SYSERR: parsing file '%s': %s", filename, errbuf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
shops = toml_array_in(tab, "shop");
|
||||
if (!shops) {
|
||||
toml_free(tab);
|
||||
log("SYSERR: TOML file '%s' missing 'shop' array.", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < toml_array_nelem(shops); i++) {
|
||||
toml_table_t *shop_tab = toml_table_at(shops, i);
|
||||
toml_array_t *arr;
|
||||
toml_table_t *msgs;
|
||||
int count, temp;
|
||||
|
||||
if (!shop_tab)
|
||||
continue;
|
||||
|
||||
top_shop++;
|
||||
if (!top_shop)
|
||||
CREATE(shop_index, struct shop_data, rec_count);
|
||||
|
||||
SHOP_NUM(top_shop) = toml_get_int_default(shop_tab, "vnum", 0);
|
||||
|
||||
arr = toml_array_in(shop_tab, "products");
|
||||
temp = arr ? toml_array_nelem(arr) : 0;
|
||||
CREATE(shop_index[top_shop].producing, obj_vnum, temp + 1);
|
||||
for (count = 0; count < temp; count++) {
|
||||
toml_datum_t v = toml_int_at(arr, count);
|
||||
SHOP_PRODUCT(top_shop, count) = v.ok ? (obj_vnum)v.u.i : NOTHING;
|
||||
}
|
||||
SHOP_PRODUCT(top_shop, temp) = NOTHING;
|
||||
|
||||
SHOP_BUYPROFIT(top_shop) = toml_get_float_default(shop_tab, "buy_profit", 0.0f);
|
||||
SHOP_SELLPROFIT(top_shop) = toml_get_float_default(shop_tab, "sell_profit", 0.0f);
|
||||
|
||||
arr = toml_array_in(shop_tab, "buy_type");
|
||||
temp = arr ? toml_array_nelem(arr) : 0;
|
||||
CREATE(shop_index[top_shop].type, struct shop_buy_data, temp + 1);
|
||||
for (count = 0; count < temp; count++) {
|
||||
toml_table_t *bt_tab = toml_table_at(arr, count);
|
||||
int t = NOTHING;
|
||||
char *word = NULL;
|
||||
if (bt_tab) {
|
||||
t = toml_get_int_default(bt_tab, "type", NOTHING);
|
||||
word = toml_get_string_dup(bt_tab, "keyword");
|
||||
}
|
||||
SHOP_BUYTYPE(top_shop, count) = t;
|
||||
SHOP_BUYWORD(top_shop, count) = word;
|
||||
}
|
||||
SHOP_BUYTYPE(top_shop, temp) = NOTHING;
|
||||
SHOP_BUYWORD(top_shop, temp) = NULL;
|
||||
|
||||
msgs = toml_table_in(shop_tab, "messages");
|
||||
if (msgs) {
|
||||
char *msg;
|
||||
msg = toml_get_string_dup(msgs, "no_such_item1");
|
||||
shop_index[top_shop].no_such_item1 = dup_shop_message(0, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "no_such_item2");
|
||||
shop_index[top_shop].no_such_item2 = dup_shop_message(1, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "do_not_buy");
|
||||
shop_index[top_shop].do_not_buy = dup_shop_message(2, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "missing_cash1");
|
||||
shop_index[top_shop].missing_cash1 = dup_shop_message(3, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "missing_cash2");
|
||||
shop_index[top_shop].missing_cash2 = dup_shop_message(4, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "message_buy");
|
||||
shop_index[top_shop].message_buy = dup_shop_message(5, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
msg = toml_get_string_dup(msgs, "message_sell");
|
||||
shop_index[top_shop].message_sell = dup_shop_message(6, SHOP_NUM(top_shop), msg);
|
||||
if (msg) free(msg);
|
||||
}
|
||||
|
||||
SHOP_BROKE_TEMPER(top_shop) = toml_get_int_default(shop_tab, "broke_temper", 0);
|
||||
SHOP_BITVECTOR(top_shop) = (long)toml_get_int_default(shop_tab, "bitvector", 0);
|
||||
SHOP_KEEPER(top_shop) = toml_get_int_default(shop_tab, "keeper", NOBODY);
|
||||
SHOP_KEEPER(top_shop) = real_mobile(SHOP_KEEPER(top_shop));
|
||||
SHOP_TRADE_WITH(top_shop) = toml_get_int_default(shop_tab, "trade_with", 0);
|
||||
|
||||
arr = toml_array_in(shop_tab, "rooms");
|
||||
temp = arr ? toml_array_nelem(arr) : 0;
|
||||
CREATE(shop_index[top_shop].in_room, room_vnum, temp + 1);
|
||||
for (count = 0; count < temp; count++) {
|
||||
toml_datum_t v = toml_int_at(arr, count);
|
||||
SHOP_ROOM(top_shop, count) = v.ok ? (room_vnum)v.u.i : NOWHERE;
|
||||
}
|
||||
SHOP_ROOM(top_shop, temp) = NOWHERE;
|
||||
|
||||
SHOP_OPEN1(top_shop) = toml_get_int_default(shop_tab, "open1", 0);
|
||||
SHOP_CLOSE1(top_shop) = toml_get_int_default(shop_tab, "close1", 0);
|
||||
SHOP_OPEN2(top_shop) = toml_get_int_default(shop_tab, "open2", 0);
|
||||
SHOP_CLOSE2(top_shop) = toml_get_int_default(shop_tab, "close2", 0);
|
||||
SHOP_BANK(top_shop) = toml_get_int_default(shop_tab, "bank", 0);
|
||||
SHOP_SORT(top_shop) = toml_get_int_default(shop_tab, "sort", 0);
|
||||
SHOP_FUNC(top_shop) = NULL;
|
||||
}
|
||||
|
||||
toml_free(tab);
|
||||
}
|
||||
|
||||
void assign_the_shopkeepers(void)
|
||||
|
|
|
|||
58
src/toml_utils.c
Normal file
58
src/toml_utils.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
#include "toml_utils.h"
|
||||
|
||||
static void toml_write_escaped(FILE *fp, const char *value)
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)value;
|
||||
|
||||
while (p && *p) {
|
||||
switch (*p) {
|
||||
case '\\':
|
||||
fputs("\\\\", fp);
|
||||
break;
|
||||
case '"':
|
||||
fputs("\\\"", fp);
|
||||
break;
|
||||
case '\n':
|
||||
fputs("\\n", fp);
|
||||
break;
|
||||
case '\r':
|
||||
fputs("\\r", fp);
|
||||
break;
|
||||
case '\t':
|
||||
fputs("\\t", fp);
|
||||
break;
|
||||
default:
|
||||
if (*p < 0x20) {
|
||||
fprintf(fp, "\\u%04x", (unsigned int)*p);
|
||||
} else {
|
||||
fputc(*p, fp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
void toml_write_string(FILE *fp, const char *value)
|
||||
{
|
||||
fputc('"', fp);
|
||||
if (value && *value)
|
||||
toml_write_escaped(fp, value);
|
||||
fputc('"', fp);
|
||||
}
|
||||
|
||||
void toml_write_kv_string(FILE *fp, const char *key, const char *value)
|
||||
{
|
||||
fprintf(fp, "%s = ", key);
|
||||
toml_write_string(fp, value);
|
||||
fputc('\n', fp);
|
||||
}
|
||||
|
||||
void toml_write_kv_string_opt(FILE *fp, const char *key, const char *value)
|
||||
{
|
||||
if (!value || !*value)
|
||||
return;
|
||||
toml_write_kv_string(fp, key, value);
|
||||
}
|
||||
10
src/toml_utils.h
Normal file
10
src/toml_utils.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef TOML_UTILS_H
|
||||
#define TOML_UTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void toml_write_string(FILE *fp, const char *value);
|
||||
void toml_write_kv_string(FILE *fp, const char *key, const char *value);
|
||||
void toml_write_kv_string_opt(FILE *fp, const char *key, const char *value);
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue