#define _FAMILY_C_
#include "version.h"
#include "main.h"
#include "acfamily.h"
#include "util.h"
#include "saacproto_serv.h"
#include <malloc.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
// 家族 Int 资料
static char* FAMILY_INTDATA[familymaxint] =
{
"fmindex",
"fmleadergrano",
"fmnum",
"fmjoinnum",
"fmacceptflag",
"fmsetupflag",
"fmsprite",
"fmpointindex",
"fmpopular",
"fmgold",
"fmmemberindexmaxnum",
"apply_time",
"setup_time",
"predel_time",
"memonowwritenum",
"memonum",
"fmadv",
"fmfeed",
"fmsynthesize",
"fmdealfood",
"fmpk",
#ifdef _NEW_MANOR_LAW
"fmmomentum",
#endif
};
// 家族 char 资料
static char* FAMILY_CHARDATA[familymaxchar] =
{
"fmname",
"fmleadername",
"fmleaderid",
"petname",
"petattr",
"fmrule",
};
// 家族成员 int 资料
static char* MEMBER_INTDATA[memberdatamaxint] =
{
"charlv",
"charflag",
"onlineflag",
"charfdid",
"predeltime",
"popular",
#ifdef _FMVER21
"eventflag",
#endif
#ifdef _NEW_MANOR_LAW
"momentum",
#endif
};
// 家族成员 char 资料
static char* MEMBER_CHARDATA[memberdatamaxchar] =
{
"charname",
"charid",
};
// 成员种类 char 资料
static char* MEMBERKIND_INTDATA[FMMEMBER_KINDNUM] =
{
"无",
"一般成员",
"申请中",
"族长",
"长老",
};
// 家族之间留言板
struct FMSMEMO
{
int num; // 留言数量
int fmsnowwritenum; // 目前留言位置
char memodata[FMSMEMONUM][FAMILY_MEMOLEN]; // 留言内容
};
// 庄园
struct FMPOINT
{
int fl; // 庄园进入图层
int x; // 庄园进入X座标
int y; // 庄园进入Y座标
int fmfl; // 庄园族长图层
int village; // 庄园邻近之村庄
int hadfmindex; // 占领庄园之家族 index
char hadfmname[CHARNAME_MAX]; // 占领庄园之家族 name
int hadfmpopular; // 占领庄园之家族综合声望值
};
// 家族成员资料
typedef struct
{
char charname[CHARNAME_MAX]; // 成员名字
char charid[USERID_MAX]; // 成员帐号
int charlv; // 成员等级
int charflag; /*
FMMEMBER_NONE 清空资料
FMMEMBER_MEMBER 家族成员
FMMEMBER_APPLY 申请中
FMMEMBER_LEADER 族长
FMMEMBER_ELDER 长老
*/
int onlineflag; // 0:offline; gmsv index
int charfdid; // 成员在 gmsv 的 fd
int predeltime; // 预计删除成员时间
int popular; // 成员的声望
#ifdef _FMVER21
int eventflag; // 是否拥有族长资格
#endif
#ifdef _NEW_MANOR_LAW
int momentum; // 成员气势
#endif
#ifdef _FM_MODIFY
int gsnum; // 记录玩家是在那一个game server
#endif
} MEMBERDATA;
struct FAMILY
{
int fmindex; // 家族 index
char fmname[CHARNAME_MAX]; // 家族名称
char fmleadername[CHARNAME_MAX]; // 族长名称
char fmleaderid[USERID_MAX]; // 族长帐号
int fmleadergrano; // 族长照片
char petname[CHARNAME_MAX]; // 守护兽名称
char petattr[256]; // 守护兽资料
int fmnum; // 家族人数,包含申请退出、加入人数
int fmjoinnum; // 真正加入家族人数
int fmacceptflag; // 是否接收成员 0:不接受 1:接受
int fmsetupflag; // 0:尚未成立 1:已成立
char fmrule[256]; // 家族主旨
int fmsprite; // 0:光明精灵 1:黑暗精灵
int fmpointindex; // 家族据点 index
int fmpopular; // 家族综合声望
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
int fmtotalfame; // 家族综合 + 家族个人声望总合
#endif
#ifdef _NEW_MANOR_LAW
int fmmomentum; // 家族气势
#endif
int fmgold; // 家族基金
int fmmemberindexmaxnum; // 家族目前最大人数
int apply_time; // 家族申请时间
int setup_time; // 家族成立时间
int predel_time; // 预计删除家族时间
int memonowwritenum; // 目前留言位置
int memonum; // 留言数量
int fmadv; // 冒险任务声望
int fmfeed; // 饲育声望
int fmsynthesize; // 合成加工声望
int fmdealfood; // 料理声望
int fmpk; // PK声望
char memolist[FAMILY_MEMONUM][FAMILY_MEMOLEN]; // 留言内容
MEMBERDATA fmmemberindex[MAX_MEMBERNUM]; // 成员资料
};
int db_familyupdate[MAX_FAMILY]={0};
int db_fmpointupdate = 0;
int db_fmsmemoupdate = 0;
int fmnownum = 0;
int fmindexmaxnum = 0;
extern gmsv gs[MAXCONNECTION];
struct FAMILY family[MAX_FAMILY];
int fmpopularindex[MAX_FAMILY]; // Arminius: sort family
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
int fmtotalfameindex[MAX_FAMILY];
#endif
#ifdef _NEW_MANOR_LAW
int fmMomentumIndex[MAX_FAMILY];
#endif
int fmadvindex[MAX_FAMILY];
int fmfeedindex[MAX_FAMILY];
int fmsynthesizeindex[MAX_FAMILY];
int fmdealfoodindex[MAX_FAMILY];
int fmpkindex[MAX_FAMILY];
struct FMPOINT fmpoint[MAX_FMPOINT];
struct FMSMEMO fmsmemo;
// Arminius: sort family & output the sorted list
// Make a sorted index (fmindex) for the family data (family)
#ifdef _NEW_MANOR_LAW
int fmMomentumcompar(const void *indexa, const void *indexb);
#endif
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
int fmtotalfamecompar(const void *indexa, const void *indexb);
#endif
int fmpopularcompar(const void *indexa, const void *indexb);
int fmadvcompar(const void *indexa, const void *indexb);
int fmfeedcompar(const void *indexa, const void *indexb);
int fmsynthesizecompar(const void *indexa, const void *indexb);
int fmdealfoodcompar(const void *indexa, const void *indexb);
int fmpkcompar(const void *indexa, const void *indexb);
int CheckFM(int *index, char *fmname, int fmindex);
int CheckFMUse(int index);
void setFamilyFileDataToArg(int index, char *data);
void setMemberFileDataToArg(int index, int memberindex, char *databuf);
// sortFamily: call this after family loaded
void sortFamily(void)
{
int i;
for(i = 0; i < MAX_FAMILY; i++)
{
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
fmtotalfameindex[i] = i;
#endif
#ifdef _NEW_MANOR_LAW
fmMomentumIndex[i] = i;
#endif
fmpopularindex[i] = i;
fmadvindex[i] = i;
fmfeedindex[i] = i;
fmsynthesizeindex[i] = i;
fmdealfoodindex[i] = i;
fmpkindex[i] = i;
}
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
qsort(fmtotalfameindex, MAX_FAMILY, sizeof(int), &fmtotalfamecompar);
#endif
qsort(fmpopularindex, MAX_FAMILY, sizeof(int), &fmpopularcompar);
qsort(fmadvindex, MAX_FAMILY, sizeof(int), &fmadvcompar);
qsort(fmfeedindex, MAX_FAMILY, sizeof(int), &fmfeedcompar);
qsort(fmsynthesizeindex, MAX_FAMILY, sizeof(int), &fmsynthesizecompar);
qsort(fmdealfoodindex, MAX_FAMILY, sizeof(int), &fmdealfoodcompar);
qsort(fmpkindex, MAX_FAMILY, sizeof(int), &fmpkcompar);
#ifdef _NEW_MANOR_LAW
qsort(fmMomentumIndex,MAX_FAMILY,sizeof(int),&fmMomentumcompar);
#endif
}
#ifdef _PERSONAL_FAME // Arminius: 家族个人声望
int fmtotalfamecompar(const void *indexa, const void *indexb)
{
int famea,fameb;
if ( CheckFMUse(* (int*) indexa)==0 ) return 1; // empty record
if ( CheckFMUse(* (int*) indexb)==0 ) return -1;
famea = family[ * (int*) indexa ].fmtotalfame;
fameb = family[ * (int*) indexb ].fmtotalfame;
return (famea>fameb)? -1 : 1;
}
#endif
#ifdef _NEW_MANOR_LAW
int fmMomentumcompar(const void *indexa, const void *indexb)
{
int momentumA,momentumB;
if(CheckFMUse(*(int*)indexa) == 0) return 1; // empty record
if(CheckFMUse(*(int*)indexb) == 0) return -1;
momentumA = family[*(int*)indexa].fmmomentum;
momentumB = family[*(int*)indexb].fmmomentum;
return (momentumA > momentumB) ? -1:1;
}
#endif
int fmpopularcompar(const void *indexa, const void *indexb)
{
int fmpopulara,fmpopularb;
if ( CheckFMUse(* (int*) indexa)==0 ) return 1; // empty record
if ( CheckFMUse(* (int*) indexb)==0 ) return -1;
fmpopulara = family[ * (int*) indexa ].fmpopular;
fmpopularb = family[ * (int*) indexb ].fmpopular;
return (fmpopulara>fmpopularb)? -1 : 1;
}
int fmadvcompar(const void *indexa, const void *indexb)
{
int fmadva,fmadvb;
if ( CheckFMUse(* (int*) indexa)==0 ) return 1; // empty record
if ( CheckFMUse(* (int*) indexb)==0 ) return -1;
fmadva = family[ * (int*) indexa ].fmadv;
fmadvb = family[ * (int*) indexb ].fmadv;
return (fmadva>fmadvb)? -1 : 1;
}
int fmfeedcompar(const vo