/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* In order to use any part of this Envy Diku Mud, you must comply with *
* the original Diku license in 'license.doc', the Merc license in *
* 'license.txt', as well as the Envy license in 'license.nvy'. *
* In particular, you may not remove either of these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
* *
* ROM 2.4 is copyright 1993-1998 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@hypercube.org) *
* Gabrielle Taylor (gtaylor@hypercube.org) *
* Brian Moore (zump@rom.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Rom24/doc/rom.license *
* *
* Code Adapted and Improved by Abandoned Realms Mud *
* and Aabahran: The Forsaken Lands Mud by Virigoth *
* *
* Continued Production of this code is available at www.flcodebase.com *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <memory.h>
#include "merc.h"
#include "clan.h"
/***************************************************************/
/*Following are army orientanted routines for Forsaken Lands */
/*mud created by Virigoth circa Apr 2004. Copyrighted for Forsaken*/
/*Lands mud Apr 04, 2004. Do not use or copy without explicit */
/*permission of author. (Voytek Plawny aka Virigoth) */
/***************************************************************/
/* GLOBALS */
static CLAN_DATA clan_list[MAX_CLANS];
/* PROTOTYPES */
char* ClanFixName( char* name );
/* PRIVATE */
//zero the clan list
void Reset(){
memset( clan_list, 0, sizeof( CLAN_DATA ) * MAX_CLANS);
}
//convert a clan name to handle, 0 on not found
int ClanNameToHandle( char* name ){
int clan;
for ( clan = 0; clan < MAX_CLANS; clan++){
if (IS_NULLSTR(clan_list[clan].name) || str_cmp(name, clan_list[clan].name))
continue;
else
return ( clan + 1);
}
return 0;
}
//convert handle to name, NULL on not found
char* ClanHandleToName( int handle ){
static char* nul = "";
if (handle < 1 || handle > MAX_CLANS || IS_NULLSTR(clan_list[handle - 1].name))
return nul;
else
return clan_list[handle - 1].name;
}
//returns clan data based on handle
CLAN_DATA* GetClanData( int handle ){
if (handle < 1 || handle > MAX_CLANS)
return NULL;
return ( &clan_list[handle - 1]);
}
int ClanInsertMember( int handle, CLAN_MEMBER* pCmd ){
CLAN_DATA* pClan = GetClanData( handle );
CLAN_MEMBER* prev, *new;
if (pClan == NULL || pCmd == NULL){
return 0;
}
else if ( (new = GetClanMember( handle, pCmd->name)) != NULL){
return handle;
}
/* search for the end of the member list */
for (prev = &pClan->members; prev->next; prev = prev->next);
/* attach the new member */
new = alloc_mem( sizeof( *new ));
memset( new, 0, sizeof( *new ));
new->name = str_dup( pCmd->name );
new->class = pCmd->class;
new->race = pCmd->race;
new->level = pCmd->level;
new->rank = pCmd->rank;
new->pts = pCmd->pts;
new->last_logon = pCmd->last_logon;
new->joined = pCmd->joined;
new->allowed = pCmd->allowed;
new->next = NULL;
prev->next = new;
pClan->max++;
return handle;
}
//adds a member to a clan
int ClanAddMember( int handle, CHAR_DATA* ch){
CLAN_MEMBER tmp;
if (handle < 1 || handle > MAX_CLANS || ch == NULL)
return 0;
tmp.name = ch->name;
tmp.class = ch->class;
tmp.race = ch->race;
tmp.level = ch->race;
tmp.rank = 0;
tmp.last_logon = ch->logoff;
tmp.joined = mud_data.current_time;
tmp.allowed = 0;
tmp.pts = ch->pcdata->clan_points + mud_data.mudport == TEST_PORT ? 1 : 0;
return (ClanInsertMember( handle, &tmp ));
}
//removes a given member from a clan
bool ClanRemMember( int handle, char* name ){
CLAN_DATA* pClan = GetClanData( handle );
CLAN_MEMBER* prev, *tmp = NULL;
if (pClan == NULL || IS_NULLSTR( name )){
return FALSE;
}
/* search members untill we find target name */
for (prev = &pClan->members; prev->next; prev = prev->next){
if (!str_cmp(prev->next->name, name)){
tmp = prev->next;
break;
}
}
if (tmp == NULL){
bug("clan.c>ClanRemMember: name not found.", 0);
return FALSE;
}
/* unlink the member */
prev->next = tmp->next;
/* free strings */
free_string( tmp->name );
/* free the member */
free_mem( tmp, sizeof( *tmp ));
pClan->max--;
return TRUE;
}
//adds a clan to the list of clans, returns handle
int ClanAdd( CLAN_DATA* pClan){
int handle;
if (pClan == NULL || IS_NULLSTR(pClan->name))
return 0;
else if ( (handle = ClanNameToHandle( pClan->name )) > 0){
return (handle);
}
else{
/* try to find an empty spot */
for (handle = 0; handle < MAX_CLANS; handle++){
if (IS_NULLSTR(clan_list[handle].name)){
memcpy(&clan_list[handle], pClan, sizeof( *pClan ));
clan_list[handle].name = str_dup( pClan->name );
return (handle + 1);
}
}
return 0;
}
}
//removes a clan from the list
bool ClanRem( int handle ){
CLAN_DATA* pClan = GetClanData( handle );
char path[MIL];
if (pClan == NULL){
bug("clan.c>ClanRem: Could not find clan %d", handle );
return FALSE;
}
/* free members */
while (pClan->members.next)
ClanRemMember( handle, pClan->members.next->name );
/* unlink save file */
sprintf( path, "%s%s", CLAN_DIR, ClanFixName( pClan->name ) );
unlink( path );
/* free strings */
free_string( pClan->name );
pClan->name = NULL;
pClan->max = 0;
return TRUE;
}
//lists all the clans loaded
void ListClans( CHAR_DATA* ch ){
int clan;
for (clan = 0; clan < MAX_CLANS; clan++){
if (IS_NULLSTR(clan_list[clan].name))
continue;
sendf(ch, "%-25.25s (%-3d)\n\r", clan_list[clan].name, clan_list[clan].max );
}
}
//returns a string with clan data for one member
char* PrintMemberData( CLAN_MEMBER* pCmd, bool fImm ){
static char out[MIL];
out[0] = 0;
/* IMM info */
if (fImm){
if (pCmd == NULL){
sprintf( out,
"Name Race Class Rank Lvl Sen Log Pts \n\r"\
"----------------------------------------------------------------------");
}
else{
sprintf( out,
"%-15.15s %-10.10s %-10.10s %-10.10s %-2d %-3ld %-3ld %-3d",
pCmd->name,
pc_race_table[pCmd->race].name,
class_table[pCmd->class].name,
clanr_table[pCmd->rank][1],
pCmd->level,
(mud_data.current_time - pCmd->joined) / 86400,
(mud_data.current_time - pCmd->last_logon) / 86400,
pCmd->pts);
}
}
/* NORMAL */
else{
if (pCmd == NULL){
sprintf( out,
"Name Rank Lvl Days Ago\n\r"\
"----------------------------------------");
}
else{
sprintf( out,
"%-15.15s %-10.10s %-2d %-3ld",
pCmd->name,
clanr_table[pCmd->rank][1],
pCmd->level,
(mud_data.current_time - pCmd->last_logon) / 86400);
}
}
return ( out );
}
//lists members of a given clan
//types are: seniority, rank, pts (default)
void ListMembers( CHAR_DATA* ch, int handle, bool fImm, char* type ){
CLAN_DATA* pClan;
CLAN_MEMBER* pCmd;
const int max_search = 128;
const int max_show = 16;
CLAN_MEMBER* members[max_search];
int max_member = 0, i, j;
bool fRank = FALSE, fSen = FALSE;
if ( (pClan = GetClanData( handle )) == NULL)
return;
for (pCmd = pClan->members.next; pCmd; pCmd = pCmd->next){
if ((mud_data.current_time - pCmd->last_logon) > MAX_INACTIVE)
continue;
/* Viri: Lets see for now if this pruning is really necessary
else if (pCmd->rank < RANK_ELDER && pCmd->pts < 1)
continue;
*/
if (max_member < max_search)
members[max_member++] = pCmd;
}
if (!str_prefix(type, "rank"))
fRank = TRUE;
if (!str_prefix(type, "seniority"))
fSen = TRUE;
/* sort */
if (fRank){
for (i = 0; i < max_member; i++){
pCmd = members[i];
for (j = i; j > 0 && members[j - 1]->rank < pCmd->rank; j--){
members[j] = members[j - 1];
}
members[j] = pCmd;
}
}
else if (fSen){
for (i = 0; i < max_member; i++){
pCmd = members[i];
for (j = i; j > 0 && members[j - 1]->joined > pCmd->joined; j--){
members[j] = members[j - 1];
}
members[j] = pCmd;
}
}
else{
for (i = 0; i < max_member; i++){
pCmd = members[i];
for (j = i; j > 0 && members[j - 1]->pts < pCmd->pts; j--){
members[j] = members[j - 1];
}
members[j] = pCmd;
}
}
/* show */
sendf( ch, "%s\n\r", PrintMemberData( NULL, fImm ) );
for (i = 0; i < max_member && i < max_show; i++){
sendf( ch, "%s\n\r", PrintMemberData( members[i], fImm ) );
}
}
//fixes a clan name to be ok for a filename
char* ClanFixName( char* name ){
static char out[MIL];
char* ptr = out;
*ptr = 0;
while (*name ){
switch( *name ){
default:
if (isalpha( *name ))
*ptr = *name;
else
*ptr = '_';
break;
case ' ': *ptr = '_'; break;
}
ptr++;
name++;
}
*ptr = 0;
return out;
}
//writes a single clan's data to file
void fWriteClan( FILE *fp, CLAN_DATA* pClan ){
CLAN_MEMBER* pCmd;
//start the file off with the name
fprintf( fp, "CLAN %s~\n", pClan->name );
for (pCmd = pClan->members.next; pCmd; pCmd = pCmd->next){
fprintf( fp,
"MEMBER %s~\n"\
"RACE %d CLASS %d LEVEL %d\n"\
"RANK %d PTS %d\n"\
"JOIN %ld LAST %ld ALLOWED %ld\n"\
"MEMBER_END\n",
pCmd->name,
pCmd->race, pCmd->class, pCmd->level,
pCmd->rank, pCmd->pts,
pCmd->joined, pCmd->last_logon, pCmd->allowed);
}
fprintf( fp, "END\n\n");
}
//reads a single clan's data and loads the clan
void fReadClan( FILE* fp ){
CLAN_DATA clan;
CLAN_MEMBER member;
char* word;
int handle;
bool fMatch;
if ( (word = fread_word( fp )) == NULL){
bug("clan.c>fReadClan: Error accessing file.\n\r", 0);
return;
}
else if (str_cmp(word, "CLAN")){
bug("can.c>fReadClan: Expected CLAN not found.", 0);
return;
}
memset( &clan, 0, sizeof( CLAN_DATA ));
//get name first
clan.name = fread_string( fp );
if ( (handle = ClanAdd( &clan )) < 1){
bug("clan.c>fReadClan: Could not get a handle for clan.", 0);
return;
}
//reset the name data for use
memset( &member, 0, sizeof( CLAN_MEMBER ));
for (;;){
fMatch = FALSE;
if (feof( fp) || (word = fread_word( fp )) == NULL)
word = "END";
switch( UPPER(word[0])){
case 'A':
KEY( "ALLOWED", member.allowed, fread_number( fp ));
break;
case 'C':
KEY( "CLASS", member.class, fread_number( fp ));
break;
case 'E':
if (!str_cmp(word, "END")){
fMatch = TRUE;
return;
}
break;
case 'J':
KEY( "JOIN", member.joined, fread_number( fp ));
break;
case 'L':
KEY( "LEVEL", member.level, fread_number( fp ));
KEY( "LAST", member.last_logon, fread_number( fp ));
break;
case 'M':
KEYS( "MEMBER", member.name, fread_string( fp ));
if (!str_cmp(word, "MEMBER_END")){
if (ClanInsertMember( handle, &member) < 1){
nlogf("[*****] BUG: clan.c>fReadClan: Could not insert member %s", member.name);
continue;
}
fMatch = TRUE;
break;
}
break;
case 'P':
KEY( "PTS", member.pts, fread_number( fp ));
break;
case 'R':
KEY( "RACE", member.race, fread_number( fp ));
KEY( "RANK", member.rank, fread_number( fp ));
break;
}
if (!fMatch){
nlogf("[*****] BUG: clan.c>fReadClan: Can't match \"%s\"", word);
}
}
}
/* INTERFACE */
void LoadClans(){
FILE* fp;
DIR *directory; //Directory
struct dirent *dir_ent; //Directory entry
struct stat Stat; //File statistics
char path[MIL]; //Current file name
Reset();
/* Open dir, get first entry */
if ( (directory = opendir(CLAN_DIR)) == NULL){
bug("clan.c>LoadClans: Could not access CLAN_DIR", 0);
return;
}
else if ( (dir_ent = readdir(directory)) == NULL){
bug("clan.c>LoadClans: Could not access first directory entry.", 0);
closedir( directory );
return;
}
fclose( fpReserve );
while( dir_ent != NULL){
sprintf( path, "%s%s", CLAN_DIR, dir_ent->d_name );
if ( -1 == stat( path, &Stat)){
dir_ent = readdir( directory );
continue;
}
else if(!S_ISREG(Stat.st_mode)){
dir_ent = readdir( directory );
continue;
}
nlogf("Loading clan %s", dir_ent->d_name );
if ( (fp = fopen( path, "r")) == NULL){
perror( path );
dir_ent = readdir( directory );
continue;
}
fReadClan( fp );
fclose( fp );
dir_ent = readdir( directory );
}
closedir( directory );
fpReserve = fopen( NULL_FILE, "r" );
}
//saves a single clan
void ClanSave( int handle ){
CLAN_DATA* pClan = GetClanData( handle );
FILE* fp;
char path[MIL], buf[MIL];
if (pClan == NULL){
bug("clan.c>ClanSave: Could not get pointer to clan %d", handle );
return;
}
sprintf( path, "%s%s", CLAN_DIR, CLAN_TMP_FILE );
if ( (fp = fopen( path, "w")) == NULL){
perror( path );
return;
}
fWriteClan( fp, pClan );
fclose( fp );
sprintf( buf, "%s%s", CLAN_DIR, ClanFixName( pClan->name ));
rename( path, buf );
}
void SaveClans(){
int clan;
fclose( fpReserve );
for ( clan = 0; clan < MAX_CLANS; clan++){
if (!IS_NULLSTR(clan_list[clan].name))
ClanSave( clan + 1 );
}
fpReserve = fopen( NULL_FILE, "r" );
}
/* commands:
clan list //clan member only
clan list clans //imm only
clan create <clan> //imm only
clan delete <clan> //imp only
clan draft <victim> //clan leader only
clan draft <victim> <clan> //imm/mob only
clan remove <victim> //clan leader only
clan remove <victim> <clan> //imm/mob only
clan prom <victim> //elder only
clan prom <victim> <clan> //imm/mob only
clan demo <victim> //elder only
clan demo <victim> <clan> //imm/mob only
*/
void do_clan( CHAR_DATA* ch, char* argument ){
int handle;
char arg1[MIL], arg2[MIL], buf[MIL];
argument = one_argument( argument, arg1 );
if (IS_NULLSTR(arg1)){
send_to_char("Common clan commands are: draft, remove, prom, demo.\n\r", ch);
return;
}
/* CREATE */
if (!str_prefix( arg1, "create")){
CLAN_DATA clan;
memset(&clan, 0, sizeof( clan ));
if (!IS_IMMORTAL(ch)){
send_to_char("You cannot create clans.\n\r", ch);
return;
}
else if (IS_NULLSTR(argument)){
send_to_char( "Create what clan?\n\r", ch);
return;
}
sprintf( buf, "%s", argument );
buf[0] = UPPER(buf[0]);
clan.name = buf;
if ( (handle = ClanNameToHandle( buf )) > 0){
send_to_char("That clan already exists.\n\r", ch);
return;
}
else if ( (handle = ClanAdd( &clan )) < 0){
send_to_char("Error adding clan.\n\r", ch);
return;
}
else
sendf( ch, "Clan \"%s\" created.\n\r", ClanHandleToName( handle ));
ClanSave( handle );
return;
}
/* DELETE */
if (!str_prefix( arg1, "delete")){
if (get_trust(ch) < CREATOR){
sendf( ch, "Requires level %d trust\n\r", CREATOR);
return;
}
else if (IS_NULLSTR(argument)){
send_to_char( "Delete what clan?\n\r", ch);
return;
}
else if ( (handle = ClanNameToHandle( argument )) < 1){
send_to_char("That clan doesn't exists.\n\r", ch);
return;
}
else if ( !ClanRem( handle ) ){
send_to_char("Error deleting clan.\n\r", ch);
return;
}
else{
send_to_char("Removed.\n\r", ch);
}
return;
}
/* LIST */
if (!str_prefix( arg1, "list")){
/* IMMORTAL LIST */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if (GET_CLAN(ch) < 1){
send_to_char( "List which clan?\n\r", ch);
return;
}
else
handle = GET_CLAN(ch);
}
if (!str_cmp(argument, "clans")){
ListClans(ch);
return;
}
else if ( (handle = ClanNameToHandle( argument )) < 1){
send_to_char("No such clan.\n\r", ch);
return;
}
argument = one_argument( argument, arg1);
ListMembers( ch, handle, TRUE, "Pts");
return;
}
/* MORTAL LIST */
else if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch );
return;
}
else if (!CLAN_ELDER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
ListMembers( ch, handle, FALSE, "Pts");
return;
}
/* RANKS */
else if (!str_prefix( arg1, "rank")){
/* IMMORTAL LIST */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if (GET_CLAN(ch) < 1){
send_to_char( "List which clan?\n\r", ch);
return;
}
else
handle = GET_CLAN(ch);
}
if ( (handle = ClanNameToHandle( argument )) < 1){
send_to_char("No such clan.\n\r", ch);
return;
}
argument = one_argument( argument, arg1);
ListMembers( ch, handle, TRUE, "Rank");
return;
}
/* MORTAL LIST */
else if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch );
return;
}
else if (!CLAN_ELDER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
ListMembers( ch, handle, FALSE, "Rank");
return;
}
/* SENIOR */
else if (!str_prefix( arg1, "senior")){
/* IMMORTAL LIST */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if (GET_CLAN(ch) < 1){
send_to_char( "List which clan?\n\r", ch);
return;
}
else
handle = GET_CLAN(ch);
}
if ( (handle = ClanNameToHandle( argument )) < 1){
send_to_char("No such clan.\n\r", ch);
return;
}
argument = one_argument( argument, arg1);
ListMembers( ch, handle, TRUE, "Senior");
return;
}
/* MORTAL LIST */
else if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch );
return;
}
else if (!CLAN_ELDER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
ListMembers( ch, handle, FALSE, "Senior");
return;
}
/* DRAFT */
else if (!str_prefix( arg1, "draft")){
CHAR_DATA* victim;
argument = one_argument( argument, arg2);
if ( IS_NULLSTR(arg2)){
send_to_char("Draft whom?\n\r", ch);
return;
}
else if ((victim = get_char_room( ch, NULL, arg2)) == NULL){
send_to_char("They aren't here.\n\r", ch);
return;
}
else if (IS_NPC(victim)){
send_to_char("Not on mobs.\n\r", ch);
return;
}
/* IMMORTAL/NPC */
if (IS_IMMORTAL(ch) || (IS_NPC(ch) && get_trust(ch) >= IMPLEMENTOR)){
if (IS_NULLSTR(argument)){
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("Draft them into which clan?\n\r", ch);
return;
}
}
if ( (handle = ClanNameToHandle( argument)) < 1){
send_to_char("That clan does not exist.\n\r", ch);
return;
}
}
/* MORTAL */
else if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch);
return;
}
else if (!CLAN_ELDER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
else if (victim->master != ch && !IS_IMMORTAL(ch)){
send_to_char("They are not following you.\n\r", ch);
return;
}
if (HAS_CLAN(victim)){
int cur = GET_CLAN(victim);
ClanRemMember( cur, victim->name);
ClanSave( cur );
}
if ( (victim->pcdata->clan_handle = ClanAddMember( handle, victim )) < 1){
send_to_char("Error removing member.\n\r", ch);
return;
}
ClanSave( handle );
act("$n is now a member of $t.", victim, ClanHandleToName( GET_CLAN(victim)), NULL, TO_ROOM);
sendf( victim, "You are now a member of %s.\n\r", ClanHandleToName( GET_CLAN(victim)) );
return;
}
/* REMOVE */
else if (!str_prefix( arg1, "remove")){
CHAR_DATA* victim;
argument = one_argument( argument, arg2);
if ( IS_NULLSTR(arg2)){
send_to_char("Remove whom?\n\r", ch);
return;
}
/* IMMORTAL/NPC */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("Remove them from which clan?\n\r", ch);
return;
}
}
if ( (handle = ClanNameToHandle( argument)) < 1){
send_to_char("That clan does not exist.\n\r", ch);
return;
}
}
/* MORTAL */
else if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch);
return;
}
else if (!CLAN_LEADER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
if (!ClanRemMember( handle, arg2)){
send_to_char("No such member in the clan.\n\r", ch);
return;
}
if ( (victim = get_char( arg2 )) != NULL && !IS_NPC(victim)){
victim->pcdata->clan_handle = 0;
send_to_char("You have been removed from your clan.\n\r", victim);
}
ClanSave( handle );
send_to_char("Removed.\n\r", ch);
return;
}
/* PROMOTE */
else if (!str_prefix( arg1, "promote")){
CLAN_MEMBER* pCmd = NULL;
argument = one_argument( argument, arg2);
if ( IS_NULLSTR(arg2)){
send_to_char("Promote whom?\n\r", ch);
return;
}
/* IMMORTAL/NPC */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("Promote them in which clan?\n\r", ch);
return;
}
}
else if ( (handle = ClanNameToHandle( argument)) < 1){
send_to_char("That clan does not exist.\n\r", ch);
return;
}
if ( (pCmd = GetClanMember(handle, arg2)) == NULL){
send_to_char("No such member in that clan.\n\r", ch);
return;
}
}
/* MORTAL */
else {
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch);
return;
}
else if (!CLAN_ELDER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
else if ( (pCmd = GetClanMember( handle, arg2)) == NULL){
send_to_char("They are not part of your clan.\n\r", ch);
return;
}
else if (pCmd->rank + 1 >= ch->pcdata->clan_rank){
send_to_char("You cannot promote them any further.\n\r", ch);
return;
}
}
if (pCmd){
CHAR_DATA* vch = get_char( pCmd->name );
if (pCmd->rank >= RANK_LEADER){
send_to_char("They cannot be promoted further.\n\r", ch);
pCmd->rank = RANK_LEADER;
}
else{
pCmd->rank++;
sendf(ch, "Promoted to %s.\n\r", clanr_table[pCmd->rank][1]);
}
if (vch && !IS_NPC(vch)){
SynchClanData( vch );
send_to_char("You have been promoted in within your clan!\n\r", vch);
}
}
ClanSave( handle );
return;
}
/* DEMOTE */
else if (!str_prefix( arg1, "demote")){
CLAN_MEMBER* pCmd = NULL;
argument = one_argument( argument, arg2);
if ( IS_NULLSTR(arg2)){
send_to_char("Demote whom?\n\r", ch);
return;
}
/* IMMORTAL/NPC */
if (IS_IMMORTAL(ch)){
if (IS_NULLSTR(argument)){
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("Demote them in which clan?\n\r", ch);
return;
}
}
else if ( (handle = ClanNameToHandle( argument)) < 1){
send_to_char("That clan does not exist.\n\r", ch);
return;
}
if ( (pCmd = GetClanMember(handle, arg2)) == NULL){
send_to_char("No such member in that clan.\n\r", ch);
return;
}
}
/* MORTAL */
else{
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("You do not belong to a clan.\n\r", ch);
return;
}
else if (!CLAN_LEADER(ch)){
send_to_char("You lack the privilige.\n\r", ch);
return;
}
else if ( (pCmd = GetClanMember( handle, arg2)) == NULL){
send_to_char("They are not part of your clan.\n\r", ch);
return;
}
else if (pCmd->rank >= ch->pcdata->clan_rank){
send_to_char("You cannot demote them.\n\r", ch);
return;
}
}
if (pCmd){
CHAR_DATA* vch = get_char( pCmd->name );
if (pCmd->rank <= RANK_NEWBIE){
send_to_char("They cannot be demoted further.\n\r", ch);
pCmd->rank = RANK_NEWBIE;
}
else{
pCmd->rank--;
sendf(ch, "Demoted to %s.\n\r", clanr_table[pCmd->rank][1]);
}
if (vch && !IS_NPC(vch)){
SynchClanData( vch );
send_to_char("You have been demoted in within your clan!\n\r", vch);
}
}
ClanSave( handle );
return;
}
/* ALLOW */
else if (!str_prefix( arg1, "allow")){
CABAL_DATA* pCab;
CLAN_MEMBER* pCmd = NULL;
CHAR_DATA* victim;
argument = one_argument( argument, arg2);
if (!IS_IMMORTAL(ch)){
send_to_char("You are not an Immortal.\n\r", ch);
return;
}
else if ( IS_NULLSTR(arg2)){
send_to_char("Allow whom to apply to their clan's cabal?\n\r", ch);
return;
}
if (IS_NULLSTR(argument)){
if ( (handle = GET_CLAN(ch)) < 1){
send_to_char("Allow them in which clan?\n\r", ch);
return;
}
}
else if ( (handle = ClanNameToHandle( argument)) < 1){
send_to_char("That clan does not exist.\n\r", ch);
return;
}
//min member check
for (pCab = cabal_list; pCab; pCab = pCab->next){
if (pCab->clan == handle && pCab->cur_member >= pCab->max_member){
send_to_char("The cabal is at max. capacity.\n\r", ch);
return;
}
}
if ( (pCmd = GetClanMember(handle, arg2)) == NULL){
send_to_char("No such member in that clan.\n\r", ch);
return;
}
pCmd->allowed = mud_data.current_time;
if ( (victim = get_char( pCmd->name)) != NULL){
send_to_char("`@You have seven days to apply to your clan's cabal.``\n\r", victim);
}
else{
DESCRIPTOR_DATA* d;
if ( (d = bring(ch->in_room, pCmd->name)) != NULL){
d->character->pcdata->roomnum *= -1;
SET_BIT(d->character->pcdata->messages, MSG_CABAL_ALLOW);
purge(d->character );
}
}
send_to_char("They have been allowed to vote for next 7 days.\n\r", ch);
ClanSave( handle );
return;
}
else
do_clan( ch, "");
}
//returns clan's handle from name
int GetClanHandle( char* name ){
return (ClanNameToHandle( name ));
}
//returns name of clan based onhandle
char* GetClanName( int handle ){
return(ClanHandleToName( handle ));
}
//synchronizes clan and character data
void SynchClanData( CHAR_DATA* ch ){
int handle;
CLAN_MEMBER* pCmd;
if ( (handle = GET_CLAN(ch)) < 1)
return;
else if ( (pCmd = GetClanMember( handle, ch->name)) == NULL)
return;
//synch
pCmd->level = ch->level;
pCmd->class = ch->class;
pCmd->race = ch->race;
pCmd->last_logon = ch->logoff;
pCmd->pts = ch->pcdata->clan_points;
if (ch->pCabal){
pCmd->rank = UMAX(ch->pcdata->rank, pCmd->rank);
ch->pcdata->clan_points = 0;
pCmd->pts = 0;
pCmd->allowed = 0;
}
ch->pcdata->clan_rank = pCmd->rank;
}
//returns member data based on handle and name
CLAN_MEMBER* GetClanMember( int handle, char* name ){
CLAN_MEMBER* pCmd;
CLAN_DATA* pClan = GetClanData( handle );
if (pClan == NULL || IS_NULLSTR(name))
return NULL;
for (pCmd = pClan->members.next; pCmd; pCmd = pCmd->next){
if (!str_cmp(name, pCmd->name))
return pCmd;
}
return NULL;
}
void CharToClan( CHAR_DATA* ch, int handle ){
if (IS_NPC(ch))
return;
ch->pcdata->clan_handle = ClanAddMember( handle, ch);
}
void CharFromClan( CHAR_DATA* ch ){
int handle;
if ( (handle = GET_CLAN( ch )) < 1)
return;
else if (ClanRemMember( handle, ch->name ))
ClanSave( handle );
}
void do_brownie( CHAR_DATA* ch, char* argument ){
CHAR_DATA* victim;
char name[MIL];
int range;
argument = one_argument( argument, name );
range = atoi( argument );
if (IS_NULLSTR(argument)){
send_to_char("Give brownie points to whom and on what scale (-2 to 2)?\n\r", ch);
return;
}
else if ( (victim = get_char( name )) == NULL){
send_to_char("Character not found.\n\r", ch);
return;
}
else if (IS_NPC(victim)){
send_to_char("Not on mobs.\n\r", ch);
return;
}
else if (range == 0){
sendf( ch, "%s has %d points. Use scale of -2 to 2 to remove or add points.\n\r", PERS2(victim), victim->pcdata->clan_points);
return;
}
else if (range < -2 || range > 2){
send_to_char("Use a scale of -2 to 52for the amount of reward.\n\r", ch);
return;
}
switch (range){
case -2: victim->pcdata->clan_points -= 100; break;
case -1: victim->pcdata->clan_points -= 50; break;
case 2: victim->pcdata->clan_points += 100; break;
case 1: victim->pcdata->clan_points += 50; break;
default: break;
}
SynchClanData( victim );
sendf( ch, "%s's clan points now at %d\n\r", PERS2(victim), victim->pcdata->clan_points);
save_char_obj( victim );
ClanSave( GET_CLAN(victim ));
}
int ClanSecondsToApply( CHAR_DATA* ch ){
int handle = GET_CLAN(ch);
CLAN_MEMBER* pCmd;
if (handle < 1){
return 0;
}
else if ( (pCmd = GetClanMember( handle, ch->name)) == NULL){
return 0;
}
else if (pCmd->allowed < 1){
return 0;
}
else if (mud_data.current_time - pCmd->allowed > CLAN_APPLY_WIN){
return 0;
}
else
return (CLAN_APPLY_WIN - (mud_data.current_time - pCmd->allowed));
}
bool ClanApplicationCheck( CHAR_DATA* ch, CABAL_DATA* pCab){
int handle = GET_CLAN(ch);
CLAN_MEMBER* pCmd;
if (handle < 1){
sendf(ch, "You cannot join %s beacuse you're a member of %s.\n\r", pCab->name, GetClanName(pCab->clan));
return FALSE;
}
else if ( (pCmd = GetClanMember( handle, ch->name)) == NULL){
sendf(ch, "You cannot join %s beacuse you're a member of %s.\n\r", pCab->name, GetClanName(pCab->clan));
return FALSE;
}
else if (pCmd->allowed < 1){
sendf(ch, "%s has not allowed you to apply to %s.\n\r", pCab->immortal, pCab->name );
return FALSE;
}
else if (mud_data.current_time - pCmd->allowed > CLAN_APPLY_WIN){
sendf(ch, "You have taken over seven days to apply. %s must allow you to do so once more.\n\r", pCab->immortal);
return FALSE;
}
return TRUE;
}
void ClanEcho( int handle, char* string ){
DESCRIPTOR_DATA* d;
for ( d = descriptor_list; d != NULL; d = d->next ){
if ( d->connected == CON_PLAYING
&& !IS_AFFECTED2(d->character, AFF_SILENCE)
&& !IS_NPC(d->character)
&& !is_affected(d->character,gsn_silence)
&& GET_CLAN(d->character) == handle
){
sendf(d->character,"[`8%s``]: '`0%s``'\n\r", GetClanName(handle), string);
}
}
}
bool ClanRename(int handle, char* current, char* new ){
CLAN_MEMBER* cm;
if (handle < 1 || IS_NULLSTR(current) || IS_NULLSTR(new))
return FALSE;
if ( (cm = GetClanMember(handle, current)) == NULL)
return FALSE;
free_string(cm->name);
cm->name = str_dup (capitalize (new));
return TRUE;
}