/************************************************************************
* Generic OLC Library - Guilds / gengld.c v1.0 *
* Copyright 1996 by Harvey Gilpin *
* Copyright 1997-2001 by George Greer (greerga@circlemud.org) *
************************************************************************/
#include "conf.h"
#include "sysdep.h"
#include "structs.h"
#include "utils.h"
#include "db.h"
#include "guild.h"
#include "shop.h"
#include "genolc.h"
#include "gengld.h"
#include "genzon.h"
extern struct index_data *mob_index;
extern struct index_data *obj_index;
extern struct guild_data *guild_index;
extern struct zone_data *zone_table;
extern int top_guild;
extern zone_rnum top_of_zone_table;
/*
* NOTE (gg): Didn't modify sedit much. Don't consider it as 'recent'
* as the other editors with regard to updates or style.
*/
/*-------------------------------------------------------------------*/
void copy_guild(struct guild_data *tgm, struct guild_data *fgm)
{
int i;
/*. Copy basic info over . */
G_NUM(tgm) = G_NUM(fgm);
G_CHARGE(tgm) = G_CHARGE(fgm);
G_TRAINER(tgm) = G_TRAINER(fgm);
G_WITH_WHO(tgm) = G_WITH_WHO(fgm);
G_OPEN(tgm) = G_OPEN(fgm);
G_CLOSE(tgm) = G_CLOSE(fgm);
G_MINLVL(tgm) = G_MINLVL(fgm);
G_FUNC(tgm) = G_FUNC(fgm);
/*. Copy the strings over . */
free_guild_strings(tgm);
G_NO_SKILL(tgm) = str_udup(G_NO_SKILL(fgm));
G_NO_GOLD(tgm) = str_udup(G_NO_GOLD(fgm));
/* copy the wasteful skills and spells table over */
for (i = 0; i < MAX_SKILLS + 2; i++)
G_SK_AND_SP(tgm, i) = G_SK_AND_SP(fgm, i);
}
/*-------------------------------------------------------------------*/
/*. Free all the character strings in a guild structure . */
void free_guild_strings(struct guild_data *guild)
{
if (G_NO_SKILL(guild)) {
free(G_NO_SKILL(guild));
G_NO_SKILL(guild) = NULL;
}
if (G_NO_GOLD(guild)) {
free(G_NO_GOLD(guild));
G_NO_GOLD(guild) = NULL;
}
}
/*-------------------------------------------------------------------*/
/*. Free up the whole guild structure and its contents . */
void free_guild(struct guild_data *guild)
{
free_guild_strings(guild);
free(guild);
}
/*-------------------------------------------------------------------*/
/* returns the real number of the guild with given virtual number
*
* We take so good care to keep it sorted - let's use it :) - Welcor
*/
guild_rnum real_guild(guild_vnum vnum)
{
guild_rnum bot, top, mid;
bot = 0;
top = top_guild - top_guild_offset;
/* perform binary search on guild_table */
for (;;) {
mid = (bot + top) / 2;
if (GM_NUM(mid) == vnum)
return (mid);
if (bot >= top)
return (NOWHERE);
if (GM_NUM(mid) > vnum)
top = mid - 1;
else
bot = mid + 1;
}
}
/*-------------------------------------------------------------------*/
/*. Generic string modifyer for guild master messages . */
void gedit_modify_string(char **str, char *new_g)
{
char *pointer;
char buf[MAX_STRING_LENGTH];
/*. Check the '%s' is present, if not, add it . */
if (*new_g != '%') {
snprintf(buf, sizeof(buf), "%%s %s", new_g);
pointer = buf;
} else
pointer = new_g;
if (*str)
free(*str);
*str = strdup(pointer);
}
/*-------------------------------------------------------------------*/
int add_guild(struct guild_data *ngld)
{
guild_rnum rguild;
int found = 0;
zone_rnum rznum = real_zone_by_thing(G_NUM(ngld));
/*
* The guild already exists, just update it.
*/
if ((rguild = real_guild(G_NUM(ngld))) != NOWHERE) {
copy_guild(&guild_index[rguild], ngld);
if (rznum != NOWHERE) {
add_to_save_list(zone_table[rznum].number, SL_GLD);
} else
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: GenOLC: Cannot determine guild zone.");
return rguild;
}
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: GenOLC: Creating new guild.");
top_guild++;
RECREATE(guild_index, struct guild_data, top_guild - top_guild_offset + 1);
for (rguild = top_guild - top_guild_offset; rguild > 0; rguild--) {
if (ngld->vnum > GM_NUM(rguild - 1)) {
found = rguild;
copy_guild(&guild_index[rguild], ngld);
break;
}
guild_index[rguild] = guild_index[rguild - 1];
}
if (!found) {
copy_guild(&guild_index[0], ngld);
}
if (rznum != NOWHERE) {
add_to_save_list(zone_table[rznum].number, SL_GLD);
}
else
mudlog(BRF, LVL_BUILDER, TRUE, "SYSERR: GenOLC: Cannot determine guild zone.");
return rguild;
}
/*-------------------------------------------------------------------*/
int save_guilds(zone_rnum zone_num)
{
int i, j, rguild;
FILE *guild_file;
char fname[64];
struct guild_data *guild;
#if CIRCLE_UNSIGNED_INDEX
if (zone_num == NOWHERE || zone_num > top_of_zone_table) {
#else
if (zone_num < 0 || zone_num > top_of_zone_table) {
#endif
log("SYSERR: GenOLC: save_guilds: Invalid real zone number %d. (0-%d)", zone_num, top_of_zone_table);
return FALSE;
}
snprintf(fname, sizeof(fname), "%s/%d.gld", GLD_PREFIX, zone_table[zone_num].number);
if (!(guild_file = fopen(fname, "w"))) {
mudlog(BRF, LVL_GOD, TRUE, "SYSERR: OLC: Cannot open Guild file!");
return FALSE;
}
/*. Search database for guilds in this zone . */
for (i = genolc_zone_bottom(zone_num); i <= zone_table[zone_num].top; i++) {
if ((rguild = real_guild(i)) != NOWHERE) {
fprintf(guild_file, "#%d~\n", i);
guild = guild_index + rguild;
/* Write which skills and spells the gm knows */
for (j = 0; j < MAX_SKILLS + 2; j++)
if (G_SK_AND_SP(guild, j))
fprintf(guild_file, "%d\n", j);
fprintf(guild_file, "-1\n");
/*. Save charge . */
fprintf(guild_file, "%1.2f\n", G_CHARGE(guild));
/*. Save messages . */
fprintf(guild_file,
"%s~\n%s~\n",
/*. Added some small'n'silly defaults as sanity checks . */
(G_NO_SKILL(guild) ? G_NO_SKILL(guild) : "%s ERROR"),
(G_NO_GOLD(guild) ? G_NO_GOLD(guild) : "%s ERROR")
);
/* Write what the GM teaches */
fprintf(guild_file, "%d\n", G_MINLVL(guild));
/*. Save the rest . */
fprintf(guild_file, "%d\n%d\n%d\n%d\n",
G_TRAINER(guild) == NOBODY ? -1 : mob_index[G_TRAINER(guild)].vnum,
G_WITH_WHO(guild),
G_OPEN(guild),
G_CLOSE(guild)
);
}
}
fprintf(guild_file, "$~\n");
fclose(guild_file);
if (in_save_list(zone_table[zone_num].number, SL_GLD))
remove_from_save_list(zone_table[zone_num].number, SL_GLD);
return TRUE;
}