/* Required headers... */ /************************************************************************** * 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 Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. 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-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ /*************************************************************************** * ROT 1.4 is copyright 1996-1997 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file doc/rot.license * ***************************************************************************/ /* CLAN CODE by Nico/Zarko(Deryck Arnold) - if it breaks, you know who to blame! * Written exclusively for Asgardian Nightmares - point system idea by Solphor. * newclan.h contains all the header information. */ #if defined(macintosh) #include <types.h> #include <time.h> #else #include <sys/types.h> #include <sys/timeb.h> #endif #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <malloc.h> #include <ctype.h> #include "merc.h" #include "recycle.h" #include "interp.h" #include "tables.h" #include "olc.h" #include "magic.h" #include "newclan.h" #include "pathfind.h" //void update_power(CHAR_DATA *barbarian); #if !defined(IS_VALID) #define IS_VALID( data ) ( ( data ) != NULL && ( data )->valid ) #endif #if !defined(VALIDATE) #define VALIDATE( data ) ( ( data )->valid = TRUE ) #endif #if !defined(INVALIDATE) #define INVALIDATE( data ) ( ( data )->valid = FALSE ) #endif #define is_main_server() TRUE /************************************** VARIABLES *************************************/ PKHIST_DATA * pkhist_table; // Spamkill data table int max_pkhist_entries; // Number of entries in the spamkill table PKILL_DATA * pkill_data_free; // Pointer to PKILL_DATA free list CLAN_DATA * clan_list; // Pointer to clan list CLAN_DATA * clan_free; // Pointer to CLAN_DATA free list int max_clan; // Number of present clans ROSTER_DATA * roster_list; // Pointer to roster list ROSTER_DATA * roster_free; // Pointer to ROSTER_DATA free list time_t roster_next_update; // Time of next update to make sure rosters update every so often time_t roster_next_penalty; // Time of next penalty check to make sure people are penalised for stuff every so often (heh) /********************************* EXTERNAL FUNCTIONS *********************************/ char * length_argument( char *argument, char *arg_first, int length ); void free_auction( AUCTION_DATA *auction ); void save_area( AREA_DATA *pArea ); bool is_safe_quiet( CHAR_DATA * ch, CHAR_DATA * victim ); /*************************************** TABLES ***************************************/ /* Central location for clan log entry type strings */ const struct log_type log_entry_string[] = { { "deposit", "{GDEPOSIT" }, // ENTRY_DEPOSIT { "", "{RDELETED" }, // ENTRY_DELETE { "upgrade", "{CUPGRADE" }, // ENTRY_UPGRADE { "", "{GCREATED" }, // ENTRY_CREATE { "member", "{MNEWMEMB" }, // ENTRY_ACCEPT { "guilds", "{CGUILDED" }, // ENTRY_GUILD { "trust", "{WTRUSTED" }, // ENTRY_TRUST { "exile", "{REXILED " }, // ENTRY_EXILE { "war", "{R--{YWAR{R--" }, // ENTRY_WAR { "changed", "{cCHANGED" }, // ENTRY_CHANGED { "", "", }, }; const struct clan_ranks clan_rank_table[TOTAL_CLAN_RANK] = { { "{MM{member{x", "{MM{mem{x", RANK_MEMBER }, { "{RR{recruit{x", "{RR{rec{x", RANK_RECRUIT }, { "{GS{goldier{x", "{GS{gdr{x", RANK_SOLDIER }, { "{YL{yieutenant{x", "{YL{yie{x", RANK_LIEUTENANT }, { "{WC{wommander{x", "{WC{wdr{x", RANK_COMMANDER }, { "{CE{clite {CC{captain{x", "{CE{clt{x", RANK_ECAPTAIN } }; const struct vnum_table cmob_table[CMOB_MAX + 1] = { { "guard", VNUM_STOCK_MOB_GUARD }, // CMOB_GUARD { "mage", VNUM_STOCK_MOB_MAGE }, // CMOB_MAGE { "mason", VNUM_STOCK_MOB_MASON }, // CMOB_MASON { "trainer", VNUM_STOCK_MOB_TRAINER }, // CMOB_TRAINER { "blacksmith", VNUM_STOCK_MOB_SMITH }, // CMOB_SMITH { "brewer", VNUM_STOCK_MOB_BREWER }, // CMOB_BREWER { "baker", VNUM_STOCK_MOB_BAKER }, // CMOB_BAKER { "good_priest", VNUM_STOCK_MOB_GPRIEST }, // CMOB_GPRIEST { "evil_priest", VNUM_STOCK_MOB_EPRIEST }, // CMOB_EPRIEST { "healer", VNUM_STOCK_MOB_HEALER }, // CMOB_HEALER { "shopkeep", VNUM_STOCK_MOB_SHOPKEEP }, // CMOB_SHOPKEEP { "pet", VNUM_STOCK_MOB_PET }, // CMOB_PET { "tanner", VNUM_STOCK_MOB_TANNER }, // CMOB_TANNER { "questor", VNUM_STOCK_MOB_QUESTOR }, // CMOB_QUESTOR { "", -1 } }; const struct vnum_table croom_table[CROOM_MAX + 1] = { { "recall", VNUM_STOCK_ROOM_RECALL }, // CROOM_RECALL { "smithy", VNUM_STOCK_ROOM_SMITHY }, // CROOM_SMITHY { "workshop", VNUM_STOCK_ROOM_WORKSHOP }, // CROOM_WORKSHOP { "good_shrine", VNUM_STOCK_ROOM_GSHRINE }, // CROOM_GSHRINE { "evil_shrine", VNUM_STOCK_ROOM_ESHRINE }, // CROOM_ESHRINE { "shop", VNUM_STOCK_ROOM_SHOP }, // CROOM_SHOP { "troom", VNUM_STOCK_ROOM_TROOM }, // CROOM_TROOM { "stable", VNUM_STOCK_ROOM_STABLE }, // CROOM_STABLE { "bakery", VNUM_STOCK_ROOM_BAKERY }, // CROOM_BAKERY { "brewery", VNUM_STOCK_ROOM_BREWERY }, // CROOM_BREWERY { "tannery", VNUM_STOCK_ROOM_TANNERY }, // CROOM_TANNERY { "", -1 } }; const struct vnum_table portloc_table[] = { { "midgaard", 3014 }, { "hopecity", 43009 }, { "ghostship", 8100 }, { "box", 45051 }, { "blackwater", 42803 }, { "empar", 37001 }, { "kingdoms", 17536 }, { "plords", 14269 }, { "dragontower", 2201 }, { "hell", 10406 }, { "plordsiceberg", 14277 }, { "plordsflyingmountain", 14258 }, { "", -1 } }; const char * process_name_word[] = { " a ", " an ", " and ", " at ", " her ", " his ", " in ", " is ", " it ", " of ", " on ", " the ", " to ", " with ", " where ", "" }; const struct cedit_cmd_type main_cedit_table[] = { { "create", cedit_create, IMPLEMENTOR, TRUST_NONE, "create a new clan." }, { "delete", cedit_delete, IMPLEMENTOR, TRUST_NONE, "delete a clan and ALL it's assets." }, { "deposit", cedit_deposit, IMPLEMENTOR, TRUST_MEMBER, "deposit either platinum or questpoints into the clan banks." }, { "description", cedit_desc, SUPREME, TRUST_LDR, "change the description of the clan." }, { "guild", cedit_guild, SUPREME, TRUST_NONE, "guild someone into THIS clan." }, { "independent", cedit_indep, IMPLEMENTOR, TRUST_NONE, "make this clan independent or not." }, { "log", cedit_log, SUPREME, TRUST_VLR, "show the clan log." }, { "member", cedit_member, SUPREME, TRUST_LDR, "view, trust or exile clan members." }, { "mob", cedit_mob, SUPREME, TRUST_VLR, "view, purchase or edit clan mobiles." }, { "name", cedit_name, SUPREME, TRUST_LDR, "change the clan name." }, { "obj", cedit_obj, SUPREME, TRUST_VLR, "view, purchase or edit clan equipment." }, { "petition", cedit_petition, IMPLEMENTOR, TRUST_VLR, "view, accept or reject membership petitions." }, { "pkill", cedit_pkill, SUPREME, TRUST_NONE, "make this clan a player-killing clan or not." }, { "rank", cedit_rank, SUPREME, TRUST_LDR, "edit the clan rank who and full names." }, { "room", cedit_room, SUPREME, TRUST_VLR, "view, purchase or edit clan rooms." }, { "show", cedit_show, SUPREME, TRUST_MEMBER, "show the cedit screen again." }, { "skills", cedit_skill, SUPREME, TRUST_MEMBER, "change to scedit to view, buy or sell clan skills." }, { "time", cedit_time, IMPLEMENTOR, TRUST_LDR, "buy more time to edit basic clan data." }, { "war", cedit_war, IMPLEMENTOR, TRUST_LDR, "declare or accept petitions of war." }, { "", NULL, TRUST_NONE, TRUST_NONE, "" } }; const struct cedit_cmd_type mob_cedit_table[] = { { "buy", mcedit_buy, SUPREME, TRUST_VLR, "buy or view upgrades for the current mobile." }, { "desc", mcedit_desc, SUPREME, TRUST_VLR, "edit the detailed description of the mobile." }, { "long", mcedit_long, SUPREME, TRUST_VLR, "edit the long description(in room) of the mobile." }, { "short", mcedit_short, SUPREME, TRUST_VLR, "edit the short description(interaction) of the mobile." }, { "show", mcedit_show, SUPREME, TRUST_VLR, "show the mcedit screen again." }, { "", NULL, TRUST_NONE, TRUST_NONE, "" } }; const struct cedit_cmd_type obj_cedit_table[] = { { "buy", ocedit_buy, SUPREME, TRUST_VLR, "buy or view upgrades for the current object." }, { "long", ocedit_long, SUPREME, TRUST_VLR, "edit the long description(in room) of the object." }, { "junk", ocedit_sell, SUPREME, TRUST_LDR, "junk the object - no money back." }, { "short", ocedit_short, SUPREME, TRUST_VLR, "edit the short description(interaction) of the object." }, { "show", ocedit_show, SUPREME, TRUST_VLR, "show the ocedit screen again." }, { "", NULL, TRUST_NONE, TRUST_NONE, "" } }; const struct cedit_cmd_type room_cedit_table[] = { { "buy", rcedit_buy, SUPREME, TRUST_VLR, "buy or view upgrades for the current room." }, { "desc", rcedit_desc, SUPREME, TRUST_VLR, "edit the room description." }, { "exdesc", rcedit_exdesc, SUPREME, TRUST_VLR, "edit the extra descriptions and their keywords." }, { "name", rcedit_name, SUPREME, TRUST_VLR, "edit the name of the room." }, { "show", rcedit_show, SUPREME, TRUST_VLR, "show the rcedit screen again." }, { "", NULL, TRUST_NONE, TRUST_NONE, "" } }; const struct cedit_cmd_type skill_cedit_table[] = { { "buy", scedit_buy, SUPREME, TRUST_LDR, "buy a clan skill." }, { "list", scedit_show, SUPREME, TRUST_MEMBER, "list the clan skills." }, { "sell", scedit_sell, SUPREME, TRUST_LDR, "sell a clan skill." }, { "show", scedit_show, SUPREME, TRUST_MEMBER, "same as list - list the clan skills." }, { "", NULL, TRUST_NONE, TRUST_NONE, "" } }; struct clan_skill_cmds clan_skill_table[] = { { "adrenaline", "Adrenaline", "Damroll bonus equal to 60%% of your level.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_adrenaline, FALSE, POS_STANDING, do_adrenaline }, { "bfury", "Battle Fury", "Damroll, hitroll and armour bonuses equal to a 7th of your level. Additional steel skin shield.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_battle_fury, FALSE, POS_STANDING, do_battle_fury }, { "blust", "Blood Lust", "Damroll, hitroll and armour bonuses equal to a 6th of your level.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_bloodlust, FALSE, POS_STANDING, do_bloodlust }, { "conceal", "Conceal", "Damroll and hitroll bonuses equal to an 8th of your level. Morphs you into \"A dark assassin\" and adds sneak.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_concealClan1, FALSE, POS_STANDING, do_conceal }, // { // "cripple", // "Cripple", // "Combat skill resulting in damage and possible blindness, possible disarmament or possible reduction in moves of the victim.", // RANK_LIEUTENANT, PRICE_SKILL_MAJOR_QP, // PRICE_SKILL_MAJOR_PLAT, NULL, TRUE, POS_FIGHTING, NULL, // do_cripple }, { "divide", "The Divide", "Damroll, hitroll and armour bonuses equal to a 7th of your level. Additional stone skin shield.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_divide, FALSE, POS_STANDING, do_divide }, { "faith", "Blind Faith", "A skill causing damage and possible blindness of the victim.", RANK_LIEUTENANT, PRICE_SKILL_MAJOR_QP, PRICE_SKILL_MAJOR_PLAT, NULL, TRUE, POS_FIGHTING, do_faith }, { "modi", "Power of Modi", "A two-part skill - either a damroll bonus or hitroll bonus equal to 40% of your level.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, NULL, FALSE, POS_STANDING, do_modi }, { "sform", "Shadow Form", "Armour bonus equal to 60% of your level.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_shadow_form, FALSE, POS_STANDING, do_shadow_form }, // { // "solar", // "Solar Flare", // "Room-effect blindness skill. NOTE: There is a 1% chance that you can blind yourself when using it.", // RANK_LIEUTENANT, PRICE_SKILL_MAJOR_QP, // PRICE_SKILL_MAJOR_PLAT, NULL, TRUE, POS_STANDING, NULL, // do_solar_flare }, { "vmight", "Might of the Vanir", "Damroll and armour bonuses equal to a 5th of your level. Additional stone skin shield.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_vmight, FALSE, POS_STANDING, do_vmight }, { "wform", "Wolf Form", "Damroll and hitroll bonuses equal to an 8th of your level. Morphs you into \"A wolfish beast\" and adds sneak.", RANK_RECRUIT, PRICE_SKILL_MINOR_QP, PRICE_SKILL_MINOR_PLAT, &gsn_concealClan2, FALSE, POS_STANDING, do_wform }, { "", "", "", 0, 0, 0, NULL, FALSE, POS_DEAD, NULL } }; COST_DATA mob_prices[] = { { .name = "guard", .func = mob_normal, .descr = "A guard to protect your hall", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_GUARD, .specific[1] = CROOM_RECALL, .max_func = NULL, .qps = 300, .platinum = 10000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mage", .func = mob_normal, .descr = "Your friendly in-house mage", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_MAGE, .specific[1] = CROOM_WORKSHOP, .max_func = NULL, .qps = 1000, .platinum = 5000, .cRoom[CROOM_WORKSHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mason", .func = mob_normal, .descr = "Someone who you can't do without for clan rooms", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_MASON, .specific[1] = CROOM_RECALL, .max_func = NULL, .qps = 100, .platinum = 2500, .cRoom[CROOM_RECALL] = TRUE }, { .name = "trainer", .func = mob_normal, .descr = "Someone to train your mobiles", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_TRAINER, .specific[1] = CROOM_TROOM, .max_func = NULL, .qps = 1200, .platinum = 8000, .cRoom[CROOM_TROOM] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "blacksmith", .func = mob_normal, .descr = "A pretty essential person for good-quality equipment", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_SMITH, .specific[1] = CROOM_SMITHY, .max_func = NULL, .qps = 500, .platinum = 12000, .cRoom[CROOM_SMITHY] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "brewer", .func = mob_normal, .descr = "Brews up potions", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_BREWER, .specific[1] = CROOM_BREWERY, .max_func = NULL, .qps = 3000, .platinum = 6000, .cRoom[CROOM_BREWERY] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "baker", .func = mob_normal, .descr = "This one can bake you some food and pills", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_BAKER, .specific[1] = CROOM_BAKERY, .max_func = NULL, .qps = 4000, .platinum = 8000, .cRoom[CROOM_BAKERY] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "good_priest", .func = mob_normal, .descr = "A good priest", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_GPRIEST, .specific[1] = CROOM_GSHRINE, .max_func = NULL, .qps = 3000, .platinum = 10000, .cRoom[CROOM_GSHRINE] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "evil_priest", .func = mob_normal, .descr = "An evil priest", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_EPRIEST, .specific[1] = CROOM_ESHRINE, .max_func = NULL, .qps = 3000, .platinum = 10000, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "healer", .func = mob_normal, .descr = "Quite handy to have around, good for upgrades too", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_HEALER, .specific[1] = -1, .max_func = NULL, .qps = 5000, .platinum = 12000, .cRoom[CROOM_GSHRINE] = TRUE, .cRoom[CROOM_ESHRINE] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "shopkeep", .func = mob_normal, .descr = "This one sells all the clan goodies", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_SHOPKEEP, .specific[1] = CROOM_SHOP, .max_func = NULL, .qps = 0, .platinum = 1000, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "pet", .func = mob_normal, .descr = "Something to feed if you're bored", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_PET, .specific[1] = CROOM_STABLE, .max_func = NULL, .qps = 1000, .platinum = 10000, .cRoom[CROOM_TROOM] = TRUE, .cRoom[CROOM_STABLE] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "tanner", .func = mob_normal, .descr = "This one likes corpses, very very much", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_TANNER, .specific[1] = CROOM_TANNERY, .max_func = NULL, .qps = 250, .platinum = 2000, .cRoom[CROOM_TANNERY] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "questor", .func = mob_normal, .descr = "This one gives you quests if you're nice", .curr_value = cval_mob_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = 1, .specific[0] = CMOB_QUESTOR, .specific[1] = CROOM_RECALL, .max_func = NULL, .qps = 3000, .platinum = 0, .cRoom[CROOM_RECALL] = TRUE }, { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; COST_DATA obj_prices[] = { { .name = "furniture", .func = obj_normal, .descr = "Something to lounge around on", .curr_value = cval_obj_normal, .flags = UPGD_ROOM_OBJ|UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_FURNITURE, .specific[1] = ITEM_FURNITURE, .max_func = mval_obj_normal, .qps = 0, .platinum = 2000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "portal", .func = obj_normal, .descr = "A quick way to get places", .curr_value = cval_obj_normal, .flags = UPGD_ROOM_OBJ|UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_PORTAL, .specific[1] = ITEM_PORTAL, .max_func = mval_obj_normal, .qps = 1250, .platinum = 4000, .cMob[CMOB_MAGE] = 75, .cRoom[CROOM_RECALL] = TRUE }, { .name = "scroll", .func = obj_normal, .descr = "Good if you can read", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_SCROLL, .specific[1] = ITEM_SCROLL, .max_func = mval_obj_normal, .qps = 500, .platinum = 1500, .cMob[CMOB_MAGE] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "wand", .func = obj_normal, .descr = "Zapping people can be fun with one of these", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_WAND, .specific[1] = ITEM_WAND, .max_func = mval_obj_normal, .qps = 500, .platinum = 1500, .cMob[CMOB_MAGE] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "staff", .func = obj_normal, .descr = "Just like the wand, only bigger (size doesn't matter, or does it?)", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_STAFF, .specific[1] = ITEM_STAFF, .max_func = mval_obj_normal, .qps = 500, .platinum = 1500, .cMob[CMOB_MAGE] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "weapon", .func = obj_normal, .descr = "Good for hurting people", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_WEAPON, .specific[1] = ITEM_WEAPON, .max_func = mval_obj_normal, .qps = 500, .platinum = 4000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "armour", .func = obj_normal, .descr = "Good for covering those.. bits that need covering", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_ARMOUR, .specific[1] = ITEM_ARMOR, .max_func = mval_obj_normal, .qps = 500, .platinum = 4000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "potion", .func = obj_normal, .descr = "Useful when you're out in the field", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_POTION, .specific[1] = ITEM_POTION, .max_func = mval_obj_normal, .qps = 1000, .platinum = 4000, .cMob[CMOB_BREWER] = 1, .cMob[CMOB_MAGE] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "container", .func = obj_normal, .descr = "Holds all your loot", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_CONTAINER, .specific[1] = ITEM_CONTAINER, .max_func = mval_obj_normal, .qps = 500, .platinum = 6000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "dcontainer", .func = obj_normal, .descr = "An excellent choice for booze", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_DCONTAINER, .specific[1] = ITEM_DRINK_CON, .max_func = mval_obj_normal, .qps = 500, .platinum = 2000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_BREWER] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "food", .func = obj_normal, .descr = "Something to nibble on when hungry", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_FOOD, .specific[1] = ITEM_FOOD, .max_func = mval_obj_normal, .qps = 0, .platinum = 1000, .cMob[CMOB_BAKER] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "boat", .func = obj_normal, .descr = "Don't go out to sea without one of these", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_BOAT, .specific[1] = ITEM_BOAT, .max_func = mval_obj_normal, .qps = 0, .platinum = 2000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "fountain", .func = obj_normal, .descr = "Water, milk, coke, beer, you pick", .curr_value = cval_obj_normal, .flags = UPGD_ROOM_OBJ|UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_FOUNTAIN, .specific[1] = ITEM_FOUNTAIN, .max_func = mval_obj_normal, .qps = 250, .platinum = 3000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "slot_machine", .func = obj_normal, .descr = "Need to satisfy that gambling addiction?", .curr_value = cval_obj_normal, .flags = UPGD_ROOM_OBJ|UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_SLOT_MACHINE, .specific[1] = ITEM_SLOT_MACHINE, .max_func = mval_obj_normal, .qps = 0, .platinum = 3000, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE, .cMob[CMOB_SHOPKEEP] = 1, }, { .name = "pill", .func = obj_normal, .descr = "Popping pills can be good for you", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_PILL, .specific[1] = ITEM_PILL, .max_func = mval_obj_normal, .qps = 2000, .platinum = 8000, .cMob[CMOB_BREWER] = 1, .cMob[CMOB_BAKER] = 1, .cMob[CMOB_GPRIEST] = 1, .cMob[CMOB_EPRIEST] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "warp_stone", .func = obj_normal, .descr = "Portals on the go with the the right spells", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_WARP_STONE, .specific[1] = ITEM_WARP_STONE, .max_func = mval_obj_normal, .qps = 2000, .platinum = 5000, .cMob[CMOB_MAGE] = 150, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "demon_stone", .func = obj_normal, .descr = "A demon in a can (well.. more like a stone)", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_DEMON_STONE, .specific[1] = ITEM_DEMON_STONE, .max_func = mval_obj_normal, .qps = 2000, .platinum = 5000, .cMob[CMOB_GPRIEST] = 150, .cMob[CMOB_EPRIEST] = 150, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "light", .func = obj_normal, .descr = "Scared of the dark?", .curr_value = cval_obj_normal, .flags = UPGD_NO_BULK, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = VNUM_STOCK_OBJ_LIGHT, .specific[1] = ITEM_LIGHT, .max_func = mval_obj_normal, .qps = 500, .platinum = 4000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_SHOPKEEP] = 1, .cRoom[CROOM_SHOP] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; COST_DATA room_prices[] = { { .name = "recall", .func = room_recall, .descr = "The standard clan recall hall", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_RECALL, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 2000 }, { .name = "smithy", .func = room_normal, .descr = "A smithy to house a blacksmith", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_SMITHY, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 10000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "workshop", .func = room_normal, .descr = "A workshop to house a mage", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_WORKSHOP, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 1000, .platinum = 5000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "good_shrine", .func = room_normal, .descr = "A shrine to house a good priest", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_GSHRINE, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 1000, .platinum = 500, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "evil_shrine", .func = room_normal, .descr = "A shrine to house an evil priest", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_ESHRINE, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 1000, .platinum = 500, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "shop", .func = room_normal, .descr = "A shop to house a shopkeep", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_SHOP, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 5000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "troom", .func = room_normal, .descr = "A room to house the trainer", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_TROOM, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 5000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "stable", .func = room_normal, .descr = "A room to house a pet", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_STABLE, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 4000, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_TROOM] = TRUE, .cRoom[CROOM_RECALL] = TRUE }, { .name = "brewery", .func = room_normal, .descr = "A brewery for a brewer", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_BREWERY, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 1000, .platinum = 3000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "bakery", .func = room_normal, .descr = "A bakery for a baker", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_BAKERY, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 1000, .platinum = 3000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "tannery", .func = room_normal, .descr = "A tannery for a tanner", .curr_value = cval_room_normal, .quantity = 1, .max = 1, .specific[0] = CROOM_TANNERY, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 5000, .cMob[CMOB_MASON] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "entrance", .func = room_hall_entrance, .descr = "Change the entrance/exit of the clan hall", .curr_value = cval_room_hall_entrance, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_room_hall_entrance, .flags = UPGD_NO_BULK, .qps = 0, .platinum = 1000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; COST_DATA mob_upgd_prices[] = { { .name = "level", .func = mob_upgd_level, .descr = "Increase the level of the mob (cannot exceed level of trainer)", .curr_value = cval_mob_upgd_level, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_mob_upgd_level, .qps = 0, .platinum = 250, .cMob[CMOB_TRAINER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "hp", .func = mob_upgd_hp, .descr = "Increase the hitpoints of the mob", .curr_value = cval_mob_upgd_hp, .quantity = 1000, .max = 50000, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 500, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_HEALER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mana", .func = mob_upgd_mana, .descr = "Increase the mana of the mob", .curr_value = cval_mob_upgd_mana, .quantity = 1000, .max = 50000, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 400, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "damage", .func = mob_upgd_damage, .descr = "Increase the damage of the mob", .curr_value = cval_mob_upgd_damage, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_mob_upgd_damage, .qps = 25, .platinum = 250, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "imm", .func = mob_upgd_imm, .descr = "Add an immunity to the mob", .curr_value = cval_mob_upgd_imm, .flags = UPGD_NO_BULK|UPGD_FLAG|UPGD_XCOST, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_xcost_count, .xcost = imm_prices, .xreq1 = CMOB_TRAINER, .xreq2 = CMOB_MAGE, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "res", .func = mob_upgd_res, .descr = "Add a resistance to the mob", .curr_value = cval_mob_upgd_res, .flags = UPGD_NO_BULK|UPGD_FLAG|UPGD_XCOST, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_xcost_count, .xcost = res_prices, .xreq1 = CMOB_TRAINER, .xreq2 = CMOB_MAGE, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "off", .func = mob_upgd_off, .descr = "Add an offensive skill to the mob", .curr_value = cval_mob_upgd_off, .flags = UPGD_NO_BULK|UPGD_FLAG|UPGD_XCOST, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_xcost_count, .xcost = off_prices, .xreq1 = CMOB_TRAINER, .xreq2 = CMOB_MAGE, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "damtype", .func = mob_upgd_damtype, .descr = "Change the damage type of the mob", .curr_value = cval_mob_upgd_damtype, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_xcost_count, .xcost = damtype_prices, .xreq1 = CMOB_TRAINER, .xreq2 = CMOB_MAX, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "ac", .func = mob_upgd_ac, .descr = "Increase the armour of the mob", .curr_value = cval_mob_upgd_ac, .quantity = 1, .max = 1500, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 10, .platinum = 250, .cMob[CMOB_TRAINER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "effect", .func = mob_upgd_perm, .descr = "Add a permanent effect to the mob", .curr_value = cval_mob_upgd_perm, .flags = UPGD_NO_BULK|UPGD_FLAG|UPGD_XCOST, .quantity = 1, .max = MAX_SPECIAL, .specific[0] = -1, .specific[1] = -1, .max_func = mval_xcost_count, .xcost = bitaf_prices, .xreq1 = CMOB_MAX, .xreq2 = CMOB_MAX, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; COST_DATA obj_upgd_prices[] = { { .name = "hp_regen", .func = obj_upgd_v3, .descr = "Increase the hitpoint regeneration rate", .curr_value = cval_obj_upgd_v3, .quantity = 50, .max = 1000, .specific[0] = ITEM_FURNITURE, .specific[1] = -1, .max_func = NULL, .qps = 100, .platinum = 3000, .cMob[CMOB_HEALER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mana_regen", .func = obj_upgd_v4, .descr = "Increase the mana regeneration rate", .curr_value = cval_obj_upgd_v4, .quantity = 50, .max = 1000, .specific[0] = ITEM_FURNITURE, .specific[1] = -1, .max_func = NULL, .qps = 150, .platinum = 2000, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "capacity", .func = obj_upgd_furn_capacity, .descr = "Increase the number of people who can use the item at one time", .curr_value = cval_obj_upgd_v0, .quantity = 2, .max = 20, .specific[0] = ITEM_FURNITURE, .specific[1] = -1, .max_func = NULL, .qps = 100, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "duration", .func = obj_upgd_v2, .descr = "Increase the duration of the light", .curr_value = cval_obj_upgd_v2, .quantity = 1, .max = 999, .specific[0] = ITEM_LIGHT, .specific[1] = -1, .max_func = NULL, .qps = 50, .platinum = 200, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "add_spell", .func = obj_upgd_add1_spell, .descr = "Add a spell to the wand", .curr_value = cval_obj_upgd_add1_spell, .xcost = spell_prices, .xreq1 = CMOB_MAGE, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_WAND, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "add_spell", .func = obj_upgd_add1_spell, .descr = "Add a spell to the staff", .curr_value = cval_obj_upgd_add1_spell, .xcost = spell_prices, .xreq1 = CMOB_MAGE, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_STAFF, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "add_spell", .func = obj_upgd_add3_spell, .descr = "Add a spell to the scroll", .curr_value = cval_obj_upgd_add3_spell, .xcost = spell_prices, .xreq1 = CMOB_MAGE, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_SCROLL, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "spell_level", .func = obj_upgd_v0, .descr = "Upgrade the spell level on the wand", .curr_value = cval_obj_upgd_v0, .quantity = 1, .max = 101, .specific[0] = ITEM_WAND, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 250, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "spell_level", .func = obj_upgd_v0, .descr = "Upgrade the spell level on the staff", .curr_value = cval_obj_upgd_v0, .quantity = 1, .max = 101, .specific[0] = ITEM_STAFF, .specific[1] = -1, .max_func = NULL, .qps = 200, .platinum = 300, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "spell_level", .func = obj_upgd_v0, .descr = "Upgrade the spell level on the scroll", .curr_value = cval_obj_upgd_v0, .quantity = 1, .max = 101, .specific[0] = ITEM_SCROLL, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 250, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "charges", .func = obj_upgd_charges, .descr = "Upgrade the number of charges on the wand", .curr_value = cval_obj_upgd_v2, .quantity = 1, .max = 50, .specific[0] = ITEM_WAND, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "charges", .func = obj_upgd_charges, .descr = "Upgrade the number of charges on the staff", .curr_value = cval_obj_upgd_v2, .quantity = 1, .max = 50, .specific[0] = ITEM_STAFF, .specific[1] = -1, .max_func = NULL, .qps = 200, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "damage", .func = obj_upgd_damage, .descr = "Boost the damdice on the weapon", .curr_value = cval_obj_upgd_v2, .quantity = 1, .max = 14, .specific[0] = ITEM_WEAPON, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 750, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "damtype", .func = obj_upgd_damtype, .descr = "Change the damage type of the weapon", .curr_value = cval_obj_upgd_damtype, .xcost = damtype_prices, .xreq1 = CMOB_TRAINER, .xreq2 = CMOB_MAGE, .flags = UPGD_NO_BULK|UPGD_XCOST|UPGD_FLAG, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_WEAPON, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "wpn_flag", .func = obj_upgd_wpnflag, .descr = "Add a weapon flag", .curr_value = cval_obj_upgd_wpnflag, .xcost = wpnflag_prices, .xreq1 = CMOB_SMITH, .xreq2 = CMOB_MAGE, .flags = UPGD_NO_BULK|UPGD_XCOST|UPGD_FLAG, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_WEAPON, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "add_spell", .func = obj_upgd_add3_spell, .descr = "Add a spell to the potion", .curr_value = cval_obj_upgd_add3_spell, .xcost = spell_prices, .xreq1 = CMOB_MAGE, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_POTION, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "add_spell", .func = obj_upgd_add3_spell, .descr = "Add a spell to the pill", .curr_value = cval_obj_upgd_add3_spell, .xcost = spell_prices, .xreq1 = CMOB_MAGE, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_XCOST, .quantity = 1, .max = MAX_NONE, .specific[0] = ITEM_PILL, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "spell_level", .func = obj_upgd_v0, .descr = "Increase the spell levels of the potion", .curr_value = cval_obj_upgd_v0, .quantity = 1, .max = 115, .specific[0] = ITEM_POTION, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 0, .cMob[CMOB_BREWER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "spell_level", .func = obj_upgd_v0, .descr = "Increase the spell levels of the pill", .curr_value = cval_obj_upgd_v0, .quantity = 1, .max = 101, .specific[0] = ITEM_PILL, .specific[1] = -1, .max_func = NULL, .qps = 300, .platinum = 0, .cMob[CMOB_BAKER] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "capacity", .func = obj_upgd_cont_capacity, .descr = "Increase the capacity of the container", .curr_value = cval_obj_upgd_v0, .quantity = 10, .max = 500, .specific[0] = ITEM_CONTAINER, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 250, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "capacity", .func = obj_upgd_v0, .descr = "Increase the capacity of the drink container", .curr_value = cval_obj_upgd_v0, .quantity = 5, .max = MAX_NONE, .specific[0] = ITEM_DRINK_CON, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 250, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_BREWER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "duration", .func = obj_upgd_v0, .descr = "Increase the duration of the \"full\" effect", .curr_value = cval_obj_upgd_v0, .quantity = 5, .max = 50, .specific[0] = ITEM_FOOD, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 300, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_BAKER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "hitroll", .func = obj_upgd_affected, .descr = "Increase the hitroll on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 35, .specific[0] = -1, .specific[1] = APPLY_HITROLL, .max_func = NULL, .qps = 50, .platinum = 750, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "damroll", .func = obj_upgd_affected, .descr = "Increase the damroll on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 35, .specific[0] = -1, .specific[1] = APPLY_DAMROLL, .max_func = NULL, .qps = 50, .platinum = 750, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "hp", .func = obj_upgd_affected, .descr = "Increase the hitpoints on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 250, .specific[0] = -1, .specific[1] = APPLY_HIT, .max_func = NULL, .qps = 5, .platinum = 250, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_HEALER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mana", .func = obj_upgd_affected, .descr = "Increase the mana on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 250, .specific[0] = -1, .specific[1] = APPLY_MANA, .max_func = NULL, .qps = 10, .platinum = 200, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "move", .func = obj_upgd_affected, .descr = "Increase the moves on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 250, .specific[0] = -1, .specific[1] = APPLY_MOVE, .max_func = NULL, .qps = 5, .platinum = 200, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "age", .func = obj_upgd_affected, .descr = "Increase the age on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 20, .specific[0] = -1, .specific[1] = APPLY_AGE, .max_func = NULL, .qps = 500, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "hp_regen", .func = obj_upgd_affected, .descr = "Increase the hitpoint regeneration", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_REGEN, .max_func = NULL, .qps = 750, .platinum = 2000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_HEALER] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mana_regen", .func = obj_upgd_affected, .descr = "Increase the mana regeneration", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_MANA_REGEN, .max_func = NULL, .qps = 750, .platinum = 2000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "saves", .func = obj_upgd_affected, .descr = "Increase the saves on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 8, .specific[0] = -1, .specific[1] = APPLY_SAVES, .max_func = NULL, .qps = 1000, .platinum = 0, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cMob[CMOB_GPRIEST] = 1, .cMob[CMOB_EPRIEST] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "ac", .func = obj_upgd_affected, .descr = "Increase the ac on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 30, .specific[0] = -1, .specific[1] = APPLY_AC, .max_func = NULL, .qps = 100, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "str", .func = obj_upgd_affected, .descr = "Increase the strength on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_STR, .max_func = NULL, .qps = 250, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "int", .func = obj_upgd_affected, .descr = "Increase the intelligence on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_INT, .max_func = NULL, .qps = 250, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "wis", .func = obj_upgd_affected, .descr = "Increase the wisdom on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_WIS, .max_func = NULL, .qps = 250, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "dex", .func = obj_upgd_affected, .descr = "Increase the dexterity on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_DEX, .max_func = NULL, .qps = 250, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "con", .func = obj_upgd_affected, .descr = "Increase the constitution on the item", .curr_value = cval_obj_upgd_affected, .quantity = 1, .max = 5, .specific[0] = -1, .specific[1] = APPLY_CON, .max_func = NULL, .qps = 250, .platinum = 1000, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag", .func = obj_upgd_objflag, .descr = "Add an object flag to the item", .curr_value = cval_obj_upgd_objflag, .xcost = objflag_prices, .xreq1 = CMOB_SMITH, .xreq2 = CMOB_MAGE, .flags = UPGD_NO_BULK|UPGD_XCOST|UPGD_FLAG, .quantity = 1, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_SMITH] = 1, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, { .name = "wear_loc", .func = obj_upgd_wearloc, .descr = "Change the wear location for the object", .curr_value = cval_obj_upgd_wearloc, .flags = UPGD_NO_BULK|UPGD_FLAG, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cRoom[CROOM_RECALL] = TRUE }, /* { .name = "effect", .func = obj_upgd_affected, .descr = "Add a permanent effect to the item", .curr_value = cval_obj_upgd_affected, .xcost = bitaf_prices, .xreq1 = CMOB_MAX, .xreq2 = CMOB_MAX, .flags = UPGD_NO_BULK|UPGD_FLAG|UPGD_XCOST, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_MAGE] = 1, .cRoom[CROOM_RECALL] = TRUE }, */ { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; COST_DATA room_upgd_prices[] = { { .name = "hp_regen", .func = room_upgd_hpregen, .descr = "Upgrade the hitpoint regeneration rate", .curr_value = cval_room_upgd_hpregen, .quantity = 50, .max = 600, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 7500, .cMob[CMOB_HEALER] = 40, .cRoom[CROOM_RECALL] = TRUE }, { .name = "mana_regen", .func = room_upgd_manaregen, .descr = "Upgrade the mana regeneration rate", .curr_value = cval_room_upgd_manaregen, .quantity = 50, .max = 600, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 250, .platinum = 7500, .cMob[CMOB_MAGE] = 40, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_dark", .func = room_upgd_flag, .descr = "Flag/unflag the room as dark", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_DARK, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 0, .platinum = 1000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_nomob", .func = room_upgd_flag, .descr = "Flag/unflag the room as no mob", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_NO_MOB, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 0, .platinum = 4000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_indoors", .func = room_upgd_flag, .descr = "Flag/unflag the room as indoors", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_INDOORS, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 0, .platinum = 1000, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_nomagic", .func = room_upgd_flag, .descr = "Flag/unflag the room as no magic", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_NO_MAGIC, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 500, .platinum = 2000, .cMob[CMOB_MAGE] = 50, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_norecall", .func = room_upgd_flag, .descr = "Flag/unflag the room as no recall", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_NO_RECALL, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 250, .platinum = 2000, .cMob[CMOB_MAGE] = 40, .cMob[CMOB_GPRIEST] = 40, .cMob[CMOB_EPRIEST] = 40, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_heroesonly", .func = room_upgd_flag, .descr = "Flag/unflag the room as heroes only", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_HEROES_ONLY, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 0, .platinum = 1000, .cMob[CMOB_MASON] = 60, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_law", .func = room_upgd_flag, .descr = "Flag/unflag the room as law", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_LAW, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 0, .platinum = 1000, .cMob[CMOB_MAGE] = 50, .cMob[CMOB_GPRIEST] = 50, .cMob[CMOB_EPRIEST] = 50, .cRoom[CROOM_RECALL] = TRUE }, { .name = "flag_nowhere", .func = room_upgd_flag, .descr = "Flag/unflag the room as nowhere", .curr_value = cval_room_upgd_flag, .quantity = 1, .max = MAX_NONE, .specific[0] = ROOM_NOWHERE, .specific[1] = -1, .max_func = NULL, .flags = UPGD_NO_BULK|UPGD_FLAG, .qps = 250, .platinum = 2000, .cMob[CMOB_MAGE] = 75, .cMob[CMOB_GPRIEST] = 75, .cMob[CMOB_EPRIEST] = 75, .cRoom[CROOM_RECALL] = TRUE }, { .name = "", .func = NULL, .descr = "", .curr_value = NULL, .quantity = 0, .max = MAX_NONE, .specific[0] = -1, .specific[1] = -1, .max_func = NULL, .qps = 0, .platinum = 0, .cMob[CMOB_TRAINER] = 0, .cMob[CMOB_SMITH] = 0, .cMob[CMOB_BREWER] = 0, .cMob[CMOB_BAKER] = 0, .cMob[CMOB_MAGE] = 0, .cMob[CMOB_MASON] = 0, .cMob[CMOB_GPRIEST] = 0, .cMob[CMOB_EPRIEST] = 0, .cMob[CMOB_HEALER] = 0, .cMob[CMOB_SHOPKEEP] = 0, .cMob[CMOB_PET] = 0, .cMob[CMOB_TANNER] = 0, .cMob[CMOB_QUESTOR] = 0, .cMob[CMOB_GUARD] = 0, .cRoom[CROOM_GSHRINE] = FALSE, .cRoom[CROOM_ESHRINE] = FALSE, .cRoom[CROOM_SMITHY] = FALSE, .cRoom[CROOM_WORKSHOP] = FALSE, .cRoom[CROOM_SHOP] = FALSE, .cRoom[CROOM_TROOM] = FALSE, .cRoom[CROOM_STABLE] = FALSE, .cRoom[CROOM_BAKERY] = FALSE, .cRoom[CROOM_BREWERY] = FALSE, .cRoom[CROOM_TANNERY] = FALSE, .cRoom[CROOM_RECALL] = TRUE } }; /* Spells for scrolls/wands/scrolls: req1=mage */ XCOST_DATA spell_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "armor", 0, 0, 0, 5000, SPELL_DEFENSIVE, 0, 0, }, { "bless", 0, 0, 0, 5000, SPELL_DEFENSIVE, 0, 0, }, { "cancellation", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 40, 0, }, { "cure_blind", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "cure_critical", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 40, 0, }, { "cure_disease", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "cure_light", 0, 0, 0, 5000, SPELL_DEFENSIVE, 0, 0, }, { "cure_poison", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "detect_evil", 0, 0, 500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "detect_good", 0, 0, 500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "detect_motion", 0, 0, 500, 5000, SPELL_DEFENSIVE, 60, 0, }, { "detect_invis", 0, 0, 500, 5000, SPELL_DEFENSIVE, 60, 0, }, { "detect_location", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 100, 0, }, { "detect_magic", 0, 0, 500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "detect_poison", 0, 0, 0, 5000, SPELL_DEFENSIVE, 0, 0, }, { "displace", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "farsight", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "fireshield", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 50, 0, }, { "fly", 0, 0, 500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "frenzy", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "giant_strength", 0, 0, 0, 5000, SPELL_DEFENSIVE, 45, 0, }, { "haste", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 45, 0, }, { "heal", 0, 0, 2000, 5000, SPELL_DEFENSIVE, 30, 0, }, { "iceshield", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 50, 0, }, { "infravision", 0, 0, 500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "invisibility", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "mass_healing", 0, 0, 2000, 5000, SPELL_DEFENSIVE, 40, 0, }, { "mass_invis", 0, 0, 2000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "pass_door", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 0, 0, }, { "protection_evil", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 50, 0, }, { "protection_good", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 50, 0, }, { "refresh", 0, 0, 0, 5000, SPELL_DEFENSIVE, 0, 0, }, { "remove_curse", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 0, 0, }, { "restore_mana", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 75, 0, }, { "sanctuary", 0, 0, 2000, 5000, SPELL_DEFENSIVE, 75, 0, }, { "shield", 0, 0, 0, 5000, SPELL_DEFENSIVE, 40, 0, }, { "shockshield", 0, 0, 1500, 5000, SPELL_DEFENSIVE, 50, 0, }, { "stone_skin", 0, 0, 1000, 5000, SPELL_DEFENSIVE, 75, 0, }, { "acid_rain", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 65, 0, }, { "acid_blast", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 95, 0, }, { "blindness", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "burning_hands", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "call_lightning", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "calm", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, //{ "cause_critical", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 0, 0, }, //{ "cause_light", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "cause_serious", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "chain_lightning", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "change_sex", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "chill_touch", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "colour_spray", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "curse", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "demonfire", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 55, 0, }, { "dispel_evil", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 40, 0, }, { "dispel_good", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 40, 0, }, { "dispel_magic", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 45, 0, }, { "earthquake", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "energy_drain", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "faerie_fire", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "feeble_mind", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 50, 0, }, { "fireball", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "flamestrike", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "harm", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "heat_metal", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 60, 0, }, { "holy_word", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 55, 0, }, { "lightning_bolt", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "magic_missile", 0, 0, 0, 5000, SPELL_OFFENSIVE, 0, 0, }, { "plague", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "poison", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "prismatic_spray", 0, 0, 500, 5000, SPELL_OFFENSIVE, 60, 0, }, { "ray_of_truth", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 55, 0, }, { "shocking_grasp", 0, 0, 500, 5000, SPELL_OFFENSIVE, 0, 0, }, { "sleep", 0, 0, 2000, 5000, SPELL_OFFENSIVE, 0, 0, }, { "slow", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 60, 0, }, { "teleport", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 60, 0, }, { "weaken", 0, 0, 1000, 5000, SPELL_OFFENSIVE, 60, 0, }, { "acid_breath", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 75, 0, }, { "fire_breath", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 75, 0, }, { "frost_breath", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 75, 0, }, { "gas_breath", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 75, 0, }, { "lightning_breath", 0, 0, 1500, 5000, SPELL_OFFENSIVE, 75, 0, }, { "animate", 0, 0, 1000, 5000, SPELL_MISC, 60, 0, }, { "conjure", 0, 0, 2000, 5000, SPELL_MISC, 60, 0, }, { "continual_light", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "control_weather", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "create_food", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "create_rose", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "create_spring", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "create_water", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "dispel_invis", 0, 0, 500, 5000, SPELL_MISC, 0, 0, }, { "empower", 0, 0, 1000, 5000, SPELL_MISC, 0, 0, }, { "enchant_weapon", 0, 0, 1500, 5000, SPELL_MISC, 0, 0, }, { "enchant_armor", 0, 0, 1500, 5000, SPELL_MISC, 0, 0, }, { "faerie_fog", 0, 0, 1000, 5000, SPELL_MISC, 0, 0, }, { "fireproof", 0, 0, 1000, 5000, SPELL_MISC, 0, 0, }, { "floating_disc", 0, 0, 500, 5000, SPELL_MISC, 0, 0, }, { "identify", 0, 0, 1000, 5000, SPELL_MISC, 45, 0, }, { "know_alignment", 0, 0, 0, 5000, SPELL_MISC, 0, 0, }, { "recharge", 0, 0, 500, 5000, SPELL_MISC, 0, 0, }, { "resurrect", 0, 0, 1000, 5000, SPELL_MISC, 0, 0, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Affected by/shielded by flags */ XCOST_DATA bitaf_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "detect_evil", AFF_DETECT_EVIL, XUPGD_OBJ, 200, 4000, BIT_AFFECT, 0, 0, }, { "detect_magic", AFF_DETECT_MAGIC, XUPGD_MOB | XUPGD_OBJ, 200, 4000, BIT_AFFECT, 0, 0, }, { "detect_motion", AFF_DETECT_MOTION, XUPGD_MOB | XUPGD_OBJ, 700, 8000, BIT_AFFECT, 0, 0, }, { "detect_good", AFF_DETECT_GOOD, XUPGD_OBJ, 200, 4000, BIT_AFFECT, 0, 0, }, { "infrared", AFF_INFRARED, XUPGD_MOB | XUPGD_OBJ, 200, 4000, BIT_AFFECT, 0, 0, }, { "farsight", AFF_FARSIGHT, XUPGD_OBJ, 700, 8000, BIT_AFFECT, 0, 0, }, { "sneak", AFF_SNEAK, XUPGD_MOB | XUPGD_OBJ, 2000, 16000, BIT_AFFECT, 0, 0, }, { "flying", AFF_FLYING, XUPGD_MOB | XUPGD_OBJ, 1300, 12000, BIT_AFFECT, 0, 0, }, { "pass_door", AFF_PASS_DOOR, XUPGD_MOB | XUPGD_OBJ, 1300, 12000, BIT_AFFECT, 0, 0, }, { "haste", AFF_HASTE, XUPGD_MOB, 1300, 12000, BIT_AFFECT, 0, 0, }, { "dark_vision", AFF_DARK_VISION, XUPGD_MOB | XUPGD_OBJ, 200, 4000, BIT_AFFECT, 0, 0, }, { "berserk", AFF_BERSERK, XUPGD_MOB, 1300, 12000, BIT_AFFECT, 0, 0, }, { "swim", AFF_SWIM, XUPGD_MOB | XUPGD_OBJ, 700, 8000, BIT_AFFECT, 0, 0, }, { "regeneration", AFF_REGENERATION, XUPGD_MOB, 700, 8000, BIT_AFFECT, 0, 0, }, { "invisible", SHD_INVISIBLE, XUPGD_MOB | XUPGD_OBJ, 700, 8000, BIT_SHIELD, 0, 0, }, { "iceshield", SHD_ICE, XUPGD_MOB, 1300, 12000, BIT_SHIELD, 0, 0, }, { "fireshield", SHD_FIRE, XUPGD_MOB, 1300, 12000, BIT_SHIELD, 0, 0, }, { "shockshield", SHD_SHOCK, XUPGD_MOB, 1300, 12000, BIT_SHIELD, 0, 0, }, { "sanctuary", SHD_SANCTUARY, XUPGD_MOB, 2800, 20000, BIT_SHIELD, 0, 0, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Weapon flags: req1=smith, req2=mage */ XCOST_DATA wpnflag_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "flaming", WEAPON_FLAMING, 0, 500, 7500, 0, 0, 80, }, { "frost", WEAPON_FROST, 0, 500, 7500, 0, 0, 80, }, { "vampiric", WEAPON_VAMPIRIC, 0, 500, 7500, 0, 0, 60, }, { "sharp", WEAPON_SHARP, 0, 1200, 7500, 0, 60, 0, }, { "vorpal", WEAPON_VORPAL, 0, 2000, 7500, 0, 60, 40, }, { "two-handed", WEAPON_TWO_HANDS, 0, 0, 7500, 0, 80, 0, }, { "shocking", WEAPON_SHOCKING, 0, 500, 7500, 0, 0, 80, }, { "poisoned", WEAPON_POISON, 0, 500, 7500, 0, 35, 40, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Object flags: req1=smith, req2=mage */ XCOST_DATA objflag_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "glowing", ITEM_GLOW, 0, 200, 2500, 0, 50, 100, }, { "humming", ITEM_HUM, 0, 800, 2500, 0, 0, 40, }, { "dark", ITEM_DARK, 0, 200, 2500, 0, 0, 40, }, { "evil", ITEM_EVIL, 0, 200, 2500, 0, 0, 40, }, { "invis", ITEM_INVIS, 0, 600, 2500, 0, 0, 60, }, { "magic", ITEM_MAGIC, 0, 200, 2500, 0, 0, 40, }, { "nodrop", ITEM_NODROP, 0, 600, 2500, 0, 0, 45, }, { "bless", ITEM_BLESS, 0, 400, 2500, 0, 0, 0, }, { "anti_good", ITEM_ANTI_GOOD, 0, 200, 2500, 0, 0, 50, }, { "anti_evil", ITEM_ANTI_EVIL, 0, 200, 2500, 0, 0, 50, }, { "anti_neutral", ITEM_ANTI_NEUTRAL, 0, 200, 2500, 0, 0, 50, }, { "noremove", ITEM_NOREMOVE, 0, 400, 2500, 0, 0, 75, }, { "nopurge", ITEM_NOPURGE, 0, 400, 2500, 0, 0, 60, }, { "nosac", ITEM_NOSAC, 0, 400, 2500, 0, 0, 45, }, { "nonmetal", ITEM_NONMETAL, 0, 800, 2500, 0, 100, 40, }, { "nolocate", ITEM_NOLOCATE, 0, 1200, 2500, 0, 75, 60, }, { "meltdrop", ITEM_MELT_DROP, 0, 600, 2500, 0, 0, 60, }, { "sellextract", ITEM_SELL_EXTRACT, 0, 400, 2500, 0, 80, 40, }, { "burnproof", ITEM_BURN_PROOF, 0, 800, 2500, 0, 50, 100, }, { "nouncurse", ITEM_NOUNCURSE, 0, 600, 2500, 0, 0, 50, }, { "rotdeath", ITEM_ROT_DEATH, 0, 400, 2500, 0, 0, 60, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Damage types for mobs - bits loaded in by looking up attack table on boot: req1=trainer req2=mage for obj */ XCOST_DATA damtype_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "slice", 0, 0, 0, 10000, 0, 0, 0, }, { "stab", 0, 0, 0, 10000, 0, 0, 0, }, { "whip", 0, 0, 0, 10000, 0, 0, 0, }, { "claw", 0, 0, 0, 10000, 0, 0, 0, }, { "blast", 0, 0, 2000, 5000, 0, 0, 75, }, { "pound", 0, 0, 0, 10000, 0, 0, 0, }, { "crush", 0, 0, 0, 10000, 0, 0, 0, }, { "grep", 0, 0, 0, 10000, 0, 0, 0, }, { "bite", 0, 0, 0, 10000, 0, 0, 0, }, { "pierce", 0, 0, 0, 10000, 0, 0, 0, }, { "suction", 0, 0, 2000, 5000, 0, 0, 0, }, { "beating", 0, 0, 0, 10000, 0, 0, 0, }, { "digestion", 0, 0, 2000, 5000, 0, 50, 0, }, { "charge", 0, 0, 2000, 5000, 0, 0, 0, }, { "slap", 0, 0, 0, 10000, 0, 0, 0, }, { "punch", 0, 0, 0, 10000, 0, 0, 0, }, { "wrath", 0, 0, 4000, 2500, 0, 60, 100, }, { "magic", 0, 0, 4000, 2500, 0, 60, 100, }, { "divine", 0, 0, 4000, 2500, 0, 60, 100, }, { "cleave", 0, 0, 0, 10000, 0, 0, 0, }, { "scratch", 0, 0, 0, 10000, 0, 0, 0, }, { "peck", 0, 0, 0, 10000, 0, 0, 0, }, { "peckb", 0, 0, 0, 10000, 0, 0, 0, }, { "chop", 0, 0, 0, 10000, 0, 0, 0, }, { "sting", 0, 0, 0, 10000, 0, 0, 0, }, { "smash", 0, 0, 0, 10000, 0, 0, 0, }, { "shbite", 0, 0, 2000, 5000, 0, 50, 75, }, { "flbite", 0, 0, 2000, 5000, 0, 40, 75, }, { "frbite", 0, 0, 2000, 5000, 0, 70, 75, }, { "acbite", 0, 0, 2000, 5000, 0, 50, 75, }, { "chomp", 0, 0, 0, 10000, 0, 0, 0, }, { "drain", 0, 0, 4000, 2500, 0, 50, 80, }, { "thrust", 0, 0, 0, 10000, 0, 0, 0, }, { "slime", 0, 0, 2000, 5000, 0, 50, 0, }, { "shock", 0, 0, 2000, 5000, 0, 50, 0, }, { "thwack", 0, 0, 0, 10000, 0, 0, 0, }, { "wave", 0, 0, 2000, 5000, 0, 60, 50, }, { "flame", 0, 0, 2000, 5000, 0, 40, 0, }, { "chill", 0, 0, 2000, 5000, 0, 70, 0, }, { "typo", 0, 0, 0, 0, 0, 0, 0, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Mobile resistances: req1=trainer, req2=mage */ XCOST_DATA res_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "summon", RES_SUMMON, 0, 1000, 5000, 0, 0, 40, }, { "charm", RES_CHARM, 0, 1000, 5000, 0, 0, 40, }, { "magic", RES_MAGIC, 0, 3000, 15000, 0, 0, 60, }, { "weapon", RES_WEAPON, 0, 3000, 15000, 0, 60, 0, }, { "bash", RES_BASH, 0, 2500, 12500, 0, 50, 0, }, { "pierce", RES_PIERCE, 0, 2500, 12500, 0, 50, 0, }, { "slash", RES_SLASH, 0, 2500, 12500, 0, 50, 0, }, { "fire", RES_FIRE, 0, 2000, 10000, 0, 40, 50, }, { "cold", RES_COLD, 0, 2000, 10000, 0, 40, 50, }, { "lightning", RES_LIGHTNING, 0, 2000, 10000, 0, 40, 50, }, { "acid", RES_ACID, 0, 2000, 10000, 0, 35, 50, }, { "poison", RES_POISON, 0, 1000, 5000, 0, 0, 45, }, { "negative", RES_NEGATIVE, 0, 2000, 10000, 0, 0, 40, }, { "holy", RES_HOLY, 0, 2000, 10000, 0, 0, 40, }, { "energy", RES_ENERGY, 0, 2000, 10000, 0, 0, 40, }, { "mental", RES_MENTAL, 0, 2000, 10000, 0, 0, 70, }, { "disease", RES_DISEASE, 0, 1000, 5000, 0, 0, 40, }, { "drowning", RES_DROWNING, 0, 2000, 10000, 0, 0, 0, }, { "light", RES_LIGHT, 0, 2000, 10000, 0, 0, 0, }, { "sound", RES_SOUND, 0, 2000, 10000, 0, 0, 0, }, { "wood", RES_WOOD, 0, 2000, 10000, 0, 0, 0, }, { "silver", RES_SILVER, 0, 2000, 10000, 0, 0, 0, }, { "iron", RES_IRON, 0, 2000, 10000, 0, 0, 0, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Mobile immunities: req1=trainer, req2=mage */ XCOST_DATA imm_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "summon", IMM_SUMMON, 0, 2000, 10000, 0, 0, 60, }, { "charm", IMM_CHARM, 0, 2000, 10000, 0, 0, 60, }, { "bash", IMM_BASH, XUPGD_IMM_SPECIAL, 6000, 30000, 0, 100, 0, }, { "pierce", IMM_PIERCE, XUPGD_IMM_SPECIAL, 6000, 30000, 0, 100, 0, }, { "slash", IMM_SLASH, XUPGD_IMM_SPECIAL, 6000, 20000, 0, 100, 0, }, { "fire", IMM_FIRE, 0, 4000, 20000, 0, 70, 100, }, { "cold", IMM_COLD, 0, 4000, 20000, 0, 70, 100, }, { "lightning", IMM_LIGHTNING, 0, 4000, 20000, 0, 70, 100, }, { "acid", IMM_ACID, 0, 4000, 20000, 0, 35, 50, }, { "poison", IMM_POISON, 0, 2000, 10000, 0, 0, 90, }, { "negative", IMM_NEGATIVE, 0, 4000, 20000, 0, 0, 80, }, { "holy", IMM_HOLY, 0, 4000, 20000, 0, 0, 80, }, { "energy", IMM_ENERGY, 0, 4000, 20000, 0, 0, 80, }, { "mental", IMM_MENTAL, 0, 4000, 20000, 0, 0, 120, }, { "disease", IMM_DISEASE, 0, 2000, 10000, 0, 0, 80, }, { "drowning", IMM_DROWNING, 0, 4000, 20000, 0, 0, 80, }, { "light", IMM_LIGHT, 0, 4000, 20000, 0, 0, 40, }, { "sound", IMM_SOUND, 0, 4000, 20000, 0, 0, 40, }, { "wood", IMM_WOOD, 0, 4000, 20000, 0, 0, 40, }, { "silver", IMM_SILVER, 0, 4000, 20000, 0, 0, 40, }, { "iron", IMM_IRON, 0, 4000, 20000, 0, 0, 40, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /* Offensive bits for mobiles: req1=trainer, req2=mage */ XCOST_DATA off_prices[] = { /* { NAME, BIT, FLAGS, AQP, PLAT, TYPE, REQ1, REQ2 } */ { "area attack", OFF_AREA_ATTACK, 0, 1000, 15000, 0, 75, 0, }, { "backstab", OFF_BACKSTAB, 0, 500, 10000, 0, 50, 0, }, { "bash", OFF_BASH, 0, 500, 10000, 0, 35, 0, }, { "berserk", OFF_BERSERK, 0, 0, 5000, 0, 35, 0, }, { "disarm", OFF_DISARM, 0, 0, 5000, 0, 45, 0, }, { "dodge", OFF_DODGE, 0, 0, 5000, 0, 0, 0, }, { "fade", OFF_FADE, 0, 500, 10000, 0, 45, 60, }, { "fast", OFF_FAST, 0, 500, 10000, 0, 50, 0, }, { "kick", OFF_KICK, 0, 0, 5000, 0, 60, 0, }, { "kick_dirt", OFF_KICK_DIRT, 0, 500, 10000, 0, 35, 0, }, { "parry", OFF_PARRY, 0, 0, 5000, 0, 0, 0, }, { "rescue", OFF_RESCUE, 0, 0, 5000, 0, 0, 0, }, { "trip", OFF_TRIP, 0, 500, 10000, 0, 0, 0, }, { "assist_all", ASSIST_ALL, 0, 0, 5000, 0, 0, 0, }, { "assist_align", ASSIST_ALIGN, 0, 0, 5000, 0, 0, 0, }, { "assist_race", ASSIST_RACE, 0, 0, 5000, 0, 0, 0, }, { "assist_players", ASSIST_PLAYERS, 0, 0, 5000, 0, 0, 0, }, { "assist_guard", ASSIST_GUARD, 0, 0, 5000, 0, 0, 0, }, { "assist_vnum", ASSIST_VNUM, 0, 0, 5000, 0, 0, 0, }, { "", 0, 0, 0, 0, 0, 0, 0, } }; /********************************* MEMORY MANAGEMENT **********************************/ /* Make a new piece of PKILL_DATA */ PKILL_DATA * new_pkill_data(void) { PKILL_DATA *pkilldata; // Allocate memory/use pre-freed if (pkill_data_free) { pkilldata = pkill_data_free; // Make pkilldata point to first free PKILL_DATA pkill_data_free = pkill_data_free->next; // Make pkill_data_free point to next freed PKILL_DATA } else pkilldata = alloc_perm(sizeof(*pkilldata)); // No free PKILL_DATA, allocate a perm // Initialise values pkilldata->kPoints = 0; pkilldata->kills = 0; pkilldata->deaths = 0; pkilldata->wins = 0; pkilldata->losses = 0; // Validate to mark it as initialised VALIDATE( pkilldata ); // All set to go! return pkilldata; } /* Free a chunk of PKILL_DATA */ void free_pkill_data(PKILL_DATA *pkilldata) { // Return if already freed if (IS_VALID( pkilldata )) return; // Mark as freed and whack onto the free list INVALIDATE( pkilldata ); pkilldata->next = pkill_data_free; // Make pkilldata->next point to first item on free list pkill_data_free = pkilldata; // Make the first item on free list point to pkilldata } /* Make a new piece of CLAN_DATA */ CLAN_DATA * new_clan_data(bool get_id) { CLAN_DATA *clan; int i; // Allocate memory/use pre-freed if (clan_free) { clan = clan_free; // Make clan point to first free CLAN_DATA clan_free = clan_free->next; // Make clan_free point to next freed CLAN_DATA } else clan = alloc_perm(sizeof(*clan)); // No free CLAN_DATA, allocate a perm // Initialise values clan->next = NULL; clan->enemy = NULL; clan->Penemy.data = NULL; clan->pkilldata = new_pkill_data(); clan->upgrade = NULL; clan->xupgrade = NULL; clan->u_rost = NULL; for (i = 0; i < CMOB_MAX; i++) clan->cMob[i] = NULL; for (i = 0; i < CROOM_MAX; i++) clan->cRoom[i] = NULL; for (i = 0; i < 2; i++) clan->skills[i] = -1; clan->name = str_dup("newclan"); clan->c_name = str_dup("New Clan"); for (i = 0; i < TOTAL_CLAN_RANK; i++) { clan->r_name[i] = str_dup(clan_rank_table[i].name); clan->r_who[i] = str_dup(clan_rank_table[i].who_name); } clan->description = str_dup(""); clan->platinum = 0; clan->qps = 0; clan->exit_changed = 0; clan->edit_time = 0; clan->u_quantity = 0; if (get_id) clan->id = generate_clan_id(); // Get identifier for clan else clan->id = 0; clan->members = 0; clan->vnum[0] = 0; clan->vnum[1] = 0; clan->entrance_vnum = 0; clan->pkill = FALSE; // Validate to mark it as initialised VALIDATE( clan ); // Add it to clan list and up max_clan number clan->next = clan_list; // Make clan->next point to first item on the clan list clan_list = clan; // Make clan the first item on the clan list ++max_clan; // All set to go! return clan; } /* Free a chunk of CLAN_DATA */ void free_clan_data(CLAN_DATA *clan) { int i; // Return if already freed if (IS_VALID( clan )) return; // Free strings first free_string(clan->name); free_string(clan->c_name); for (i = 0; i < TOTAL_CLAN_RANK; i++) { free_string(clan->r_name[i]); free_string(clan->r_who[i]); } free_string(clan->description); // If clan pkilldata hasn't been freed yet, free it if (clan->pkilldata) free_pkill_data(clan->pkilldata); // Mark as free and put on the clan_free list INVALIDATE( clan ); clan->next = clan_free; // Make clan->next point to first item on the clan_free list clan_free = clan; // Make clan the first item on the clan_free list --max_clan; } /* Make a new piece of ROSTER_DATA */ ROSTER_DATA * new_roster_data(bool get_id) { ROSTER_DATA *roster; // Allocate memory if (roster_free) { roster = roster_free; // Make roster point to first free ROSTER_DATA roster_free = roster_free->next; // Make roster_free point to next freed ROSTER_DATA } else roster = alloc_perm(sizeof(*roster)); // No free ROSTER_DATA, allocate a perm // Initialise values roster->next = NULL; roster->character = NULL; roster->clan = get_clan_by_id(CLAN_NONE); roster->petition = NULL; roster->pkilldata = NULL; roster->name = str_dup(""); roster->last_login = 0; roster->penalty_time = 0; roster->dPoints = 0; roster->flags = 0; roster->bounty = 0; if (get_id) roster->id = generate_roster_id(); else roster->id = 0; roster->trust = TRUST_ALL; // Validate to mark it as initialised and add to roster list VALIDATE( roster ); roster->next = roster_list; // Make roster->next point to the first item on the roster list roster_list = roster; // Make roster the first item on the roster list // All set to go! return roster; } /* Free a chunk of ROSTER_DATA */ void free_roster_data(ROSTER_DATA *roster) { // Return if already freed if (IS_VALID( roster )) return; // Free strings first free_string(roster->name); // Free pkilldata if not already done if (roster->pkilldata) free_pkill_data(roster->pkilldata); // Mark as free and add to roster list INVALIDATE( roster ); roster->next = roster_free; // Make roster->next point to the first item on the roster_free list roster_free = roster; // Make roster the first item on the roster_free list } /********************************** HELPER FUNCTIONS **********************************/ /* Lookup a vnum on the vnum_type tables */ char * vnum_lookup(const struct vnum_table *table, int vnum) { static char buf[MAX_STRING_LENGTH]; for (; table->name[0] != '\0'; table++) if (table->vnum == vnum) break; if (table->vnum < 0) strcpy(buf, "-"); else strcpy(buf, capitalize(table->name)); return buf; } /* Generate a unique clan id */ int generate_clan_id(void) { CLAN_DATA *clan; int id, i, j; bool found; for (i = 0; i < 50; i++) // Prevent infinite loops { id = current_time * 2; if (id < 0) id *= -1; for (j = 0; j <= i && id > 500; j++) id -= number_range(100, 300); if (id < 0) id *= -1; if (id < 500) id += number_range(500, 3000); // Check if any clan has this id for (found = FALSE, clan = clan_list, i = 0; clan != NULL; clan = clan->next, i++) { if (clan->id == id) found = TRUE; } if (!found) return id; } printf_debug("generate_clan_id: unable to retrieve unique id."); return -1; } long get_total_points(ROSTER_DATA *roster) { if (roster == NULL) return -1; return roster->pkilldata->kPoints * 2 + roster->dPoints; } /* Get the index of the players rank on the rank table */ int get_r_rank_index(ROSTER_DATA *roster) { if (roster == NULL) return -1; return get_p_rank_index(get_total_points(roster)); } /* Find the rank if given points */ int get_p_rank_index(long points) { int i; for (i = (TOTAL_CLAN_RANK - 1); i > 0; i--) if (points >= clan_rank_table[i].points) break; return i; } void clanskill_check(CHAR_DATA *ch) { ROSTER_DATA *roster; if (IS_NPC(ch)) return; GET_ROSTER(ch, roster); int i; for (i = 0; clan_skill_table[i].cmd[0] != '\0'; i++) { if (clan_skill_table[i].gsn) { if ((roster == NULL || !clan_has_skill(roster->clan, i)) && is_affected(ch, *(clan_skill_table[i].gsn))) affect_strip(ch, *(clan_skill_table[i].gsn)); } else if (!str_cmp(clan_skill_table[i].cmd, "modi")) { if (roster == NULL || !clan_has_skill(roster->clan, i)) { if (is_affected(ch, gsn_concentration)) affect_strip(ch, gsn_concentration); if (is_affected(ch, gsn_modis_anger)) affect_strip(ch, gsn_modis_anger); } } } } bool clan_has_skill(CLAN_DATA *clan, int skill) { int i; if (clan == NULL) return FALSE; for (i = 0; i < 2; i++) if (clan->skills[i] == skill) return TRUE; return FALSE; } /* Get clan data by looking up id - faster than by name */ CLAN_DATA * get_clan_by_id(int id) { CLAN_DATA *clan; for (clan = clan_list; clan != NULL; clan = clan->next) if (clan->id == id) return clan; return NULL; } /* Get clan data by looking up name */ CLAN_DATA * get_clan_by_name(char *name) { CLAN_DATA *clan; if (name[0] == '\0') return NULL; for (clan = clan_list; clan != NULL; clan = clan->next) { if (UPPER( name[0] ) != UPPER( clan->name[0] )) // Compare first letter first continue; else if (!str_cmp(clan->name, name)) return clan; } return NULL; } CLAN_DATA * clan_lookup(char *name) { return get_clan_by_name(name); } /* Get clan data by looking up vnums */ CLAN_DATA * get_clan_by_vnum(int vnum) { CLAN_DATA *clan; for (clan = clan_list; clan != NULL; clan = clan->next) { if (clan->vnum[0] == clan->vnum[1]) continue; if (vnum >= clan->vnum[0] && vnum <= clan->vnum[1]) return clan; } return NULL; } /* Get a player's clan */ CLAN_DATA * get_clan_by_ch(CHAR_DATA *ch) { ROSTER_DATA *roster; if (ch->pIndexData) return get_clan_by_vnum(ch->pIndexData->vnum); GET_ROSTER( ch, roster ); if (roster == NULL || roster->clan == NULL) return get_clan_by_id(CLAN_NONE); return roster->clan; } /* Get a clan deathroom if clanned and there is one or put them in the temple */ ROOM_INDEX_DATA * get_clan_deathroom(CHAR_DATA *ch) { ROOM_INDEX_DATA *pRoom; ROSTER_DATA *roster; GET_ROSTER( ch, roster ); if (roster == NULL || roster->clan->independent || roster->clan->cRoom[CROOM_RECALL] == NULL) // pRoom = get_room_index(ROOM_VNUM_TEMPLE); pRoom = get_room_index(2909); else pRoom = roster->clan->cRoom[CROOM_RECALL]; if (pRoom == NULL) // If no temple, fall back to the market square { printf_debug("ROOM_VNUM_TEMPLE (%d) == NULL", ROOM_VNUM_TEMPLE ); pRoom = get_room_index(VNUM_MARKET_SQUARE); } return pRoom; } /* Generate a unique roster id */ int generate_roster_id(void) { ROSTER_DATA *roster; int id, i, j; bool found; for (i = 0; i < 1000; i++) // Prevent infinite loops { id = current_time * number_range(1, 5); if (id < 0) id *= -1; for (j = 0; j <= i && id > 500; j++) id -= number_range(100, 300); if (id < 0) id *= -1; if (id < 500) id += number_range(500, 3000); // Check if any roster has this id for (found = FALSE, roster = roster_list, i = 0; roster != NULL; roster = roster->next, i++) if (roster->id == id) found = TRUE; if (!found) return id; } printf_debug("generate_roster_id: unable to retrieve unique id."); return -1; } /* Get roster data by char data - faster */ ROSTER_DATA * get_roster_by_id(int id) { ROSTER_DATA *roster; for (roster = roster_list; roster != NULL; roster = roster->next) if (id == roster->id) return roster; return NULL; } /* Get roster data by player name */ ROSTER_DATA * get_roster_by_name(char *name, bool prefix) { ROSTER_DATA *roster; if (name[0] == '\0') return NULL; for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; else if (UPPER( name[0] ) != UPPER( roster->name[0] )) // Compare first letter first continue; else if ((prefix && !str_prefix(name, roster->name)) || !str_cmp(name, roster->name)) return roster; } return NULL; } /* Update roster for specific character */ void update_roster(CHAR_DATA *ch, bool quit) { ROSTER_DATA *roster; if (ch == NULL || IS_NPC(ch) || ch->pcdata == NULL) return; roster = ch->pcdata->roster; if (quit) { if (!roster && (roster = get_roster_by_name(ch->name, FALSE )) == NULL) // Check pcdata first, if unable to find, check by character name { printf_debug( "update_roster: unable to find roster data for quitting character %s", ch->name); return; } roster->last_login = current_time; roster->character = NULL; if (IS_IMMORTAL( ch ) && !IS_SET( roster->flags, ROST_IMMORTAL )) SET_BIT( roster->flags, ROST_IMMORTAL ); else if (!IS_IMMORTAL( ch ) && IS_SET( roster->flags, ROST_IMMORTAL )) REMOVE_BIT( roster->flags, ROST_IMMORTAL ); SET_ROSTER( ch, NULL ); } else { if (!roster && (roster = get_roster_by_name(ch->name, FALSE )) == NULL) // New characters { roster = new_roster_data(TRUE); roster->character = ch; roster->clan = get_clan_by_id(CLAN_NONE); roster->pkilldata = new_pkill_data(); free_string(roster->name); roster->name = str_dup(ch->name); roster->last_login = current_time; SET_ROSTER( ch, roster ); save_all_rosters(); return; } REMOVE_BIT( roster->flags, ROST_INACTIVE ); REMOVE_BIT( roster->flags, ROST_AWAY ); roster->last_login = current_time; roster->character = ch; if (IS_IMMORTAL( ch ) && !IS_SET( roster->flags, ROST_IMMORTAL )) SET_BIT( roster->flags, ROST_IMMORTAL ); else if (!IS_IMMORTAL( ch ) && IS_SET( roster->flags, ROST_IMMORTAL )) REMOVE_BIT( roster->flags, ROST_IMMORTAL ); SET_ROSTER( ch, roster ); clanskill_check(ch); } save_roster_data(roster); } /* Update rosters, flags, killed by stuff */ void update_all_rosters(void) { char buf[MAX_STRING_LENGTH]; ROSTER_DATA *roster; bool penalty = FALSE; FILE *fp; if (roster_next_update <= 0 || roster_next_update <= current_time) roster_next_update = current_time + TIME_ROSTER_UPD_TICK; else return; if (roster_next_penalty <= 0) roster_next_penalty = current_time + TIME_ROSTER_PEN_TICK; else if (roster_next_penalty <= current_time) { penalty = TRUE; roster_next_penalty = current_time + TIME_ROSTER_PEN_TICK; } for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; sprintf(buf, "%s%s%s%s", PLAYER_DIR, initial(roster->name), "/", capitalize(roster->name)); fp = NULL; if (roster->character) roster->last_login = current_time; // Check if character exists. else if ((fp = fopen(buf, "r")) == NULL) { mark_delete_roster(roster); continue; } else if (!roster->clan->independent) { if (!IS_SET( roster->flags, ROST_AWAY ) || !IS_SET( roster->flags, ROST_EXILE_GRACE )) { if ((current_time - roster->last_login) > TIME_WEEK && roster->trust == TRUST_LDR) SET_BIT( roster->flags, ROST_INACTIVE ); else if ((current_time - roster->last_login) > (2 * TIME_WEEK)) SET_BIT( roster->flags, ROST_INACTIVE ); } } if (fp != NULL) fclose(fp); if (IS_SET( roster->flags, ROST_EXILE_GRACE ) && current_time >= roster->penalty_time) exile_player(roster); else if (penalty && roster->dPoints > 0 && IS_SET( roster->flags, ROST_EXILE_GRACE )) roster->dPoints -= 10; if (IS_SET( roster->flags, ROST_NEWBIE ) && (roster->pkilldata->kPoints >= 10 || (roster->character && roster->character->played > 360000))) { REMOVE_BIT( roster->flags, ROST_NEWBIE ); if (roster->character) send_to_char( "{RYour newbie flag has expired. You are now a FULL player-killer.\n\r", roster->character); } } save_all_rosters(); } /* Mark roster for deletion */ void mark_delete_roster(ROSTER_DATA *roster) { if (IS_SET( roster->flags, ROST_DELETED )) return; SET_BIT( roster->flags, ROST_DELETED ); roster->penalty_time = current_time + TIME_ROSTER_DELETE; } /* Clan transaction logging */ void append_clan_log(CLAN_DATA *clan, int type, char *name, char *string) { FILE *fp; char file[100]; sprintf(file, "%s%d.log", is_main_server() ? CLAN_HISTORY_FOLDER : TEST_CLAN_HISTORY_FOLDER, clan->id); smash_tilde(string); if ((fp = fopen(file, "a")) == NULL) { printf_system( "append_clan_log: unable to open %s clan log for appending.", clan->name); return; } fprintf(fp, ">%d %ld %s %s\n", type, current_time, name, string); fclose(fp); if (type == ENTRY_DELETE) { char fileB[100]; sprintf(fileB, "%s%d.del", is_main_server() ? CLAN_HISTORY_FOLDER : TEST_CLAN_HISTORY_FOLDER, clan->id); rename(file, fileB); } } /* Display clan log */ void parse_clan_log(CHAR_DATA *ch, CLAN_DATA *clan, void *filter, int ftype) { BUFFER *output; FILE *fp; char buf[MAX_STRING_LENGTH], file[100]; bool found = FALSE; sprintf(file, "%s%d.log", is_main_server() ? CLAN_HISTORY_FOLDER : TEST_CLAN_HISTORY_FOLDER, clan->id); if ((fp = fopen(file, "r")) == NULL) { perror(file); sprintf(buf, "Unable to open %s clan log file", clan->name); send_to_char(buf, ch); return; } output = new_buf(); while (!feof(fp)) { char c, *name, *string; int type; time_t time; while (!feof(fp) && (c = fread_letter(fp)) != '>') ; if (feof(fp)) break; type = fread_number(fp); time = fread_number(fp); name = fread_word(fp); string = fread_string_eol(fp); if (time < (current_time - (2 * TIME_WEEK)) || (type == ENTRY_GUILD && !IS_IMMORTAL( ch ))) goto LoopEnd; switch (ftype) // If the entry doesn't pass the filter check, then we'll skip { // past the displaying bit straight to freeing string case FILTER_NAME: if (str_cmp(((char *) filter), name)) goto LoopEnd; break; case FILTER_TYPE: if (type != (*(long *) filter)) goto LoopEnd; break; case FILTER_TIME: if (time < (*(long *) filter)) goto LoopEnd; break; case FILTER_KEYWORD: if (str_infix(((char *) filter), string)) goto LoopEnd; break; default: break; } found = TRUE; sprintf(buf, "{B[{w%.24s{B:%s{B] {W%s: {w%s{x\n\r", ctime(&time), log_entry_string[type].display, name, string); add_buf(output, buf); LoopEnd: free_string(string); } fclose(fp); if (found) page_to_char(output->string, ch); else send_to_char("There is no clan log file.\n\r", ch); free_buf(output); } /* Strip all spaces */ char * strip_spaces(char *str) { static char buf[MAX_STRING_LENGTH]; int i; for (i = 0; *str; str++) { if (*str == ' ') continue; else { buf[i] = *str; i++; } } buf[i] = '\0'; return buf; } /* Strip spaces at the end and beginning only */ char * strip_bespaces(char *str) { static char buf[MAX_STRING_LENGTH], temp[3]; int i; buf[0] = '\0'; for (;; str++) { if (*str == '{' && *(++str) != '{') { temp[0] = *(str - 1); temp[1] = *str; temp[2] = '\0'; strcat(buf, temp); } else if (!isspace( *str )) break; } strcat(buf, str); for (i = (strlen(buf) - 1); i > 0; i--) { if (buf[i - 1] == '{' && buf[i] != '{') { i--; continue; } if (!isspace( buf[i] )) break; } buf[i + 1] = '\0'; return buf; } /* Strip all colour codes and special characters */ char * strip_spec_char_col(char *str) { static char buf[MAX_STRING_LENGTH]; int i; for (i = 0; *str; str++) { if (*str == '{') { if (*(++str) == '\0') break; } else if ((*str >= 'a' && *str <= 'z') || (*str >= 'A' && *str <= 'Z') || *str == ' ') { buf[i] = LOWER(*str); i++; } } buf[i] = '\0'; return buf; } /* Process a short description and turn it into a valid keyword name */ char * process_name(char *str) { static char buf[MAX_STRING_LENGTH]; char temp[MAX_STRING_LENGTH]; char *retval; int i; sprintf(buf, " %s ", strip_spec_char_col(str)); for (i = 0; process_name_word[i][0] != '\0'; i++) { strcpy(temp, process_name_word[i]); str_replace(buf, temp, " "); } for (i = 0; buf[i] != '\0'; i++) buf[i] = LOWER( buf[i] ); retval = buf; while (*retval != '\0' && *retval == ' ') retval++; return retval; } /* Return a two-letter penalty code - hierarchical arrangement */ char * get_pen_code(ROSTER_DATA *roster) { static char pCode[3]; if (IS_SET( roster->flags, ROST_EXILE_GRACE )) strcpy(pCode, "EX"); else if (IS_SET( roster->flags, ROST_INACTIVE )) strcpy(pCode, "IN"); else strcpy(pCode, "--"); return pCode; } /* Get the area that holds all the clan vnums */ AREA_DATA * get_clan_area(void) { AREA_DATA *pArea; for (pArea = area_first; pArea != NULL; pArea = pArea->next) { if (pArea->min_vnum == VNUM_CLAN_LOWER && pArea->max_vnum == VNUM_CLAN_UPPER) return pArea; } printf_debug("get_clan_area: No clan area!\n\r"); return NULL; } /* Find a free mob vnum for a clan */ int get_clan_mvnum(CLAN_DATA *clan) { int i; for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) if (get_mob_index(i) == NULL) return i; return -1; } /* Find a free obj vnum for a clan */ int get_clan_ovnum(CLAN_DATA *clan) { int i; for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) if (get_obj_index(i) == NULL) return i; return -1; } /* Find a free room vnum for a clan */ int get_clan_rvnum(CLAN_DATA *clan) { int i; for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) if (get_room_index(i) == NULL) return i; return -1; } /* Assign a set of clan area vnums */ void assign_clan_vnums(CLAN_DATA *clan) { CLAN_DATA *checkClan; int vnum; bool found; for (vnum = VNUM_CLAN_LOWER; vnum < (VNUM_CLAN_UPPER - 1); vnum = (vnum + VNUM_CLAN_BLOCK)) { for (found = FALSE, checkClan = clan_list; checkClan != NULL; checkClan = checkClan->next) if (vnum >= checkClan->vnum[0] && vnum <= checkClan->vnum[1]) found = TRUE; if (!found) { clan->vnum[0] = vnum; clan->vnum[1] = vnum + (VNUM_CLAN_BLOCK - 1); return; } } printf_debug("assign_clan_vnums: no more free vnums for clan %d.\n\r", clan->id); return; } /* Get the number of clan eq items that can be worn */ int clan_eq_wear_max(CHAR_DATA *ch) { ROSTER_DATA *roster; GET_ROSTER( ch, roster ); if (roster == NULL) return 0; if (IS_IMMORTAL(ch)) return 10; if (roster->clan->independent || roster->trust < TRUST_MEMBER) return 0; return URANGE( 0, get_r_rank_index( roster ), 5 ); } PF_FILT_COND_DEF( clanhall_conditions ) { // No lockable doors. if (IS_SET(exit->rs_flags, EX_ISDOOR) && IS_SET(exit->rs_flags, EX_LOCKED)) return TRUE; ROOM_INDEX_DATA *room = exit->u1.to_room; // No non-basic sectors. if (room->sector_type == SECT_WATER_NOSWIM || room->sector_type == SECT_AIR) return TRUE; RESET_DATA *pReset; MOB_INDEX_DATA *pMob; // No aggies. for (pReset = room->reset_first; pReset != NULL; pReset = pReset->next) { if (pReset->command != 'M') continue; if ((pMob = get_mob_index(pReset->arg1)) == NULL) continue; if (IS_SET( pMob->act, ACT_AGGRESSIVE ) && pMob->level > 40) return TRUE; } return FALSE; } /* Check the directions from the market square to desired clan hall entrance */ bool check_path(ROOM_INDEX_DATA *end) { return bfs_pathfind( get_room_index(VNUM_MARKET_SQUARE), pf_end_at_room(end), &clanhall_conditions, PF_MAX_DEPTH, FALSE ) >= 0; } void reset_clan_mob(MOB_INDEX_DATA *pMob, bool delete) { ROOM_INDEX_DATA *pRoom; CHAR_DATA *mob, *mob_next, *master = NULL; if (pMob == NULL) return; CLAN_DATA *clan = get_clan_by_vnum(pMob->vnum); for (mob = char_list; mob != NULL; master = NULL, mob = mob_next) { mob_next = mob->next; if (!IS_NPC( mob )) continue; if (mob->pIndexData != pMob) continue; if ((pRoom = mob->in_room) == NULL) { extract_char(mob, TRUE ); continue; } // Only update the mob if they're currently in friendly territory. if (get_clan_by_vnum(pRoom->vnum) != clan) continue; if (mob->master && mob->master->pet == mob) { master = mob->master; mob->master->pet = NULL; mob->master = NULL; } extract_char(mob, TRUE ); if (delete) continue; if (master) { // Pets. mob = create_mobile(pMob); char_to_room(mob, pRoom); mob->master = master; master->pet = mob; } else // Everything else should reset in place. reset_room(pRoom); } } int wear_map[] = { ITEM_LIGHT, ITEM_WEAR_FINGER, ITEM_WEAR_FINGER, ITEM_WEAR_NECK, ITEM_WEAR_NECK, ITEM_WEAR_BODY, ITEM_WEAR_HEAD, ITEM_WEAR_LEGS, ITEM_WEAR_FEET, ITEM_WEAR_HANDS, ITEM_WEAR_ARMS, ITEM_WEAR_SHIELD, ITEM_WEAR_ABOUT, ITEM_WEAR_WAIST, ITEM_WEAR_WRIST, ITEM_WEAR_WRIST, ITEM_WIELD, ITEM_HOLD, ITEM_WEAR_FLOAT, ITEM_WIELD, ITEM_WEAR_FACE, ITEM_WEAR_EAR, ITEM_RESERVED, ITEM_WEAR_ANKLE, ITEM_WEAR_ANKLE, ITEM_WEAR_CLAN, ITEM_WEAR_RELIG, ITEM_WEAR_PATCH, ITEM_WEAR_BACK }; void reset_clan_obj(OBJ_INDEX_DATA *pObj, bool delete) { AUCTION_DATA *auc; CHAR_DATA *carrier = NULL; CLAN_DATA *clan; ROOM_INDEX_DATA *room = NULL; OBJ_DATA *obj, *obj_next, *container = NULL, *obj_content = NULL, *objCheck = NULL, *objCheck_next; char buf[MAX_STRING_LENGTH]; int loc = WEAR_NONE; if (pObj == NULL) return; clan = get_clan_by_vnum(pObj->vnum); for (obj = object_list; obj != NULL; loc = WEAR_NONE, room = NULL, carrier = NULL, container = NULL, obj_content = NULL, obj = obj_next) { obj_next = obj->next; if (obj->pIndexData != pObj) continue; for (auc = auction_list; auc != NULL; auc = auc->next) { if (auc->item != NULL && obj == auc->item) { if (auc->high_bidder != NULL) { add_cost(auc->high_bidder, auc->bid_amount, auc->bid_type); send_to_char("\n\rYour bid has been returned to you.\n\r", auc->high_bidder); } free_auction(auc); break; } } if (auc != NULL && auc->owner != NULL) carrier = auc->owner; if (obj->in_room != NULL) room = obj->in_room; else if (obj->carried_by != NULL) { carrier = obj->carried_by; if (obj->wear_loc < sizeof(wear_map)) loc = obj->wear_loc; } else if (obj->in_obj != NULL) container = obj->in_obj; else { extract_obj(obj); continue; } if ((obj_content = obj->contains) != NULL) { obj->contains = NULL; for (objCheck = obj_content; objCheck != NULL; objCheck = objCheck_next) { objCheck_next = objCheck->next_content; if (delete) { obj_from_obj(objCheck); if (room) obj_to_room(objCheck, room); else if (carrier) obj_to_char(objCheck, carrier); else if (container) obj_to_obj(objCheck, container); } else objCheck->in_obj = NULL; } } extract_obj(obj); if (delete) continue; obj = create_object(pObj, pObj->level); if (room) obj_to_room(obj, room); else if (carrier) { if (IS_NPC( carrier ) && clan->cMob[CMOB_SHOPKEEP] && clan->cMob[CMOB_SHOPKEEP] == carrier->pIndexData && (room = carrier->in_room) != NULL) { extract_char(carrier, TRUE ); reset_room(room); } else { obj_to_char(obj, carrier); if (loc == WEAR_NONE) ; else if (loc < sizeof(wear_map) && IS_SET(obj->wear_flags, wear_map[loc])) { equip_char(carrier, obj, loc); } else { sprintf(buf,"{R***NOTE*** A clan item({x%s{R) has changed and has been unequipped as it now occupies a different slot.{x\n\r", obj->short_descr); send_to_char(buf, carrier); } } } else if (container) obj_to_obj(obj, container); if (obj_content) { obj->contains = obj_content; for (objCheck = obj_content; objCheck != NULL; objCheck = objCheck->next_content) objCheck->in_obj = obj; } } } /*********************************** SAVING/LOADING ***********************************/ /* Order: clans --> rosters */ /* Load a clan */ void load_clan_data(FILE *fp) { CLAN_DATA *clan = NULL; bool foundHash = FALSE; while (!feof(fp)) // Loop through each (line) section and load in data { char letter; // Section reference letter char *check; int i, j; letter = fread_letter(fp); switch (letter) { case '#': clan = new_clan_data(FALSE); clan->id = fread_number(fp); clan->pkill = fread_number(fp); clan->independent = fread_number(fp); clan->edit_time = fread_number(fp); foundHash = TRUE; break; case '$': return; case 'A': clan->qps = fread_number(fp); break; case 'C': free_string(clan->c_name); clan->c_name = fread_string(fp); break; case 'D': free_string(clan->description); clan->description = fread_string(fp); break; case 'E': clan->enemy = get_clan_by_id(fread_number(fp)); if (clan->enemy) // Make sure the enemy of this clan's enemy is this clan (heh). clan->enemy->enemy = clan; // If two clans are warring against each other, this will work on the second clan. break; case 'F': clan->Penemy.id = fread_number(fp); break; case 'G': clan->exit_changed = fread_number(fp); break; case 'H': clan->entrance_vnum = fread_number(fp); break; case 'K': clan->pkilldata->kPoints = fread_number(fp); clan->pkilldata->kills = fread_number(fp); clan->pkilldata->deaths = fread_number(fp); clan->pkilldata->wins = fread_number(fp); clan->pkilldata->losses = fread_number(fp); break; case 'M': i = fread_number(fp); j = fread_number(fp); if (j > 0) clan->cMob[i] = get_mob_index(j); break; case 'N': free_string(clan->name); clan->name = str_dup(fread_word(fp)); break; case 'P': clan->platinum = fread_number(fp); break; case 'R': i = fread_number(fp); free_string(clan->r_name[i]); clan->r_name[i] = fread_string(fp); break; case 'S': check = fread_word(fp); for (i = 0; clan_skill_table[i].cmd[0] != '\0'; i++) { if (!str_cmp(clan_skill_table[i].cmd, check)) { if (clan->skills[0] >= 0) clan->skills[1] = i; else clan->skills[0] = i; break; } } if (clan_skill_table[i].cmd[0] == '\0') { printf_debug( "load_clan_data: clan skill %s not found", check); } break; case 'T': i = fread_number(fp); j = fread_number(fp); if (j > 0) clan->cRoom[i] = get_room_index(j); break; case 'W': i = fread_number(fp); free_string(clan->r_who[i]); clan->r_who[i] = str_dup(fread_word(fp)); break; case 'V': clan->vnum[0] = fread_number(fp); clan->vnum[1] = fread_number(fp); break; default: printf_debug("load_clan_data: read invalid section %c", letter); fread_string_eol(fp); break; } if (!foundHash) { printf_system("load_clan_data: # not found"); exit(1); } } } /* Load all clan data */ void load_all_clans(void) { FILE *fpList; if ((fpList = fopen( is_main_server() ? CLAN_DATA_LIST : TEST_CLAN_DATA_LIST, "r")) == NULL) { perror(is_main_server() ? CLAN_DATA_LIST : TEST_CLAN_DATA_LIST); exit(1); // Stop running if clan list isn't found } while (!feof(fpList)) { FILE *fp; char file[100], *word; word = fread_word(fpList); if (!str_cmp(word, "END")) // Check for end of file marker break; sprintf(file, "%s%s", is_main_server() ? CLAN_DATA_FOLDER : TEST_CLAN_DATA_FOLDER, word); if ((fp = fopen(file, "r")) == NULL) // Open clan file { perror(file); fclose(fpList); exit(1); // Stop running if clan file isn't found } load_clan_data(fp); fclose(fp); } fclose(fpList); } /* Save a clan */ void save_clan_data(CLAN_DATA *clan) { FILE *fp; char file[100]; int i; sprintf(file, "%s%d.dat", is_main_server() ? CLAN_DATA_FOLDER : TEST_CLAN_DATA_FOLDER, clan->id); if ((fp = fopen(file, "w")) == NULL) // Open clan file { printf_system( "save_clan_data: unable to open clan file %s for writing", file); return; // Return if clan file isn't writable } fprintf(fp, "# %d %d %d %ld\n", clan->id, clan->pkill, clan->independent, clan->edit_time); if (clan->enemy) fprintf(fp, "E %d\n", clan->enemy->id); else if (clan->Penemy.data) fprintf(fp, "F %d\n", clan->Penemy.data->id); fprintf(fp, "K %ld %d %d %d %d\n", clan->pkilldata->kPoints, clan->pkilldata->kills, clan->pkilldata->deaths, clan->pkilldata->wins, clan->pkilldata->losses); for (i = 0; i < CMOB_MAX; i++) if (clan->cMob[i] != NULL) fprintf(fp, "M %d %d\n", i, clan->cMob[i]->vnum); for (i = 0; i < CROOM_MAX; i++) if (clan->cRoom[i] != NULL) fprintf(fp, "T %d %d\n", i, clan->cRoom[i]->vnum); fprintf(fp, "N %s\n", clan->name); fprintf(fp, "C %s~\n", clan->c_name); for (i = 0; i < TOTAL_CLAN_RANK; i++) { fprintf(fp, "R %d %s~\n", i, clan->r_name[i]); fprintf(fp, "W %d %s\n", i, clan->r_who[i]); } fprintf(fp, "D %s~\n", clan->description); fprintf(fp, "P %ld\n", clan->platinum); fprintf(fp, "A %ld\n", clan->qps); fprintf(fp, "G %ld\n", clan->exit_changed); fprintf(fp, "V %d %d\n", clan->vnum[0], clan->vnum[1]); fprintf(fp, "H %d\n", clan->entrance_vnum); // Write clan skills for (i = 0; i < 2; i++) if (clan->skills[i] >= 0) fprintf(fp, "S %s\n", clan_skill_table[clan->skills[i]].cmd); fprintf(fp, "$\n"); // Write end of file marker fclose(fp); } /* Save all clan data */ void save_all_clans(void) { CLAN_DATA *clan; FILE *fpList; int maxID, capID; if ((fpList = fopen(TEMP_FILE, "w")) == NULL) // Use temp file so if anything goes wrong, the old clan list still exists { printf_system("save_all_clans: unable to open temp file for writing clan list"); return; } for (capID = -1;;) // More complicated saving technique to order the clan list { for (maxID = -1, clan = clan_list; clan != NULL; clan = clan->next) { if (capID >= 0 && clan->id >= capID) continue; if (clan->id > maxID) maxID = clan->id; } capID = maxID; clan = get_clan_by_id(maxID); fprintf(fpList, "%d.dat\n", // Write entry to clan list file clan->id); save_clan_data(clan); if (capID == 0) break; } fprintf(fpList, "END\n"); fclose(fpList); rename(TEMP_FILE, is_main_server() ? CLAN_DATA_LIST : TEST_CLAN_DATA_LIST ); } /* Load a roster and assign clan data */ void load_roster_data(FILE *fp) { ROSTER_DATA *roster = NULL; char letter; int value; bool foundHash = FALSE; while (!feof(fp)) { letter = fread_letter(fp); switch (letter) { case '#': roster = new_roster_data(FALSE); roster->id = fread_number(fp); foundHash = TRUE; break; case '$': return; case 'B': roster->bounty = fread_number(fp); break; case 'C': value = fread_number(fp); roster->clan = get_clan_by_id(value); if (roster->clan) (roster->clan->members)++; else { roster->clan = get_clan_by_id(CLAN_NONE); printf_debug( "load_roster_data: invalid clan id: %d for roster %s", value, roster->name ? roster->name : "no name"); (roster->clan->members)++; } break; case 'D': roster->dPoints = fread_number(fp); break; case 'F': roster->flags = fread_flag(fp); break; case 'L': roster->last_login = fread_number(fp); break; case 'N': free_string(roster->name); roster->name = str_dup(fread_word(fp)); break; case 'O': break; case 'P': roster->penalty_time = fread_number(fp); break; case 'Q': roster->petition = get_clan_by_id(fread_number(fp)); break; case 'S': roster->pkilldata = new_pkill_data(); roster->pkilldata->kPoints = fread_number(fp); roster->pkilldata->kills = fread_number(fp); roster->pkilldata->deaths = fread_number(fp); roster->pkilldata->wins = fread_number(fp); roster->pkilldata->losses = fread_number(fp); break; case 'T': roster->trust = fread_number(fp); break; default: printf_debug("load_roster_data: read invalid section %c", letter); fread_string_eol(fp); break; } if (!foundHash) { printf_debug( "load_roster_data: # not found"); break; } } } /* Load all rosters */ void load_all_rosters(void) { FILE *fp, *fpList; char file[100]; if ((fpList = fopen(is_main_server() ? ROSTER_DATA_LIST : TEST_ROSTER_DATA_LIST, "r")) == NULL) { perror(is_main_server() ? ROSTER_DATA_LIST : TEST_ROSTER_DATA_LIST); exit(1); } while (!feof(fpList)) { char *word; word = fread_word(fpList); if (!str_cmp(word, "END")) break; sprintf(file, "%s%s", is_main_server() ? ROSTER_DATA_FOLDER : TEST_ROSTER_DATA_FOLDER, word); if ((fp = fopen(file, "r")) == NULL) { perror(file); continue; } load_roster_data(fp); fclose(fp); } fclose(fpList); update_all_rosters(); } /* Save a roster */ void save_roster_data(ROSTER_DATA *roster) { FILE *fp; char file[100]; sprintf(file, "%s%d.rost", is_main_server() ? ROSTER_DATA_FOLDER : TEST_ROSTER_DATA_FOLDER, roster->id); if ((fp = fopen(file, "w")) == NULL) { printf_system("save_roster_data: unable to open file for writing roster"); return; } fprintf(fp, "# %d\n", roster->id); fprintf(fp, "N %s\n", roster->name); fprintf(fp, "P %ld\n", roster->penalty_time); fprintf(fp, "S %ld %d %d %d %d\n", roster->pkilldata->kPoints, roster->pkilldata->kills, roster->pkilldata->deaths, roster->pkilldata->wins, roster->pkilldata->losses); fprintf(fp, "F %s\n", print_flags(roster->flags)); if (!IS_SET( roster->flags, ROST_DELETED )) { fprintf(fp, "C %d\n", roster->clan ? roster->clan->id : CLAN_NONE ); if (roster->petition) fprintf(fp, "Q %d\n", roster->petition->id); fprintf(fp, "L %ld\n", roster->last_login); fprintf(fp, "D %ld\n", roster->dPoints); fprintf(fp, "B %ld\n", roster->bounty); fprintf(fp, "T %d\n", roster->trust); } fprintf(fp, "$\n"); fclose(fp); } /* Save all roster data */ void save_all_rosters(void) { FILE *fpList; ROSTER_DATA *roster; if ((fpList = fopen(TEMP_FILE, "w")) == NULL) // Open temp data file so previously saved roster data isn't wiped out if theres a problem { printf_system("save_all_rosters: unable to open temp data file for writing roster list"); return; } for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED ) && roster->penalty_time <= current_time) continue; fprintf(fpList, "%d.rost\n", roster->id); save_roster_data(roster); } fprintf(fpList, "END\n"); fclose(fpList); rename(TEMP_FILE, is_main_server() ? ROSTER_DATA_LIST : TEST_ROSTER_DATA_LIST ); } /* Load the spamkill list */ void load_pkhist_data(void) { FILE *fp; int maxVal; if ((fp = fopen(PKHIST_DATA_FILE, "r")) == NULL) { printf_system("Error opening PKHIST_DATA_FILE"); return; } if ((maxVal = fread_number(fp)) <= 0) { fclose(fp); return; } if ((pkhist_table = malloc(sizeof(PKHIST_DATA) * maxVal)) == NULL) { printf_system("Error allocating memory for pkhist_table"); exit(1); } while (!feof(fp)) { char letter; letter = fread_letter(fp); if (letter == '$') break; else if (letter == '#') { max_pkhist_entries++; pkhist_table[max_pkhist_entries - 1].victim = get_roster_by_id( fread_number(fp)); pkhist_table[max_pkhist_entries - 1].killer = get_roster_by_id( fread_number(fp)); pkhist_table[max_pkhist_entries - 1].vClan = get_clan_by_id( fread_number(fp)); pkhist_table[max_pkhist_entries - 1].kClan = get_clan_by_id( fread_number(fp)); pkhist_table[max_pkhist_entries - 1].time = fread_number(fp); pkhist_table[max_pkhist_entries - 1].vLevel = fread_number(fp); pkhist_table[max_pkhist_entries - 1].kLevel = fread_number(fp); pkhist_table[max_pkhist_entries - 1].flags = fread_flag(fp); if (pkhist_table[max_pkhist_entries - 1].killer == NULL || pkhist_table[max_pkhist_entries - 1].victim == NULL) max_pkhist_entries--; } else { printf_debug("load_pkhist_data: read invalid section %c", letter); fread_string_eol(fp); } } fclose(fp); if (max_pkhist_entries < maxVal) { PKHIST_DATA *pkhist; if (max_pkhist_entries == 0) { free(pkhist_table); pkhist_table = NULL; return; } else if ((pkhist = realloc(pkhist_table, sizeof(PKHIST_DATA) * max_pkhist_entries)) == NULL) { printf_system("load_pkhist_data: unable to reallocate memory after one or more null entries."); return; } pkhist_table = pkhist; } } void save_pkhist_data(void) { FILE *fp; int i; int max_hist = UMIN(max_pkhist_entries, 100); if (!pkhist_table || max_pkhist_entries <= 0) return; if ((fp = fopen(PKHIST_DATA_FILE, "w")) == NULL) { printf_system("save_pkhist_data: unable to open temp data file for writing roster list"); return; } fprintf(fp, "%d\n", max_hist); for (i = UMAX(max_pkhist_entries-max_hist, 0); i < max_pkhist_entries; i++) fprintf(fp, "# %d %d %d %d %ld %d %d %s\n", pkhist_table[i].victim->id, pkhist_table[i].killer->id, pkhist_table[i].vClan ? pkhist_table[i].vClan->id : -1, pkhist_table[i].kClan ? pkhist_table[i].kClan->id : -1, pkhist_table[i].time, pkhist_table[i].vLevel, pkhist_table[i].kLevel, print_flags(pkhist_table[i].flags)); fprintf(fp, "$\n"); fclose(fp); } /* Fix clan data, upgrade data, etc */ void fix_clan_boot(void) { CLAN_DATA *clan; char buf[MAX_STRING_LENGTH]; int i, j; // Fix petitioned enemies for (clan = clan_list; clan != NULL; clan = clan->next) if (clan->Penemy.id) clan->Penemy.data = get_clan_by_id(clan->Penemy.id); for (i = 0; spell_prices[i].name[0] != '\0'; i++) { j = -1; strcpy(buf, spell_prices[i].name); while (buf[++j] != '\0') if (buf[j] == '_') buf[j] = ' '; if ((spell_prices[i].bit = skill_lookup(buf)) < 0) { printf_debug( "Unknown spell for spell_prices: %s.", spell_prices[i].name); } } for (i = 0; damtype_prices[i].name[0] != '\0'; i++) { if ((damtype_prices[i].bit = attack_lookup(damtype_prices[i].name)) <= 0) { printf_debug( "Possible unknown damtype for damtype_prices: %s.", damtype_prices[i].name); } } } /********************************** UPGRADE FUNCTIONS *********************************/ /* Find out whether clan has requirements for upgrade */ bool upgrade_req_pass(CHAR_DATA *ch, COST_DATA *table, bool showPass) { BUFFER *output = new_buf(); CLAN_DATA *clan; char buf[MAX_STRING_LENGTH], level[100]; int i; bool pass, roompass = TRUE, mobpass = TRUE, found; EDIT_CLAN( ch, clan ); sprintf(buf, "{C%s\n\r", capitalize(table->name)); add_buf(output, buf); add_buf(output, "{WRoom requirements:\n\r"); for (found = FALSE, i = 0; i < CROOM_MAX; i++) { if (!table->cRoom[i]) continue; pass = FALSE; found = TRUE; if (i == CROOM_GSHRINE && table->cRoom[CROOM_GSHRINE] == table->cRoom[CROOM_ESHRINE]) { if (clan->cRoom[CROOM_GSHRINE] != NULL || clan->cRoom[CROOM_ESHRINE] != NULL) { if (showPass) { sprintf(buf, " {w%-15s{B: {Gyes\n\r", "Either shrine"); add_buf(output, buf); } } else { sprintf(buf, " {w%-15s{B: {Rno\n\r", "Either shrine"); add_buf(output, buf); roompass = FALSE; } i++; continue; } else if (table->cRoom[i] && clan->cRoom[i] != NULL) pass = TRUE; if (pass && showPass) { sprintf(buf, " {w%-15s{B: {Gyes\n\r", capitalize( croom_table[i].name)); add_buf(output, buf); } else if (!pass) { roompass = FALSE; sprintf(buf, " {w%-15s{B: {Rno\n\r", capitalize(croom_table[i].name)); add_buf(output, buf); } } if (!showPass && roompass && found) add_buf(output, "{w All room requirements have passed.\n\r"); else if (!found) add_buf(output, "{w There are no room requirements.\n\r"); if (IS_SET( table->flags, UPGD_XCOST )) add_buf(output, "{w There might be additional requirements.\n\r"); add_buf(output, "{WMobile requirements:\n\r"); for (found = FALSE, i = 0; i < CMOB_MAX; i++) { if (table->cMob[i] <= 0) continue; pass = FALSE; found = TRUE; if (i == CMOB_GPRIEST && table->cMob[CMOB_GPRIEST] == table->cMob[CMOB_EPRIEST]) { if ((clan->cMob[CMOB_GPRIEST] && clan->cMob[CMOB_GPRIEST]->level >= table->cMob[CMOB_GPRIEST]) || (clan->cMob[CMOB_EPRIEST] && clan->cMob[CMOB_EPRIEST]->level >= table->cMob[CMOB_GPRIEST])) { if (showPass) { sprintf(buf, " {wLevel {C%3d{b:{w %-15s{B- {Gyes\n\r", table->cMob[CMOB_GPRIEST], "Either priest"); add_buf(output, buf); } } else { level[0] = '\0'; if (clan->cMob[CMOB_GPRIEST]) sprintf(level, "{W({wG{W:{w %d{B) ", clan->cMob[CMOB_GPRIEST]->level); if (clan->cMob[CMOB_EPRIEST]) { sprintf(buf, "{W({wE{W:{w %d{B)", clan->cMob[CMOB_EPRIEST]->level); strcat(level, buf); } sprintf(buf, " {wLevel {C%3d{b:{w %-15s{B- {Rno%s\n\r", table->cMob[CMOB_GPRIEST], "Either priest", level); add_buf(output, buf); } i++; continue; } else if (clan->cMob[i] && clan->cMob[i]->level >= table->cMob[i]) pass = TRUE; if (pass && showPass) { sprintf(buf, " {wLevel {C%3d{B:{w %-15s{B- {Gyes\n\r", table->cMob[i], capitalize(cmob_table[i].name)); add_buf(output, buf); } else if (!pass) { mobpass = FALSE; if (clan->cMob[i]) sprintf(level, "{W({wCurr{W: {w%d{W)", clan->cMob[i]->level); else strcpy(level, ""); sprintf(buf, " {wLevel {C%3d{B:{w %-15s{B- {Rno %s\n\r", table->cMob[i], capitalize(cmob_table[i].name), level); add_buf(output, buf); } } if (!showPass && mobpass && found) add_buf(output, "{w All mob requirements have passed.\n\r"); else if (!found) add_buf(output, "{w There are no mob requirements.\n\r"); if (IS_SET( table->flags, UPGD_XCOST )) add_buf(output, "{w There might be additional requirements.\n\r"); add_buf(output, "{WCost:\n\r"); if (IS_SET( table->flags, UPGD_XCOST )) add_buf(output, "{wPrice is variable.\n\r"); else { if (table->platinum > 0) { sprintf(buf, " {wPlatinum:{Y %7d {B- %s\n\r", table->platinum, clan->platinum >= table->platinum ? "{Gyes" : "{Rno"); add_buf(output, buf); } if (table->qps > 0) { sprintf(buf, " {wQuest: {Y %7d {B- %s\n\r", table->qps, clan->qps >= table->qps ? "{Gyes" : "{Rno"); add_buf(output, buf); } if (table->platinum <= 0 && table->qps <= 0) add_buf(output, " {GFree.\n\r"); } add_buf(output, "\n\r{GYes{w/{Rno{w shows whether requirement is fulfilled or not.{x\n\r"); if (IS_SET( table->flags, UPGD_XCOST )) add_buf( output, "Additional arguments are required - append {Rlist{x to the previous argument to see a list.\n\r"); if (!showPass && (!roompass || !mobpass)) { add_buf(output, "{ROne or more of the requirements still need fulfilling.{x\n\r"); page_to_char(output->string, ch); } else if (showPass) page_to_char(output->string, ch); free_buf(output); return (roompass & mobpass); } /* Process upgrade requests - return TRUE if possible */ bool upgrade_process(CHAR_DATA *ch, char *argument, COST_DATA *table, bool buy) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob = NULL; OBJ_INDEX_DATA *pObj = NULL; ROSTER_DATA *roster; XCOST_DATA *xcost = NULL; char item[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; long plat, qps; int quantity = 1, current, max, cMobIndex = CMOB_MAX; if (argument[0] == '\0') { send_to_char("Please specify an item.\n\r", ch); return FALSE; } argument = one_argument(argument, item); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (table == obj_upgd_prices) EDIT_OBJ( ch, pObj ); else if (table == mob_upgd_prices) { EDIT_MOB( ch, pMob ); for (cMobIndex = 0; cMobIndex < CMOB_MAX; cMobIndex++) if (pMob == clan->cMob[cMobIndex]) break; } for (; table->name[0] != '\0'; table++) { if (pObj && table->specific[0] != -1 && pObj->item_type != table->specific[0]) continue; if (pMob && table->specific[0] != -1 && cMobIndex < CMOB_MAX && cMobIndex != table->specific[0]) continue; if (!str_prefix(item, table->name)) break; } if (table->name[0] == '\0') { send_to_char("Item not found. Use the list option to see a list.\n\r", ch); return FALSE; } if (IS_SET( table->flags, UPGD_XCOST )) { argument = one_argument(argument, item); if (!str_cmp(item, "list")) { xupgrade_list_table(ch, table); return FALSE; } } if (!upgrade_req_pass(ch, table, !buy)) return FALSE; if (!buy) return TRUE; if (IS_SET( table->flags, UPGD_XCOST )) { if (item[0] == '\0') { send_to_char( "This item has different types. Please specify the type.\n\r", ch); send_to_char( "Use {Glist{x as an argument (e.g. \"{Gobj buy add_spell list{x\") to view the types.\n\r", ch); return FALSE; } for (xcost = table->xcost; xcost->name[0] != '\0'; xcost++) if (!str_prefix(item, xcost->name)) break; if (xcost->name[0] == '\0') { send_to_char( "What type of this upgrade would you like? - Use \"{Gbuy req <item> list{x\" for a list.\n\r", ch); return FALSE; } if (table->xreq1 != CMOB_MAX) { if (clan->cMob[table->xreq1] == NULL || clan->cMob[table->xreq1]->level < xcost->req1) { sprintf( buf, "You need a {R%s{x at level {R%d{x for this specific type.\n\r", cmob_table[table->xreq1].name, xcost->req1); send_to_char(buf, ch); return FALSE; } } if (table->xreq2 != CMOB_MAX) { if (clan->cMob[table->xreq2] == NULL || clan->cMob[table->xreq2]->level < xcost->req2) { sprintf( buf, "You need a {R%s{x at level {R%d{x for this specific type.\n\r", cmob_table[table->xreq2].name, xcost->req2); send_to_char(buf, ch); return FALSE; } } if (clan->platinum < xcost->platinum) { sprintf( buf, "The clan only has {R%ld{x platinum and the upgrade requires at least {R%d{x platinum.\n\r", clan->platinum, xcost->platinum); send_to_char(buf, ch); return FALSE; } if (clan->qps < xcost->qps) { sprintf( buf, "The clan only has {R%ld{x Quest points and the upgrade requires at least {R%d{x Quest points.\n\r", clan->qps, xcost->qps); send_to_char(buf, ch); return FALSE; } } if (is_number(argument)) { quantity = atoi(argument); if (IS_SET( table->flags, UPGD_NO_BULK )) { send_to_char( "Quantity argument ignored - this item doesn't come in bulk.\n\r", ch); quantity = 1; } if (quantity <= 0) { send_to_char("The quantity must be greater than 0.\n\r", ch); return FALSE; } } else if (!IS_SET( table->flags, UPGD_NO_BULK )) { send_to_char("Please specify a quantity.\n\r", ch); return FALSE; } current = ((*table->curr_value)(ch, table)); if (table->max == MAX_SPECIAL) { max = ((*table->max_func)(ch, table)); if (current >= max) { send_to_char("The current quantity is already at the maximum.\n\r", ch); return FALSE; } if ((current + (quantity * (table->quantity))) > max) { send_to_char( "You have specified an amount that would exceed the maximum.\n\r", ch); return FALSE; } } else if (table->max != MAX_NONE) { if (current >= table->max) { send_to_char("The current quantity is already at the maximum.\n\r", ch); return FALSE; } if ((current + (quantity * (table->quantity))) > table->max) { send_to_char( "You have specified an amount that would exceed the maximum.\n\r", ch); return FALSE; } } plat = quantity * (table->platinum); if (IS_SET( table->flags, UPGD_XCOST )) plat += quantity * (xcost->platinum); qps = quantity * (table->qps); if (IS_SET( table->flags, UPGD_XCOST )) qps += quantity * (xcost->qps); if (qps > 0 && plat > 0 && clan->platinum < plat && clan->qps < qps) { sprintf( buf, "The clan cannot cover the price of {R%ld{x platinum and {R%ld{x Quest points\n\r", plat, qps); send_to_char(buf, ch); return FALSE; } else if (qps > 0 && clan->qps < qps) { sprintf(buf, "The clan cannot cover the price of {R%ld{x Quest points\n\r", qps); send_to_char(buf, ch); return FALSE; } else if (plat > 0 && clan->platinum < plat) { sprintf(buf, "The clan cannot cover the price of {R%ld{x platinum.\n\r", plat); send_to_char(buf, ch); return FALSE; } clan->u_quantity = quantity; clan->upgrade = table; clan->u_rost = roster; if (IS_SET( table->flags, UPGD_XCOST )) clan->xupgrade = xcost; else clan->xupgrade = NULL; // Prevent any mixups upgd_handler(ch, ""); return TRUE; } /* If a clan has a pending upgrade, input processing is switched from cedit handler to here */ void upgd_handler(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH]; int total, plat = 0, qps = 0; EDIT_CLAN( ch, clan ); argument = one_argument(argument, arg); if (arg[0] == '\0') { BUFFER *output = new_buf(); add_buf(output, "You have a clan upgrade pending:\n\r"); sprintf(buf, "{WType:{w %s\n\r", capitalize(clan->upgrade->name)); add_buf(output, buf); if (clan->u_quantity > 1) { total = (clan->u_quantity) * (clan->upgrade->quantity); sprintf(buf, "{WQuantity: {w%2d {Wx {w%4d {W= {G%d\n\r", clan->u_quantity, clan->upgrade->quantity, total); add_buf(output, buf); if (clan->upgrade->max == MAX_NONE) sprintf(buf, " {WTotal quantity post-purchase: {g%d\n\r", total + ((*clan->upgrade->curr_value)(ch, clan->upgrade))); else sprintf( buf, " {WTotal quantity post-purchase: {g%d {W({wMax: %d{W)\n\r", total + ((*clan->upgrade->curr_value)(ch, clan->upgrade)), clan->upgrade->max == MAX_SPECIAL ? ((*clan->upgrade->max_func)( ch, clan->upgrade)) : clan->upgrade->max); add_buf(output, buf); if (clan->upgrade->qps || (clan->xupgrade && clan->xupgrade->qps)) { total = (clan->u_quantity) * (clan->upgrade->qps); if (clan->xupgrade) total += (clan->u_quantity) * (clan->xupgrade->qps); sprintf(buf, "{YQ{yuest{W cost: {w%2d {Wx {w%4d {W= {Y%d\n\r", clan->u_quantity, clan->xupgrade ? clan->upgrade->qps + clan->xupgrade->qps : clan->upgrade->qps, total); add_buf(output, buf); sprintf(buf, " {WClan {YQ{yuest{W amount post-purchase:{R %ld\n\r", (clan->qps) - total); add_buf(output, buf); } if (clan->upgrade->platinum || (clan->xupgrade && clan->xupgrade->platinum)) { total = (clan->u_quantity) * (clan->upgrade->platinum); if (clan->xupgrade) total += (clan->u_quantity) * (clan->xupgrade->platinum); sprintf(buf, "{CP{clatinum {Wcost: {w%2d {Wx {w%4d {W= {Y%d\n\r", clan->u_quantity, clan->xupgrade ? clan->upgrade->platinum + clan->xupgrade->platinum : clan->upgrade->platinum, total); add_buf(output, buf); sprintf( buf, " {WClan {CP{clatinum{W amount post-purchase:{R %ld\n\r", (clan->platinum) - total); add_buf(output, buf); } } else { sprintf(buf, "{WQuantity: {G%d\n\r", clan->upgrade->quantity); add_buf(output, buf); if (clan->upgrade->max == MAX_NONE) sprintf(buf, " {WTotal quantity post-purchase: {g%d\n\r", clan->upgrade->quantity + ((*clan->upgrade->curr_value)(ch, clan->upgrade))); else sprintf( buf, " {WTotal quantity post-purchase: {g%d {W({wMax: %d{W)\n\r", clan->upgrade->quantity + ((*clan->upgrade->curr_value)(ch, clan->upgrade)), clan->upgrade->max == MAX_SPECIAL ? ((*clan->upgrade->max_func)( ch, clan->upgrade)) : clan->upgrade->max); if (clan->upgrade->qps || (clan->xupgrade && clan->xupgrade->qps)) { sprintf(buf, "{YQ{yuest{W cost: {Y%d\n\r", clan->xupgrade ? clan->upgrade->qps + clan->xupgrade->qps : clan->upgrade->qps); add_buf(output, buf); sprintf(buf, " {WClan {YQ{yuest{W amount post-purchase:{R %ld\n\r", (clan->qps) - (clan->xupgrade ? clan->upgrade->qps + clan->xupgrade->qps : clan->upgrade->qps)); add_buf(output, buf); } if (clan->upgrade->platinum || (clan->xupgrade && clan->xupgrade->platinum)) { sprintf(buf, "{CP{clatinum {Wcost: {Y%d\n\r", clan->xupgrade ? clan->upgrade->platinum + clan->xupgrade->platinum : clan->upgrade->platinum); add_buf(output, buf); sprintf( buf, " {WClan {CP{clatinum{W amount post-purchase:{R %ld\n\r", (clan->platinum) - (clan->xupgrade ? clan->upgrade->platinum + clan->xupgrade->platinum : clan->upgrade->platinum)); add_buf(output, buf); } } add_buf(output, "{xType {Gconfirm{x to accept, {Rclear{x to clear.\n\r"); send_to_char(output->string, ch); free_buf(output); } else if (!str_cmp(arg, "confirm")) { int state = ((*clan->upgrade->func)(ch, argument, clan->upgrade, clan->xupgrade)); if (state == UPGRADE_SUCCESS) { send_to_char("Upgrade successful.\n\r", ch); if (clan->upgrade->qps || (clan->xupgrade && clan->xupgrade->qps)) { qps = (clan->u_quantity) * (clan->upgrade->qps); if (clan->xupgrade) qps += (clan->u_quantity) * (clan->xupgrade->qps); clan->qps -= qps; sprintf( buf, "{R%d {YQ{yuest{x points have been deducted from your clan accounts.\n\r", qps); send_to_char(buf, ch); sprintf(buf, "{YQ{yuest{x points remaining in accounts: {Y%ld\n\r", clan->qps); send_to_char(buf, ch); } if (clan->upgrade->platinum || (clan->xupgrade && clan->xupgrade->platinum)) { plat = (clan->u_quantity) * (clan->upgrade->platinum); if (clan->xupgrade) plat += (clan->u_quantity) * (clan->xupgrade->platinum); clan->platinum -= plat; sprintf( buf, "{R%d {CP{clatinum{x have been deducted from your clan accounts.\n\r", plat); send_to_char(buf, ch); sprintf(buf, "{CP{clatinum{x remaining in accounts: {Y%ld\n\r", clan->platinum); send_to_char(buf, ch); } sprintf( buf, "{w%d {Wx {w%s{W({wblock quantity: %d{W){x, {YQ{yuest{x cost: {Y%d{x, {CP{clatinum{x cost: {Y%d", clan->u_quantity, clan->upgrade->name, clan->upgrade->quantity, qps, plat); append_clan_log(clan, ENTRY_UPGRADE, ch->name, buf); clan->upgrade = NULL; clan->xupgrade = NULL; clan->u_quantity = 0; save_area(get_clan_area()); save_clan_data(clan); int i; for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) { reset_clan_obj(get_obj_index(i), FALSE); reset_clan_mob(get_mob_index(i), FALSE); } } else if (state == UPGRADE_REQ_ARG) send_to_char( "To confirm the upgrade, type {Rconfirm <required arguments>{x\n\r", ch); else { send_to_char( "Clan upgrade failed. Please contact an immortal.\n\r", ch); sprintf(buf, "%s clan upgrade failed for clan %s, quantity %d.", clan->upgrade->name, clan->name, clan->u_quantity); printf_debug(buf); wiznet(buf, ch, NULL, WIZ_DEBUG, 0, 0); clan->upgrade = NULL; clan->xupgrade = NULL; clan->u_rost = NULL; clan->u_quantity = 0; save_clan_data(clan); save_area(get_clan_area()); } } else if (!str_cmp(arg, "clear")) { clan->upgrade = NULL; clan->xupgrade = NULL; clan->u_rost = NULL; clan->u_quantity = 0; send_to_char("Pending clan upgrade cleared.\n\r", ch); } else upgd_handler(ch, ""); } void upgrade_list_table(CHAR_DATA *ch, COST_DATA *table) { BUFFER *output = new_buf(); CLAN_DATA *clan; MOB_INDEX_DATA *pMob = NULL; OBJ_INDEX_DATA *pObj = NULL; char buf[MAX_STRING_LENGTH]; int cval, mval, cMobIndex = CMOB_MAX; EDIT_CLAN( ch, clan ); add_buf(output, "{WName Qnty Plat QPs Curr/Max Description\n\r"); if (table == obj_upgd_prices) EDIT_OBJ( ch, pObj ); else if (table == mob_upgd_prices) { EDIT_MOB( ch, pMob ); for (cMobIndex = 0; cMobIndex < CMOB_MAX; cMobIndex++) if (pMob == clan->cMob[cMobIndex]) break; } for (; table->name[0] != '\0'; table++) { if (pObj && table->specific[0] != -1 && pObj->item_type != table->specific[0]) continue; if (pMob && table->specific[0] != -1 && cMobIndex < CMOB_MAX && cMobIndex != table->specific[0]) continue; if (table->max == MAX_SPECIAL) mval = ((*table->max_func)(ch, table)); else mval = table->max; cval = ((*table->curr_value)(ch, table)); sprintf(buf, "{w%-15s {R%4d {w%6d {w%6d {c%5d/{C%-5d {w%s\n\r", capitalize(table->name), table->quantity, table->platinum, table->qps, cval, mval, table->descr); add_buf(output, buf); } add_buf(output, "\n\r{WUse the {Greq <item>{W option to view full requirements.{x\n\r"); page_to_char(output->string, ch); free_buf(output); } void xupgrade_list_table(CHAR_DATA *ch, COST_DATA *table) { BUFFER *output = new_buf(); CLAN_DATA *clan; XCOST_DATA *xcost; char buf[MAX_STRING_LENGTH], flags[10]; int req1 = 0, req2 = 0; EDIT_CLAN( ch, clan ); sprintf(buf, "{WName Type Flags Plat Qps %-11s ", table->xreq1 == CMOB_MAX ? "n/a" : capitalize( cmob_table[table->xreq1].name)); add_buf(output, buf); sprintf(buf, "%-11s\n\r", table->xreq2 == CMOB_MAX ? "n/a" : capitalize( cmob_table[table->xreq2].name)); add_buf(output, buf); if (table->xreq1 != CMOB_MAX && clan->cMob[table->xreq1] != NULL) req1 = clan->cMob[table->xreq1]->level; if (table->xreq2 != CMOB_MAX && clan->cMob[table->xreq2] != NULL) req2 = clan->cMob[table->xreq2]->level; for (xcost = table->xcost; xcost->name[0] != '\0'; xcost++) { flags[0] = '\0'; if (IS_SET( xcost->flags, XUPGD_IMM_SPECIAL )) strcat(flags, "*"); else strcat(flags, "-"); sprintf( buf, "{w%-15s {w%-4s {w%5s {y%5d {Y%5d {C%-3d {B- [{%c%3d{B] {C%-3d {B- [{%c%3d{B]\n\r", capitalize(xcost->name), table->xcost == spell_prices ? (xcost->type == SPELL_DEFENSIVE ? "def" : xcost->type == SPELL_OFFENSIVE ? "off" : "misc") : "-", flags, xcost->platinum, xcost->qps, xcost->req1, xcost->req1 < req1 ? 'G' : 'R', req1, xcost->req2, xcost->req2 < req2 ? 'G' : 'R', req2); add_buf(output, buf); } add_buf(output, "{x"); page_to_char(output->string, ch); free_buf(output); } CALC_FUN( mval_xcost_count ) { if (upgrade->xcost == NULL) return 0; XCOST_DATA *xcost; int count = 0; for (xcost = upgrade->xcost; xcost->name[0] != '\0'; xcost++) count++; return count; } /* Start of mob item functions */ CALC_FUN( cval_mob_normal ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->cMob[upgrade->specific[0]] != NULL) return 1; return 0; } UPGD_FUN( mob_normal ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob, *pStock; RESET_DATA *pReset; ROOM_INDEX_DATA *pRoom; char buf[MAX_STRING_LENGTH]; int vnum, iHash, i; EDIT_CLAN( ch, clan ); // Check for room first if (upgrade->specific[0] == CMOB_HEALER) { if (clan->cRoom[CROOM_GSHRINE] == NULL) { if (clan->cRoom[CROOM_ESHRINE] == NULL) return UPGRADE_FAIL; pRoom = clan->cRoom[CROOM_ESHRINE]; } else pRoom = clan->cRoom[CROOM_GSHRINE]; } else if (upgrade->specific[0] == CMOB_PET) { if ((pRoom = get_room_index(VNUM_CLAN_PET_ROOM)) == NULL) return UPGRADE_FAIL; } else { if ((pRoom = clan->cRoom[upgrade->specific[1]]) == NULL) return UPGRADE_FAIL; } if (upgrade->specific[0] >= CMOB_MAX) return UPGRADE_FAIL; else vnum = cmob_table[upgrade->specific[0]].vnum; if ((pStock = get_mob_index(vnum)) == NULL) return UPGRADE_FAIL; if ((vnum = get_clan_mvnum(clan)) <= 0) return UPGRADE_FAIL; pMob = new_mob_index(); pMob->area = get_clan_area(); pMob->vnum = vnum; // pMob->clan_data.data = clan; strcpy(buf, pStock->player_name); str_replace_c(buf, "%s", clan->name); free_string(pMob->player_name); pMob->player_name = str_dup(buf); strcpy(buf, pStock->short_descr); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pMob->short_descr); pMob->short_descr = str_dup(buf); strcpy(buf, pStock->long_descr); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pMob->long_descr); pMob->long_descr = str_dup(buf); strcpy(buf, pStock->description); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pMob->description); pMob->description = str_dup(buf); pMob->act = pStock->act; pMob->affected_by = pStock->affected_by; pMob->shielded_by = pStock->shielded_by; pMob->alignment = pStock->alignment; pMob->level = pStock->level; pMob->hitroll = pStock->hitroll; pMob->spec_fun = pStock->spec_fun; for (i = 0; i <= 3; i++) { pMob->hit[i] = pStock->hit[i]; pMob->mana[i] = pStock->mana[i]; pMob->damage[i] = pStock->damage[i]; pMob->ac[i] = pStock->ac[i]; } pMob->ac[4] = pStock->ac[4]; pMob->dam_type = pStock->dam_type; pMob->off_flags = pStock->off_flags; pMob->imm_flags = pStock->imm_flags; pMob->res_flags = pStock->res_flags; pMob->vuln_flags = pStock->vuln_flags; pMob->start_pos = pStock->start_pos; pMob->default_pos = pStock->default_pos; pMob->sex = pStock->sex; pMob->race = pStock->race; pMob->wealth = pStock->wealth; pMob->form = pStock->form; pMob->parts = pStock->parts; pMob->size = pStock->size; free_string(pMob->material); pMob->material = str_dup(pStock->material); free_string(pMob->die_descr); pMob->die_descr = str_dup(pStock->die_descr); free_string(pMob->say_descr); pMob->say_descr = str_dup(pStock->say_descr); pMob->round_dam = pStock->round_dam; if (pStock->pShop) { pMob->pShop = new_shop(); pMob->pShop->keeper = pMob->vnum; for (i = 0; i < MAX_TRADE; i++) pMob->pShop->buy_type[i] = pStock->pShop->buy_type[i]; pMob->pShop->profit_buy = pStock->pShop->profit_buy; pMob->pShop->profit_sell = pStock->pShop->profit_sell; pMob->pShop->open_hour = pStock->pShop->open_hour; pMob->pShop->close_hour = pStock->pShop->close_hour; if (!shop_first) shop_first = pMob->pShop; if (shop_last) shop_last->next = pMob->pShop; shop_last = pMob->pShop; } iHash = vnum % MAX_KEY_HASH; pMob->next = mob_index_hash[iHash]; mob_index_hash[iHash] = pMob; clan->cMob[upgrade->specific[0]] = pMob; pReset = new_reset_data(); pReset->command = 'M'; pReset->arg1 = pMob->vnum; pReset->arg2 = 1; pReset->arg3 = pRoom->vnum; pReset->arg4 = 1; add_reset(pRoom, pReset, -1); save_area(pRoom->area); reset_room(pRoom); return UPGRADE_SUCCESS; } /* Start of object item functions */ CALC_FUN( cval_obj_normal ) // Max should be VNUM_CLAN_BLOCK { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; int count = 0, iHash; EDIT_CLAN( ch, clan ); for (iHash = 0; iHash < MAX_KEY_HASH; iHash++) { for (pObj = obj_index_hash[iHash]; pObj != NULL; pObj = pObj->next) if (pObj->vnum >= clan->vnum[0] && pObj->vnum <= clan->vnum[1] && pObj->item_type == upgrade->specific[1]) count++; } return count; } CALC_FUN( mval_obj_normal ) // Max should be VNUM_CLAN_BLOCK { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; int count = 0, objcount = 0, iHash; EDIT_CLAN( ch, clan ); for (iHash = 0; iHash < MAX_KEY_HASH; iHash++) { for (pObj = obj_index_hash[iHash]; pObj != NULL; pObj = pObj->next) { if (pObj->vnum >= clan->vnum[0] && pObj->vnum <= clan->vnum[1]) { if (pObj->item_type == upgrade->specific[1]) objcount++; count++; } } } return (objcount + VNUM_CLAN_BLOCK - count); } UPGD_FUN( obj_normal ) { CHAR_DATA *keeper; CLAN_DATA *clan; OBJ_INDEX_DATA *pObj, *pStock; RESET_DATA *pReset; ROOM_INDEX_DATA *pRoom; char buf[MAX_STRING_LENGTH]; int vnum, i = 0, iHash, v0 = -1, v2 = -1, v3 = -1; EDIT_CLAN( ch, clan ); if (IS_SET( upgrade->flags, UPGD_ROOM_OBJ )) { argument = one_argument(argument, buf); if (buf[0] == '\0') { send_to_char( "Please specify the clan room you want to load the object in.\n\r", ch); return UPGRADE_REQ_ARG; } for (i = 0; i < CROOM_MAX; i++) { if (!str_cmp(buf, croom_table[i].name)) break; } if (i == CROOM_MAX || clan->cRoom[i] == NULL) { send_to_char("Please specify a valid, existing room.\n\r", ch); return UPGRADE_REQ_ARG; } pRoom = clan->cRoom[i]; } else { if ((pRoom = clan->cRoom[CROOM_SHOP]) == NULL) return UPGRADE_FAIL; else if (clan->cMob[CMOB_SHOPKEEP] == NULL) return UPGRADE_FAIL; } argument = one_argument(argument, buf); switch (upgrade->specific[1]) { case ITEM_FOUNTAIN: if (buf[0] == '\0') { send_to_char("Please specify the liquid type.\n\r", ch); return UPGRADE_REQ_ARG; } if ((v2 = liq_lookup(buf)) < 0) { send_to_char("Invalid liquid type.\n\r", ch); return UPGRADE_REQ_ARG; } break; case ITEM_PORTAL: if (buf[0] == '\0') { send_to_char( "Please specify the area you would like the portal to go to.\n\r", ch); strcpy(buf, "{w "); for (i = 0; portloc_table[i].name[0] != '\0'; i++) { strcat(buf, portloc_table[i].name); strcat(buf, " "); } strcat(buf, "{x\n\r"); send_to_char(buf, ch); return UPGRADE_REQ_ARG; } for (i = 0; portloc_table[i].name[0] != '\0'; i++) if (!str_prefix(buf, portloc_table[i].name)) break; if ((v3 = portloc_table[i].vnum) <= 0) { send_to_char("Invalid area.\n\r", ch); return UPGRADE_REQ_ARG; } break; case ITEM_WEAPON: if (buf[0] == '\0') { send_to_char("Please specify the type of weapon.\n\r", ch); return UPGRADE_REQ_ARG; } if ((v0 = flag_value(weapon_class, buf)) == NO_FLAG) { send_to_char("Weapon type not found.\n\r", ch); return UPGRADE_REQ_ARG; } break; default: break; } if ((pStock = get_obj_index(upgrade->specific[0])) == NULL) return UPGRADE_FAIL; if ((vnum = get_clan_ovnum(clan)) <= 0) return UPGRADE_FAIL; pObj = new_obj_index(); pObj->vnum = vnum; pObj->area = get_clan_area(); strcpy(buf, pStock->name); str_replace_c(buf, "%s", clan->name); if (upgrade->specific[1] == ITEM_PORTAL) { strcat(buf, " "); strcat(buf, portloc_table[i].name); } free_string(pObj->name); pObj->name = str_dup(buf); strcpy(buf, pStock->short_descr); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pObj->short_descr); pObj->short_descr = str_dup(buf); strcpy(buf, pStock->description); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pObj->description); pObj->description = str_dup(buf); free_string(pObj->material); pObj->material = str_dup(pStock->material); pObj->item_type = pStock->item_type; pObj->extra_flags = pStock->extra_flags; pObj->wear_flags = pStock->wear_flags; pObj->level = pStock->level; pObj->condition = pStock->condition; pObj->count = pStock->count; pObj->weight = pStock->weight; pObj->cost = pStock->cost; for (i = 0; i < 5; i++) pObj->value[i] = pStock->value[i]; pObj->class = pStock->class; pObj->timer = pStock->timer; pObj->class_restrict_flags = pStock->class_restrict_flags; if (v0 > -1) pObj->value[0] = v0; if (v2 > -1) pObj->value[2] = v2; if (v3 > -1) pObj->value[3] = v3; iHash = vnum % MAX_KEY_HASH; pObj->next = obj_index_hash[iHash]; obj_index_hash[iHash] = pObj; pReset = new_reset_data(); if (IS_SET( upgrade->flags, UPGD_ROOM_OBJ )) { pReset->command = 'O'; pReset->arg1 = pObj->vnum; pReset->arg2 = 0; pReset->arg3 = pRoom->vnum; pReset->arg4 = 0; } else { pReset->command = 'G'; pReset->arg1 = pObj->vnum; pReset->arg2 = 0; pReset->arg3 = WEAR_NONE; pReset->arg4 = 0; } add_reset(pRoom, pReset, -1); save_area(pObj->area); if (IS_SET( upgrade->flags, UPGD_ROOM_OBJ )) obj_to_room(create_object(pObj, pObj->level), pRoom); else { for (keeper = pRoom->people; keeper; keeper = keeper->next_in_room) if (keeper->pIndexData && keeper->pIndexData == clan->cMob[CMOB_SHOPKEEP]) break; if (keeper) extract_char(keeper, TRUE ); } reset_room(pRoom); return UPGRADE_SUCCESS; } /* Start of room item functions */ CALC_FUN( cval_room_normal ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->cRoom[upgrade->specific[0]] != NULL) return 1; return 0; } UPGD_FUN( room_normal ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pStock, *pRoom; char buf[MAX_STRING_LENGTH]; int vnum, exit, iHash; EDIT_CLAN( ch, clan ); if (ch->in_room == NULL) return UPGRADE_FAIL; if (upgrade->specific[0] != CROOM_RECALL) { if (!is_clan_room(ch->in_room, clan, TRUE )) { send_to_char("Please move to a room owned by the clan.\n\r", ch); return UPGRADE_REQ_ARG; } if (argument[0] == '\0') { send_to_char( "Please specify the direction you wish the new room to be built in.\n\r", ch); return UPGRADE_REQ_ARG; } } switch (UPPER(argument[0])) { case 'N': exit = DIR_NORTH; break; case 'E': exit = DIR_EAST; break; case 'S': exit = DIR_SOUTH; break; case 'W': exit = DIR_WEST; break; case 'U': exit = DIR_UP; break; case 'D': exit = DIR_DOWN; break; default: send_to_char("Direction must be n, e, s, w, u, or d.\n\r", ch); return UPGRADE_REQ_ARG; } if (ch->in_room->exit[exit] || ch->in_room->exit[exit + 6]) { send_to_char( "The direction you specified already has a room. Choose another.\n\r", ch); return UPGRADE_REQ_ARG; } if (upgrade->specific[0] > CROOM_MAX) return UPGRADE_FAIL; else vnum = croom_table[upgrade->specific[0]].vnum; if ((pStock = get_room_index(vnum)) == NULL) { sprintf(buf, "UPGD_FUN room_normal: stock vnum %d for %s(%d) == NULL", vnum, upgrade->name, upgrade->specific[0]); printf_debug(buf); wiznet(buf, ch, NULL, WIZ_DEBUG, 0, 0); return UPGRADE_FAIL; } if ((vnum = get_clan_rvnum(clan)) < 0) return UPGRADE_FAIL; pRoom = new_room_index(); pRoom->area = get_clan_area(); pRoom->vnum = vnum; // pRoom->clan_data.data = clan; strcpy(buf, pStock->name); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pRoom->name); pRoom->name = str_dup(buf); strcpy(buf, pStock->description); str_replace_c(buf, "%s", strip_bespaces(clan->c_name)); free_string(pRoom->description); pRoom->description = str_dup(buf); pRoom->room_flags = pStock->room_flags; pRoom->light = pStock->light; pRoom->sector_type = pStock->sector_type; pRoom->heal_rate = pStock->heal_rate; pRoom->mana_rate = pStock->mana_rate; ch->in_room->exit[exit] = new_exit(); ch->in_room->exit[exit]->u1.to_room = pRoom; ch->in_room->exit[exit]->orig_door = exit; pRoom->exit[rev_dir[exit]] = new_exit(); pRoom->exit[rev_dir[exit]]->u1.to_room = ch->in_room; pRoom->exit[rev_dir[exit]]->orig_door = rev_dir[exit]; iHash = vnum % MAX_KEY_HASH; pRoom->next = room_index_hash[iHash]; room_index_hash[iHash] = pRoom; if (upgrade->specific[0] != CROOM_MAX) clan->cRoom[upgrade->specific[0]] = pRoom; if (upgrade->specific[0] == CROOM_RECALL) { clan->entrance_vnum = ch->in_room->vnum; clan->exit_changed = current_time; } save_area(pRoom->area); save_area(ch->in_room->area); return UPGRADE_SUCCESS; } UPGD_FUN( room_recall ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (ch->in_room == NULL) return UPGRADE_FAIL; if (is_clan_room(ch->in_room, NULL, FALSE )) { send_to_char( "Please go to the room where you want the entrance of the clan hall to be.\n\r", ch); return UPGRADE_REQ_ARG; } if (argument[0] == '\0') { send_to_char( "Please provide the direction you want the clan hall to be in.\n\r" "An example would be \"{Rconfirm u{x\".\n\r", ch); return UPGRADE_REQ_ARG; } if (!check_path(ch->in_room)) { send_to_char("There isn't a clear path from the Market Square to here.\r\n", ch); return UPGRADE_FAIL; } return room_normal(ch, argument, upgrade, xupgrade); } CALC_FUN( cval_room_hall_entrance ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->cRoom[CROOM_RECALL] == NULL) return 1; return 0; } CALC_FUN( mval_room_hall_entrance ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->cRoom[CROOM_RECALL] == NULL || (current_time - clan->exit_changed) < TIME_DAY) return 0; return 1; } UPGD_FUN( room_hall_entrance ) { CLAN_DATA *clan; int exit, i; EDIT_CLAN( ch, clan ); if (ch->in_room == NULL) return UPGRADE_FAIL; if (is_clan_room(ch->in_room, NULL, FALSE )) { send_to_char( "Please go to the room where you want the entrance of the clan hall to be.\n\r", ch); return UPGRADE_REQ_ARG; } if (argument[0] == '\0') { send_to_char( "Please provide the direction you want the clan hall to be in.\n\r" "An example would be \"{Rconfirm u{x\", if you want it to be above you.\n\r", ch); return UPGRADE_REQ_ARG; } if (!check_path(ch->in_room)) { send_to_char("There isn't a clear path from the Market Square to here.\r\n", ch); return UPGRADE_FAIL; } switch (UPPER(argument[0])) { case 'N': exit = DIR_NORTH; break; case 'E': exit = DIR_EAST; break; case 'S': exit = DIR_SOUTH; break; case 'W': exit = DIR_WEST; break; case 'U': exit = DIR_UP; break; case 'D': exit = DIR_DOWN; break; default: send_to_char("Direction must be n, e, s, w, u, or d.\n\r", ch); return UPGRADE_REQ_ARG; } if (ch->in_room->exit[exit] != NULL && ch->in_room->exit[exit]->u1.to_room != NULL) { send_to_char("You cannot have a clanhall in that direction.\r\n", ch); return UPGRADE_REQ_ARG; } for (i = 0; i < MAX_DIR; i++) if (clan->cRoom[CROOM_RECALL]->exit[i] && clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room && clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room->vnum == clan->entrance_vnum) break; if (i == MAX_DIR) { printf_debug("room_hall_entrance: no original clan hall entrance.\n\r"); return UPGRADE_FAIL; } if (ch->in_room == clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room) { send_to_char("Your clanhall already uses this room as an entrance.\r\n", ch); return UPGRADE_REQ_ARG; } AREA_DATA *oldArea = clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room->area; free_exit(clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room->exit[rev_dir[i]]); clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room->exit[rev_dir[i]] = NULL; free_exit(clan->cRoom[CROOM_RECALL]->exit[i]); clan->cRoom[CROOM_RECALL]->exit[i] = NULL; if (ch->in_room->exit[exit] != NULL) free_exit(ch->in_room->exit[exit]); ch->in_room->exit[exit] = new_exit(); ch->in_room->exit[exit]->u1.to_room = clan->cRoom[CROOM_RECALL]; ch->in_room->exit[exit]->orig_door = exit; if (clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]] != NULL) { if (clan->cRoom[CROOM_RECALL]->exit[i] != NULL) free_exit(clan->cRoom[CROOM_RECALL]->exit[i]); clan->cRoom[CROOM_RECALL]->exit[i] = new_exit(); clan->cRoom[CROOM_RECALL]->exit[i]->u1.to_room = ch->in_room; clan->cRoom[CROOM_RECALL]->exit[i]->orig_door = i; } else { if (clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]] != NULL) free_exit(clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]]); clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]] = new_exit(); clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]]->u1.to_room = ch->in_room; clan->cRoom[CROOM_RECALL]->exit[rev_dir[exit]]->orig_door = rev_dir[exit]; } clan->entrance_vnum = ch->in_room->vnum; clan->exit_changed = current_time; save_area(clan->cRoom[CROOM_RECALL]->area); save_area(ch->in_room->area); save_area(oldArea); return UPGRADE_SUCCESS; } /* Start of mob upgrade functions */ CALC_FUN( cval_mob_upgd_level ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); return pMob->level; } CALC_FUN( mval_mob_upgd_level ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; int i; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); for (i = 0; i < CMOB_MAX; i++) if (pMob == clan->cMob[i]) break; if (i == CMOB_TRAINER) return 180; if (clan->cMob[CMOB_TRAINER] == NULL) return pMob->level; else return clan->cMob[CMOB_TRAINER]->level; } UPGD_FUN( mob_upgd_level ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); pMob->level += upgrade->quantity * clan->u_quantity; pMob->hitroll = pMob->level * 2; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_hp ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); return pMob->hit[DICE_BONUS]; } UPGD_FUN( mob_upgd_hp ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); pMob->hit[DICE_BONUS] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_mana ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); return pMob->mana[DICE_BONUS]; } UPGD_FUN( mob_upgd_mana ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); pMob->mana[DICE_BONUS] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_damage ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); return pMob->damage[DICE_BONUS]; } CALC_FUN( mval_mob_upgd_damage ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; int i; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); for (i = 0; i < CMOB_MAX; i++) if (pMob == clan->cMob[i]) break; if (i == CMOB_GUARD || i == CMOB_PET) return 500; return 0; } UPGD_FUN( mob_upgd_damage ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); pMob->damage[DICE_BONUS] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_imm ) { MOB_INDEX_DATA *pMob; XCOST_DATA *xcost; int count = 0; EDIT_MOB( ch, pMob ); for (xcost = imm_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pMob->imm_flags, xcost->bit )) count++; return count; } UPGD_FUN( mob_upgd_imm ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; XCOST_DATA *xcost; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the immunity.\n\r", ch); return UPGRADE_REQ_ARG; } if (!str_prefix(argument, "add")) { if (IS_SET( pMob->imm_flags, xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } if (IS_SET( xupgrade->flags, XUPGD_IMM_SPECIAL )) { for (xcost = upgrade->xcost; xcost->name[0] != '\0'; xcost++) { if (IS_SET( xcost->flags, XUPGD_IMM_SPECIAL ) && IS_SET( pMob->imm_flags, xcost->bit )) { send_to_char( "You may only have one of this type of flag (starred ones on list) set.\n\r", ch); return UPGRADE_REQ_ARG; } } } SET_BIT( pMob->imm_flags, xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( pMob->imm_flags, xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; REMOVE_BIT( pMob->imm_flags, xupgrade->bit ); } else return mob_upgd_imm(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_res ) { MOB_INDEX_DATA *pMob; XCOST_DATA *xcost; int count = 0; EDIT_MOB( ch, pMob ); for (xcost = res_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pMob->res_flags, xcost->bit )) count++; return count; } UPGD_FUN( mob_upgd_res ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the resistance.\n\r", ch); return UPGRADE_REQ_ARG; } if (!str_prefix(argument, "add")) { if (IS_SET( pMob->res_flags, xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } SET_BIT( pMob->res_flags, xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( pMob->res_flags, xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; REMOVE_BIT( pMob->res_flags, xupgrade->bit ); } else return mob_upgd_res(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_off ) { MOB_INDEX_DATA *pMob; XCOST_DATA *xcost; int count = 0; EDIT_MOB( ch, pMob ); for (xcost = off_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pMob->off_flags, xcost->bit )) count++; return count; } UPGD_FUN( mob_upgd_off ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the offensive skill.\n\r", ch); return UPGRADE_REQ_ARG; } if (!str_prefix(argument, "add")) { if (IS_SET( pMob->off_flags, xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } SET_BIT( pMob->off_flags, xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( pMob->off_flags, xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; REMOVE_BIT( pMob->off_flags, xupgrade->bit ); } else return mob_upgd_off(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_damtype ) { return 1; } UPGD_FUN( mob_upgd_damtype ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); if (pMob->dam_type == xupgrade->bit) { send_to_char("The mob already has that damtype.\n\r", ch); return UPGRADE_REQ_ARG; } pMob->dam_type = xupgrade->bit; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_ac ) { MOB_INDEX_DATA *pMob; EDIT_MOB( ch, pMob ); return -(pMob->ac[0]); } UPGD_FUN( mob_upgd_ac ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; int i; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); for (i = 0; i < 4; i++) pMob->ac[i] -= upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_mob_upgd_perm ) { MOB_INDEX_DATA *pMob; XCOST_DATA *xcost; int count = 0; EDIT_MOB( ch, pMob ); for (xcost = bitaf_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pMob->affected_by, xcost->bit ) || IS_SET( pMob->shielded_by, xcost->bit )) count++; return count; } UPGD_FUN( mob_upgd_perm ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; long *flags; EDIT_MOB( ch, pMob ); EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the perm effect.\n\r", ch); return UPGRADE_REQ_ARG; } if (xupgrade->type == BIT_AFFECT) flags = &(pMob->affected_by); else flags = &(pMob->shielded_by); if (!str_prefix(argument, "add")) { if (IS_SET( *flags, xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; SET_BIT( *flags, xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( *flags, xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } REMOVE_BIT( *flags, xupgrade->bit ); } else return mob_upgd_perm(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } /* Start of object upgrade functions */ UPGD_FUN( obj_upgd_furn_capacity ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[0] += upgrade->quantity * clan->u_quantity; pObj->value[1] += upgrade->quantity * clan->u_quantity * 100; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_v0 ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); return pObj->value[0]; } UPGD_FUN( obj_upgd_v0 ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[0] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_v2 ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); return pObj->value[2]; } UPGD_FUN( obj_upgd_v2 ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[2] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_v3 ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); return pObj->value[3]; } UPGD_FUN( obj_upgd_v3 ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[3] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_v4 ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); return pObj->value[4]; } UPGD_FUN( obj_upgd_v4 ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[4] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_add1_spell ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if (pObj->value[3] > 0 && pObj->value[3] < MAX_SKILL) return 1; return 0; } UPGD_FUN( obj_upgd_add1_spell ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); pObj->value[3] = xupgrade->bit; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_add3_spell ) { OBJ_INDEX_DATA *pObj; int i, count = 0; EDIT_OBJ( ch, pObj ); for (i = 1; i <= 4; i++) { if (pObj->value[i] > 0 && pObj->value[i] < MAX_SKILL) count++; } return count; } UPGD_FUN( obj_upgd_add3_spell ) { OBJ_INDEX_DATA *pObj; int slot; EDIT_OBJ( ch, pObj ); for (slot = 1; slot < 4; slot++) { if (pObj->value[slot] == xupgrade->bit) { send_to_char( "You can only have one of each type of spell and this item already has this spell.\n\r", ch); send_to_char("Please clear the upgrade.\n\r", ch); return UPGRADE_REQ_ARG; } } if (argument[0] == '\0' || !is_number(argument)) { send_to_char( "Please specfiy a slot number to put the spell into.\n\r" "{RNote: {xThe spell you specify WILL replace the preset spell in the slot.\n\r", ch); return UPGRADE_REQ_ARG; } if ((slot = atoi(argument)) < 1 || slot > 3) { send_to_char("The slot number must be between 1 and 3.\n\r", ch); return UPGRADE_REQ_ARG; } pObj->value[slot] = xupgrade->bit; return UPGRADE_SUCCESS; } UPGD_FUN( obj_upgd_charges ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[1] += upgrade->quantity * clan->u_quantity; pObj->value[2] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } UPGD_FUN( obj_upgd_damage ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); pObj->value[1] += upgrade->quantity * clan->u_quantity; pObj->value[2] += upgrade->quantity * clan->u_quantity; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_damtype ) { return 1; } UPGD_FUN( obj_upgd_damtype ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); pObj->value[3] = xupgrade->bit; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_wpnflag ) { OBJ_INDEX_DATA *pObj; XCOST_DATA *xcost; int count = 0; EDIT_OBJ( ch, pObj ); for (xcost = wpnflag_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pObj->value[4], xcost->bit )) count++; return count; } UPGD_FUN( obj_upgd_wpnflag ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the weapon flag.\n\r", ch); return UPGRADE_REQ_ARG; } if (!str_prefix(argument, "add")) { if (IS_SET( pObj->value[4], xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } SET_BIT( pObj->value[4], xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( pObj->value[4], xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; REMOVE_BIT( pObj->value[4], xupgrade->bit ); } else return obj_upgd_wpnflag(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } UPGD_FUN( obj_upgd_cont_capacity ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); pObj->value[0] += upgrade->quantity * clan->u_quantity; pObj->value[3] += (upgrade->quantity / 5) * clan->u_quantity; pObj->value[4] -= 1; return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_affected ) { AFFECT_DATA *af; OBJ_INDEX_DATA *pObj; int count = 0; EDIT_OBJ( ch, pObj ); for (af = pObj->affected; af != NULL; af = af->next) if (af->where == TO_OBJECT && af->location == upgrade->specific[1]) count += af->modifier; if (upgrade->specific[1] == APPLY_SAVES || upgrade->specific[1] == APPLY_AC) count *= -1; return count; } UPGD_FUN( obj_upgd_affected ) { AFFECT_DATA *af; CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); EDIT_CLAN( ch, clan ); if (!IS_SET( pObj->wear_flags, ITEM_TAKE )) { send_to_char( "Effects cannot be added to this item. Please clear the transaction.\n\r", ch); return UPGRADE_REQ_ARG; } for (af = pObj->affected; af != NULL; af = af->next) if (af->where == TO_OBJECT && af->location == upgrade->specific[1]) break; if (af == NULL) { af = new_affect(); af->where = TO_OBJECT; af->location = upgrade->specific[1]; af->type = -1; af->duration = -1; af->modifier = 0; af->bitvector = 0; af->level = pObj->level; af->next = pObj->affected; pObj->affected = af; } if (upgrade->specific[1] == APPLY_SAVES || upgrade->specific[1] == APPLY_AC) af->modifier = af->modifier - (upgrade->quantity * clan->u_quantity); else af->modifier = af->modifier + (upgrade->quantity * clan->u_quantity); return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_objflag ) { OBJ_INDEX_DATA *pObj; XCOST_DATA *xcost; int count = 0; EDIT_OBJ( ch, pObj ); for (xcost = objflag_prices; xcost->name[0] != '\0'; xcost++) if (IS_SET( pObj->extra_flags, xcost->bit )) count++; return count; } UPGD_FUN( obj_upgd_objflag ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); if (argument[0] == '\0') { send_to_char( "Please specify whether you want to remove/add the object flag.\n\r", ch); return UPGRADE_REQ_ARG; } if (!str_prefix(argument, "add")) { if (IS_SET( pObj->extra_flags, xupgrade->bit )) { send_to_char("Flag already present.\n\r", ch); return UPGRADE_REQ_ARG; } SET_BIT( pObj->extra_flags, xupgrade->bit ); } else if (!str_prefix(argument, "remove")) { if (!IS_SET( pObj->extra_flags, xupgrade->bit )) { send_to_char("Flag already not present.\n\r", ch); return UPGRADE_REQ_ARG; } clan->platinum = clan->platinum + xupgrade->platinum / 3; clan->qps = clan->qps + xupgrade->qps / 3; REMOVE_BIT( pObj->extra_flags, xupgrade->bit ); } else return obj_upgd_objflag(ch, "", upgrade, xupgrade); return UPGRADE_SUCCESS; } CALC_FUN( cval_obj_upgd_wearloc ) { OBJ_INDEX_DATA *pObj; EDIT_OBJ( ch, pObj ); if (IS_SET( pObj->wear_flags, ITEM_TAKE )) return 0; return 1; } UPGD_FUN( obj_upgd_wearloc ) { OBJ_INDEX_DATA *pObj; int i; long restricted_wearloc = ITEM_TAKE | ITEM_WEAR_BACK | ITEM_WEAR_FLOAT; EDIT_OBJ( ch, pObj ); if (!IS_SET( pObj->wear_flags, ITEM_TAKE )) { send_to_char("You cannot change the wear loc on this item.\n\r", ch); return UPGRADE_REQ_ARG; } if (argument[0] == '\0') { send_to_char( "{WAvailable wear locations (original wearloc will be replaced):\n\r{w ", ch); for (i = 0; wear_flags[i].name; i++) { if (IS_SET( restricted_wearloc, wear_flags[i].bit )) continue; send_to_char(wear_flags[i].name, ch); send_to_char(" ", ch); } send_to_char("\n\r", ch); return UPGRADE_REQ_ARG; } for (i = 0; wear_flags[i].name; i++) if (!str_prefix(argument, wear_flags[i].name)) break; if (wear_flags[i].name == NULL) { send_to_char("Wear flag not found.\n\r", ch); return UPGRADE_REQ_ARG; } if (IS_SET( restricted_wearloc, wear_flags[i].bit )) { send_to_char("Invalid wear location.\n\r", ch); return UPGRADE_REQ_ARG; } pObj->wear_flags = ITEM_TAKE | wear_flags[i].bit; return UPGRADE_SUCCESS; } /* Start of room upgrade functions */ CALC_FUN( cval_room_upgd_hpregen ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); return pRoom->heal_rate; } UPGD_FUN( room_upgd_hpregen ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); EDIT_CLAN( ch, clan ); if (clan->u_quantity < 1) clan->u_quantity = 1; pRoom->heal_rate += (clan->u_quantity) * (upgrade->quantity); return UPGRADE_SUCCESS; } CALC_FUN( cval_room_upgd_manaregen ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); return pRoom->mana_rate; } UPGD_FUN( room_upgd_manaregen ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); EDIT_CLAN( ch, clan ); if (clan->u_quantity < 1) clan->u_quantity = 1; pRoom->mana_rate += (clan->u_quantity) * (upgrade->quantity); return UPGRADE_SUCCESS; } CALC_FUN( cval_room_upgd_flag ) { ROOM_INDEX_DATA *pRoom; EDIT_ROOM( ch, pRoom ); return ((int) IS_SET( pRoom->room_flags, upgrade->specific[0] )); } UPGD_FUN( room_upgd_flag ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; EDIT_CLAN( ch, clan ); EDIT_ROOM( ch, pRoom ); if (IS_SET( pRoom->room_flags, upgrade->specific[0] )) { if (!str_cmp(argument, "remove")) { REMOVE_BIT( pRoom->room_flags, upgrade->specific[0] ); clan->platinum = clan->platinum + upgrade->platinum / 3; clan->qps = clan->qps + upgrade->qps / 3; } else { send_to_char( "Flag already set - append {Rremove{x as an argument to remove it.\n\r", ch); return UPGRADE_REQ_ARG; } return UPGRADE_SUCCESS; } SET_BIT( pRoom->room_flags, upgrade->specific[0] ); return UPGRADE_SUCCESS; } /**************************************** OLC *****************************************/ /* Finish editing clan and save clan */ void cedit_done(CHAR_DATA *ch) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->upgrade != NULL) { clan->upgrade = NULL; clan->xupgrade = NULL; clan->u_quantity = 0; clan->u_rost = NULL; send_to_char("Pending upgrade cleared.\n\r", ch); } SET_EDIT_ITEM( ch, NULL ); SET_EDIT_CLAN( ch, NULL ); SET_EDIT_TYPE( ch, ED_NONE ); save_all_clans(); } /* Show the available cedit commands */ void show_cedit_commands(CHAR_DATA *ch, char *argument, const struct cedit_cmd_type *table) { BUFFER *output = new_buf(); ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH], trustStr[20]; int i, trust; bool immortal = IS_IMMORTAL( ch ), description = FALSE; GET_ROSTER( ch, roster ); if (argument[0] != '\0' && !str_prefix(argument, "help")) description = TRUE; if (immortal) trust = get_trust(ch); else trust = roster->trust; add_buf(output, "Available commands:\n\r"); for (i = 1; table->cmd[0] != '\0'; table++) { if ((immortal && table->trust == TRUST_NONE) || (!immortal && table->m_trust == TRUST_NONE)) continue; if ((immortal && trust < table->trust) || (!immortal && trust < table->m_trust)) continue; if (immortal) sprintf(trustStr, "{C%d", table->trust); else sprintf(trustStr, "%s", table->m_trust == TRUST_ALL ? "{GALL" : table->m_trust == TRUST_MEMBER ? "{gMEM" : table->m_trust == TRUST_VLR ? "{CVLR" : table->m_trust == TRUST_LDR ? "{RLDR" : "{w---"); if (description) sprintf(buf, "{B[%s{B]{w %-12s {B:{w %s\n\r", trustStr, table->cmd, table->description); else sprintf(buf, "{B[%s{B]{w %-12s ", trustStr, table->cmd); add_buf(output, buf); if (!description && i % 4 == 0 && i > 0) add_buf(output, "\n\r"); i++; } if (!description && (i - 1) % 4 != 0) add_buf(output, "\n\r"); if (i < 1) add_buf(output, "None.\n\r"); if (!description) add_buf(output, "{WType \"{Gcommand help{W\" for a list of command descriptions.\n\r"); add_buf(output, "{x"); send_to_char(output->string, ch); free_buf(output); } /* Get clan mob to edit */ MOB_INDEX_DATA * get_cmob_by_type_name(CHAR_DATA *ch, char *name) { CLAN_DATA *clan; int i; EDIT_CLAN( ch, clan ); if (!clan) return NULL; for (i = 0; i < CMOB_MAX; i++) { if (clan->cMob[i] && !str_cmp(name, cmob_table[i].name)) return clan->cMob[i]; } return NULL; } CEDIT_FUN( cedit_create ) { CLAN_DATA *clan; char *name, buf[MAX_STRING_LENGTH]; if (argument[0] == '\0') { send_to_char("Cedit syntax: create <clan colour name>\n\r" "Normal syntax: cedit create <clan colour name>\n\r", ch); return FALSE; } if (strlen_color(argument) > MAX_CLAN_WHO_LENGTH) { sprintf( buf, "The length of the colour name cannot be longer than %d characters", MAX_CLAN_WHO_LENGTH ); send_to_char(buf, ch); return FALSE; } clan = new_clan_data(TRUE); send_to_char("Clan created.\n\r", ch); free_string(clan->c_name); clan->c_name = str_dup(argument); name = strip_spaces(argument); name = strip_spec_char_col(name); if (*name) { free_string(clan->name); clan->name = str_dup(name); } else send_to_char("Don't forget to input a meaningful keyword name.\n\r", ch); clan->edit_time = current_time + (2 * TIME_HOUR); assign_clan_vnums(clan); append_clan_log(clan, ENTRY_CREATE, ch->name, "{wClan created"); SET_EDIT_ITEM( ch, NULL ); SET_EDIT_CLAN( ch, clan ); SET_EDIT_TYPE( ch, ED_CEDIT ); save_all_clans(); cedit_show(ch, ""); return TRUE; } CEDIT_FUN( cedit_delete ) { CHAR_DATA *mob, *mob_next; CLAN_DATA *clan, *findclan; MOB_INDEX_DATA *pMob, *pMob_prev; OBJ_DATA *obj, *obj_next; OBJ_INDEX_DATA *pObj, *pObj_prev; RESET_DATA *pReset, *prevReset = NULL; ROOM_INDEX_DATA *pRoom, *pRoom_prev; ROSTER_DATA *roster; int i, iHash; bool objMove = FALSE; EDIT_CLAN( ch, clan ); if (argument[0] == '\0' || str_cmp(argument, clan->name)) { send_to_char( "The argument to the command must equal the clan name.\n\r", ch); return FALSE; } if (clan->id == CLAN_NONE || clan->id == CLAN_LONER || clan->id == CLAN_PK_OUTCAST || clan->id == CLAN_NONPK_OUTCAST || clan->id == CLAN_IMMORTAL) { send_to_char("This clan is important and cannot be deleted.\n\r", ch); return FALSE; } for (roster = roster_list; roster != NULL; roster = roster->next) { if (roster->clan == NULL) continue; if (roster->clan == clan) { if (clan->pkill) roster->clan = get_clan_by_id(CLAN_LONER); else roster->clan = get_clan_by_id(CLAN_NONE); roster->trust = TRUST_ALL; if (roster->character && (IS_EDITING_CLAN( roster->character, clan ) || roster->clan == clan)) { cedit_done(roster->character); send_to_char("{RYou clan has just been deleted!{x\n\r", ch); } } if (roster->petition == clan) { roster->petition = NULL; if (roster->character) send_to_char( "{RThe clan you have petitioned for membership was just deleted.{x\n\r", ch); } } for (i = 0; i < max_pkhist_entries; i++) { if (pkhist_table[i].vClan != NULL && pkhist_table[i].vClan == clan) pkhist_table[i].vClan = NULL; if (pkhist_table[i].kClan != NULL && pkhist_table[i].kClan == clan) pkhist_table[i].kClan = NULL; } // Find all the objects/mobs in the world and delete them - kick anyone out of the hall // Not going to check for resets because if there are resets outside the clan's area, then some immortal has done something they shouldn't have done for (mob = char_list; mob != NULL; mob = mob_next) { mob_next = mob->next; if (mob->in_room && mob->in_room->vnum >= clan->vnum[0] && mob->in_room->vnum <= clan->vnum[1] && !IS_NPC( mob )) // Move any players out { char_from_room(mob); char_to_room(mob, get_room_index(VNUM_MARKET_SQUARE)); send_to_char( "{RYou have been transferred to the Market Square because the clan that owns this room is being deleted.\n\r" "{GHave a nice day!{x\n\r", mob); do_look(mob, ""); } if (mob->pIndexData && mob->pIndexData->vnum >= clan->vnum[0] && mob->pIndexData->vnum <= clan->vnum[1]) extract_char(mob, TRUE ); } for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) reset_clan_obj(get_obj_index(i), TRUE ); for (obj = object_list; obj != NULL; obj = obj_next) { obj_next = obj->next; if (obj->in_room != NULL && is_clan_room(obj->in_room, clan, TRUE )) { obj_from_room(obj); obj_to_room(obj, ch->in_room ? ch->in_room : get_room_index( VNUM_CLAN_PET_ROOM)); objMove = TRUE; } } if (clan->entrance_vnum && (pRoom = get_room_index(clan->entrance_vnum)) != NULL) { for (i = 0; i < MAX_DIR; i++) { if (pRoom->exit[i] && pRoom->exit[i]->u1.to_room == clan->cRoom[CROOM_RECALL]) { free_exit(pRoom->exit[i]); pRoom->exit[i] = NULL; break; } } save_area(pRoom->area); } for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) { if ((pRoom = get_room_index(i)) != NULL) { iHash = pRoom->vnum % MAX_KEY_HASH; pRoom_prev = room_index_hash[iHash]; if (pRoom_prev->next == NULL) room_index_hash[iHash] = NULL; else if (pRoom_prev == pRoom) room_index_hash[iHash] = pRoom->next; else { for (; pRoom_prev; pRoom_prev = pRoom_prev->next) { if (pRoom_prev->next == pRoom) { pRoom_prev->next = pRoom->next; break; } } } free_room_index(pRoom); } } if (clan->cMob[CMOB_PET] && (pRoom = get_room_index(VNUM_CLAN_PET_ROOM)) != NULL) { for (i = 0, pReset = pRoom->reset_first; pReset != NULL; prevReset = pReset, i++, pReset = pReset->next) { if (i > 0 && pRoom->reset_first == pReset) // Reset linked list doesn't end at null, but loops round - this will only happen if pet reset not found break; if (pReset->command != 'M' || pReset->arg1 != clan->cMob[CMOB_PET]->vnum) continue; if (prevReset == NULL) { prevReset = pRoom->reset_last; if (prevReset != NULL) prevReset->next = pReset->next; pRoom->reset_first = pReset->next; } else { if (pRoom->reset_last == pReset) pRoom->reset_last = prevReset; prevReset->next = pReset->next; } free_reset_data(pReset); break; } } for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) { if ((pMob = get_mob_index(i)) != NULL) { iHash = pMob->vnum % MAX_KEY_HASH; pMob_prev = mob_index_hash[iHash]; if (pMob_prev->next == NULL) mob_index_hash[iHash] = NULL; else if (pMob_prev == pMob) mob_index_hash[iHash] = pMob->next; else { for (; pMob_prev; pMob_prev = pMob_prev->next) { if (pMob_prev->next == pMob) { pMob_prev->next = pMob->next; break; } } } free_mob_index(pMob); } } for (i = clan->vnum[0]; i <= clan->vnum[1]; i++) { if ((pObj = get_obj_index(i)) != NULL) { iHash = pObj->vnum % MAX_KEY_HASH; pObj_prev = obj_index_hash[iHash]; if (pObj_prev->next == NULL) obj_index_hash[iHash] = NULL; else if (pObj_prev == pObj) obj_index_hash[iHash] = pObj->next; else { for (; pObj_prev; pObj_prev = pObj_prev->next) { if (pObj_prev->next == pObj) { pObj_prev->next = pObj->next; break; } } } free_obj_index(pObj); } } append_clan_log(clan, ENTRY_DELETE, ch->name, "{y-{Y>{RDELETED{Y<{y-"); for (findclan = clan_list; findclan != NULL; findclan = findclan->next) { if (findclan->enemy != NULL && findclan->enemy == clan) findclan->enemy = NULL; if (findclan->Penemy.data && findclan->Penemy.data == clan) findclan->Penemy.data = NULL; } if (clan == clan_list) clan_list = clan->next; else { for (findclan = clan_list; findclan != NULL; findclan = findclan->next) { if (findclan->next == clan) { findclan->next = clan->next; break; } } } SET_EDIT_ITEM( ch, NULL ); SET_EDIT_CLAN( ch, NULL ); SET_EDIT_TYPE( ch, ED_NONE ); free_clan_data(clan); send_to_char("Clan deleted.\n\r", ch); save_all_clans(); save_all_rosters(); save_area(get_clan_area()); if (objMove) { if (ch->in_room) do_get(ch, "all"); else send_to_char( "{RSome objects have been moved to the clan pet reset room.{x\n\r", ch); } return TRUE; } CEDIT_FUN( cedit_deposit ) { CLAN_DATA *clan; ROSTER_DATA *roster; char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; int value, prev; EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (argument[0] == '\0') { send_to_char("Cedit syntax: deposit <amount> questpoints\n\r" " deposit <amount> platinum\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!is_number(arg)) { send_to_char("Please provide a numerical amount.\n\r", ch); return FALSE; } if ((value = atoi(arg)) <= 0 && !IS_IMMORTAL(ch)) { send_to_char("Amount must be greater than zero.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char("Please specify either questpoints or platinum.\n\r", ch); return FALSE; } if (!str_prefix(argument, "questpoints")) { if (ch->questpoints < value) { send_to_char("You don't have enough quest points!\n\r", ch); return FALSE; } sprintf(buf, "{R%d {YQ{yuest", value); clan->qps += value; ch->questpoints -= value; value *= POINT_VALUE_QP; } else if (!str_prefix(argument, "platinum")) { if (ch->platinum < value) { send_to_char("You don't have enough platinum!\n\r", ch); return FALSE; } sprintf(buf, "{R%d {CP{clatinum", value); clan->platinum += value; ch->platinum -= value; value *= POINT_VALUE_PLATINUM; } else { send_to_char("Please specify either questpoints or platinum.\n\r", ch); return FALSE; } append_clan_log(clan, ENTRY_DEPOSIT, ch->name, buf); // Log transaction // Bonus player for donating only if clan is theirs // (ie don't bonus immortals if the clan isn't the immortal clan) if (clan == roster->clan && (!IS_IMMORTAL( ch ) || (IS_IMMORTAL( ch ) && clan->id == CLAN_IMMORTAL))) { prev = get_r_rank_index(roster); roster->dPoints += value; sprintf( buf, "{GYou have received {Y%d{G donation points for your donation.{x\n\r", value); send_to_char(buf, ch); if ((value = get_r_rank_index(roster)) > prev) // Advanced in clan rank { sprintf(buf, "{GYour rank has advanced to {x%s{x!\n\r", clan->r_name[value]); send_to_char(buf, ch); } } return TRUE; } /* Clan description */ CEDIT_FUN( cedit_desc ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (!IS_IMMORTAL( ch ) && clan->edit_time < current_time) { send_to_char( "You do not have anymore time to edit ranks. Use {Rtime buy{x to buy more time.\n\r", ch); return FALSE; } if (argument[0] == '\0') { string_append(ch, &clan->description); append_clan_log(clan, ENTRY_CHANGED, ch->name, "Clan description changed."); return TRUE; } send_to_char("Cedit syntax: desc - set the clan description\n\r", ch); return FALSE; } /* Put a player in a clan */ CEDIT_FUN( cedit_guild ) { CLAN_DATA *clan; ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "Cedit syntax: guild <character> - guild character into this clan\n\r", ch); return FALSE; } for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (str_cmp(argument, roster->name)) continue; // Check if already in the clan if (roster->clan == clan) { sprintf(buf, "That player is already in %s{x.\n\r", strip_bespaces( clan->c_name)); send_to_char(buf, ch); return FALSE; } // Check max members if (!clan->independent && ((clan->pkill && clan->members >= MAX_PK_CLAN_MEMBERS) || (!clan->pkill && clan->members >= MAX_NONPK_CLAN_MEMBERS))) { sprintf(buf, "%s{x has enough members already.\n\r", strip_bespaces(clan->c_name)); send_to_char(buf, ch); return FALSE; } // Lower number of members in previous clan if was in one and log if (!roster->clan->independent) { (roster->clan->members)--; sprintf(buf, "Removed from clan by {R%s{w.", ch->name); if ((roster->character && (roster->character != ch || !IS_IMMORTAL( roster->character ))) || !roster->character) append_clan_log(roster->clan, ENTRY_GUILD, roster->name, buf); } roster->clan = clan; if (!clan->independent) { (clan->members)++; // Up member number in new clan if not independent roster->trust = TRUST_MEMBER; // Set trust as member // Log addition sprintf(buf, "Made member of clan by {R%s{w.", ch->name); if ((roster->character && (roster->character != ch || !IS_IMMORTAL( roster->character ))) || !roster->character) append_clan_log(clan, ENTRY_GUILD, roster->name, buf); } else roster->trust = TRUST_ALL; // Trust to 0 if independent REMOVE_BIT( roster->flags, ROST_EXILE_GRACE ); // If in exile grace period, remove flag REMOVE_BIT( roster->flags, ROST_INACTIVE ); // If flagged inactive, unflag if (clan->id == CLAN_NONPK_OUTCAST || clan->id == CLAN_PK_OUTCAST) roster->penalty_time = current_time + TIME_WEEK; // Set penalty time if outcasted else roster->penalty_time = 0; // Clear penalty time if not outcasted if (roster->character) // Tell the guy whats happened { sprintf(buf, "You have been made a member of %s{x by %s.\n\r", strip_bespaces(clan->c_name), (roster->character && roster->character == ch) ? "yourself" : ch->name); send_to_char(buf, roster->character); } if (roster->character == NULL || (roster->character && roster->character != ch)) { sprintf(buf, "{R%s{x has been made a member of %s{x.\n\r", roster->name, strip_bespaces(clan->c_name)); send_to_char(buf, ch); } save_roster_data(roster); return TRUE; } send_to_char("Player not found.\n\r", ch); return FALSE; } CEDIT_FUN( cedit_indep ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->id == CLAN_NONE || clan->id == CLAN_LONER || clan->id == CLAN_PK_OUTCAST || clan->id == CLAN_NONPK_OUTCAST || clan->id == CLAN_IMMORTAL) { send_to_char("This cannot be changed.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: independent yes/no - sets the clan as a ranked clan\n\r", ch); return FALSE; } else if (!str_cmp(argument, "yes")) { clan->independent = TRUE; send_to_char("Clan made independent.\n\r", ch); } else if (!str_cmp(argument, "no")) { clan->independent = FALSE; send_to_char("Clan is no longer independent.\n\r", ch); } else { cedit_indep(ch, ""); return FALSE; } return TRUE; } CEDIT_FUN( cedit_log ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char("Cedit syntax: log show - show clan log\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (str_prefix(arg, "show")) { cedit_log(ch, ""); return FALSE; } send_to_char("{WClan log entries:{x\n\r", ch); parse_clan_log(ch, clan, NULL, FILTER_NONE ); return FALSE; } CEDIT_FUN( cedit_member ) { CLAN_DATA *clan; ROSTER_DATA *roster, *chRoster; char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); GET_ROSTER( ch, chRoster ); if (argument[0] == '\0') { send_to_char( "Cedit syntax: member list - list current members\n\r" " member trust <player> <level> - trust player to open up parts of the cedit sytem to them\n\r" " member exile <player> <grace period in days/none>\n\r" " {RNote:{x The grace period is optional, however once marked for exile, theres no turning back.\n\r" " During the grace period, the player may leave the clan voluntarily,\n\r" " incurring less of a point cost to them and placing them in the loner\n\r" " clan. If they do not leave, they are automatically exiled from the clan,\n\r" " placed in the outcast clan and would lose more donation points.\n\r" " Without a grace period specified, the latter happens straight away\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!str_prefix(arg, "list")) { BUFFER *output = new_buf(); int count = 0; add_buf( output, "{B+-----------------------------------------------------------------------------------------+\n\r"); add_buf( output, "{B|{W No. {B|{W Trust {B|{W Rnk {B|{W Name {B|{W K Pnts {B|{W D Pnts {B|{W Last log off {B|{W Penalty {B|\n\r"); add_buf( output, "{B+-----------------------------------------------------------------------------------------+\n\r"); for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED ) || roster->clan != clan) continue; count++; sprintf( buf, "{B|{R %3d {B| %s {B|{x %s {B|{w %s {B|{R %6ld {B|{Y %6ld {B|{%c %-24.24s {B|", count, roster->trust == TRUST_LDR ? " {GLDR " : (roster->trust == TRUST_VLR ? " {MVLR " : " {w--- "), clan->independent ? "{D---" : clan->r_who[get_r_rank_index(roster)], end_string(roster == chRoster ? "{WYou" : capitalize( roster->name), 12), roster->pkilldata->kPoints, roster->dPoints, roster->character ? 'G' : 'w', roster->character ? "Online" : ctime(&(roster->last_login))); add_buf(output, buf); if (roster->penalty_time > 0) sprintf(buf, "{R %s {B-{R %2ld {B|\n\r", get_pen_code(roster), (current_time - roster->penalty_time) / TIME_DAY ); else strcpy(buf, "{G None {B|\n\r"); add_buf(output, buf); } add_buf( output, "{B+-----------------------------------------------------------------------------------------+{x\n\r"); if (count > 0) page_to_char(output->string, ch); else send_to_char("There are no current clan members.\n\r", ch); free_buf(output); } else if (!str_prefix(arg, "trust")) { int trust; if (argument[0] == '\0') { send_to_char("Who would you like to trust?\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (argument[0] == '\0') { if (IS_IMMORTAL( ch )) send_to_char( "Valid trust levels are {Rleader{x, {Rvice{x and {Rmember{x.\n\r", ch); else send_to_char( "Valid trust levels are {Rvice{x and {Rmember{x.\n\r", ch); return FALSE; } else if (!str_prefix(argument, "leader") && IS_IMMORTAL( ch )) trust = TRUST_LDR; else if (!str_prefix(argument, "vice")) trust = TRUST_VLR; else if (!str_prefix(argument, "member")) trust = TRUST_MEMBER; else return cedit_member(ch, "trust a "); for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (roster->clan == clan && !str_prefix(arg, roster->name)) break; } if (!roster) { send_to_char("Player not found.\n\r", ch); return FALSE; } else if (roster == chRoster) { send_to_char("You trust yourself enough... or do you?\n\r", ch); return FALSE; } if (IS_SET( roster->flags, ROST_EXILE_GRACE )) { send_to_char("They have been marked for exile.\n\r", ch); return FALSE; } roster->trust = trust; send_to_char("Trust level changed.\n\r", ch); sprintf(buf, "{R%s{w trusted to {R%s", roster->name, trust == TRUST_VLR ? "vice-leader" : trust == TRUST_LDR ? "leader" : "member"); append_clan_log(clan, ENTRY_TRUST, ch->name, buf); strcat(buf, "{x\n\r"); send_to_char(buf, ch); } else if (!str_cmp(arg, "exile")) { char p_name[MAX_INPUT_LENGTH]; int grace; argument = one_argument(argument, p_name); if (p_name[0] == '\0') { send_to_char("Please provide a player name.\n\r", ch); return FALSE; } if (!str_cmp(argument, "none")) grace = 0; else if (is_number(argument)) { grace = atoi(argument); if (grace <= 0) { send_to_char( "Please specify a number of days grace over 0, or type {Rnone{x if you don't want to give any.\n\r", ch); return FALSE; } else if (grace >= 7) { send_to_char( "The number of days grace must be less than a week.\n\r", ch); return FALSE; } } else { send_to_char( "Please specify the grace period in days or type {Rnone{x.\n\r", ch); return FALSE; } for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (roster->clan == clan && !str_cmp(roster->name, p_name)) break; } if (!roster) { send_to_char("Player not found.\n\r", ch); return FALSE; } else if (roster == chRoster) { send_to_char("You can't exile yourself.\n\r", ch); return FALSE; } if (IS_SET( roster->flags, ROST_EXILE_GRACE )) { send_to_char("They have already been marked for exile.\n\r", ch); return FALSE; } if (grace > 0) { REMOVE_BIT( roster->flags, ROST_INACTIVE ); SET_BIT( roster->flags, ROST_EXILE_GRACE ); roster->penalty_time = current_time + (grace * TIME_DAY); roster->trust = TRUST_ALL; // Won't get to wear clan eq or make clan donations sprintf( buf, "%s will be exiled in %d days if they do not leave voluntarily.\n\r", roster->name, grace); send_to_char(buf, ch); if (roster->character) { sprintf( buf, "{Y>{y>{Y>{R You must voluntarily leave the clan within{W %d {Rdays or you will be exiled. {Y<{y<{Y<{x\n\r", grace); send_to_char(buf, ch); send_to_char( "Use the {Gloner{x command to leave the clan. You will lose fewer donation points if you do so.\n\r", ch); } sprintf( buf, "{R%s{w marked for exile with grace period set at {R%d{w days.", roster->name, grace); } else { sprintf(buf, "%s has been exiled from the clan.\n\r", roster->name); send_to_char(buf, ch); sprintf(buf, "{R%s{w exiled with {Rno{w grace period set.", roster->name); exile_player(roster); } append_clan_log(clan, ENTRY_EXILE, ch->name, buf); } else { cedit_member(ch, ""); return FALSE; } return TRUE; } CEDIT_FUN( cedit_mob ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH]; int i; EDIT_CLAN( ch, clan ); if (clan->independent) { send_to_char("Only proper clans may have assets.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: mob edit <type> - edit the specified mob(e.g. blacksmith)\n\r" " mob buy <item> - buy a mob\n\r" " mob req <item> - find out what the mob needs and costs to buy\n\r" " mob list - list the available mobs for sale\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (arg[0] == '\0') { cedit_mob(ch, ""); return FALSE; } if (!str_prefix(arg, "edit")) { for (i = 0; i < CMOB_MAX; i++) if (!str_prefix(argument, cmob_table[i].name)) break; if (i == CMOB_MAX) { send_to_char("Mobile type not found.\n\r", ch); return FALSE; } if (clan->cMob[i] == NULL) { send_to_char("The clan does not have that type of mobile.\n\r", ch); return FALSE; } SET_EDIT_ITEM( ch, clan->cMob[i] ); SET_EDIT_TYPE( ch, ED_MCEDIT ); } else if (!str_prefix(arg, "buy")) return upgrade_process(ch, argument, mob_prices, TRUE ); else if (!str_prefix(arg, "list")) { upgrade_list_table(ch, mob_prices); return FALSE; } else if (!str_prefix(arg, "req")) return upgrade_process(ch, argument, mob_prices, FALSE ); else cedit_mob(ch, ""); return FALSE; } CEDIT_FUN( cedit_name ) { CLAN_DATA *clan; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH], *string; EDIT_CLAN( ch, clan ); if (!IS_IMMORTAL( ch ) && clan->edit_time < current_time) { send_to_char( "You do not have anymore time to edit ranks. Use {Rtime buy{x to buy more time.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: name <clan who name> - set the clan who name\n\r", ch); if (IS_IMMORTAL( ch )) send_to_char( " name fix <non-colour name> - set the keyword name if autogeneration from the who name goes bad\n\r", ch); return FALSE; } one_argument(argument, arg); if (IS_IMMORTAL( ch ) && !str_cmp(arg, "fix")) { argument = one_argument(argument, arg); if (argument[0] == '\0') { cedit_name(ch, ""); return FALSE; } string = strip_spec_char_col(argument); string = strip_spaces(string); if (strlen(string) > MAX_CLAN_WHO_LENGTH) { sprintf( buf, "Clan keyword names cannot be longer than %d characters(not including colours).\n\r", MAX_CLAN_WHO_LENGTH ); send_to_char(buf, ch); return FALSE; } free_string(clan->name); clan->name = str_dup(string); sprintf(buf, "Clan keyword name changed to {R%s{x\n\r", string); send_to_char(buf, ch); append_clan_log(clan, ENTRY_CHANGED, ch->name, buf); return TRUE; } if (strlen_color(argument) > MAX_CLAN_WHO_LENGTH) { sprintf( buf, "Clan who names cannot be longer than %d characters(not including colours).\n\r", MAX_CLAN_WHO_LENGTH ); send_to_char(buf, ch); return FALSE; } string = strip_spec_char_col(argument); string = strip_spaces(string); free_string(clan->c_name); clan->c_name = str_dup(argument); free_string(clan->name); clan->name = str_dup(string); sprintf(buf, "Clan name changed to %s{x, keyword name auto-changed to {R%s{x.", strip_bespaces(clan->c_name), clan->name); append_clan_log(clan, ENTRY_CHANGED, ch->name, buf); strcat(buf, "\n\r"); send_to_char(buf, ch); return TRUE; } CEDIT_FUN( cedit_obj ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; char arg[MAX_INPUT_LENGTH]; int vnum; EDIT_CLAN( ch, clan ); if (clan->independent) { send_to_char("Only proper clans may have assets.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: obj edit <number> - edit the specified obj vnum\n\r" " obj buy <item> - buy a obj\n\r" " obj req <item> - find out what the obj needs and costs to buy\n\r" " obj list - list the available objs for sale\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (arg[0] == '\0') { cedit_obj(ch, ""); return FALSE; } if (!str_prefix(arg, "edit")) { if (!is_number(argument)) { cedit_obj(ch, ""); return FALSE; } vnum = atoi(argument); if ((pObj = get_obj_index(vnum)) == NULL) { send_to_char("Object not found.\n\r", ch); return FALSE; } if (!is_full_clan_obj_index(pObj, clan, TRUE )) { send_to_char("Object not found.\n\r", ch); return FALSE; } SET_EDIT_ITEM( ch, pObj ); // in edit part of function SET_EDIT_TYPE( ch, ED_OCEDIT ); } else if (!str_prefix(arg, "buy")) return upgrade_process(ch, argument, obj_prices, TRUE ); else if (!str_prefix(arg, "list")) { upgrade_list_table(ch, obj_prices); return FALSE; } else if (!str_prefix(arg, "req")) return upgrade_process(ch, argument, obj_prices, FALSE ); else cedit_obj(ch, ""); return FALSE; } CEDIT_FUN( cedit_petition ) { CLAN_DATA *clan; ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH], arg[MAX_STRING_LENGTH]; ; int count = 0; bool fAccept = FALSE, fReject = FALSE; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "Cedit syntax: petition list - lists current petitions.\n\r" " petition accept <number/name> - accept petition.\n\r" " petition reject <number/name> - reject petition.\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!str_prefix(arg, "list")) { BUFFER *output = new_buf(); for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (roster->petition != clan) continue; count++; sprintf(buf, "{R%3d{B){w %10s {B- {w%6ld KP\n\r", count, roster->name, roster->pkilldata->kPoints); add_buf(output, buf); } add_buf(output, "{x"); if (count > 0) send_to_char(output->string, ch); else send_to_char("There are no current petitions.\n\r", ch); free_buf(output); return TRUE; } if (!str_prefix(arg, "accept")) fAccept = TRUE; else if (!str_prefix(arg, "reject")) fReject = TRUE; if (fAccept || fReject) { int numArg = 0; if (fAccept && ((clan->pkill && clan->members >= MAX_PK_CLAN_MEMBERS) || (!clan->pkill && clan->members >= MAX_NONPK_CLAN_MEMBERS)) && !clan->independent) { send_to_char("You have enough members already!\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Please specify the petition number or name of the person.\n\r", ch); return FALSE; } if (is_number(argument)) numArg = atoi(argument); for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (roster->petition != clan) continue; count++; if (numArg == count || !str_prefix(argument, roster->name)) { roster->petition = NULL; if (fAccept) { if (roster->clan && !roster->clan->independent) roster->clan->members--; roster->clan = clan; roster->trust = TRUST_MEMBER; (clan->members)++; send_to_char("Petition accepted.\n\r", ch); if (roster->character) // Notify player if online { sprintf( buf, "{GCongratulations! You are now a member of clan %s{G!{x\n\r", strip_bespaces(clan->c_name)); send_to_char(buf, roster->character); } sprintf(buf, "{R%s{w is granted clan membership.", roster->name); append_clan_log(clan, ENTRY_ACCEPT, ch->name, buf); } else { send_to_char("Petition rejected.\n\r", ch); if (roster->character) // Notify player if online { sprintf( buf, "{RYour petition to clan %s{R for membership was rejected.{x\n\r", strip_bespaces(clan->c_name)); send_to_char(buf, roster->character); } } return TRUE; } } send_to_char("Petition request not found.\n\r", ch); return FALSE; } cedit_petition(ch, ""); return FALSE; } CEDIT_FUN( cedit_pkill ) { CLAN_DATA *clan; EDIT_CLAN( ch, clan ); if (clan->id == CLAN_NONE || clan->id == CLAN_LONER || clan->id == CLAN_PK_OUTCAST || clan->id == CLAN_NONPK_OUTCAST || clan->id == CLAN_IMMORTAL) { send_to_char("This cannot be changed.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: pkill yes/no - sets the clan as a pkill clan or not\n\r", ch); return FALSE; } else if (!str_cmp(argument, "yes")) { clan->pkill = TRUE; send_to_char("Clan made pkill.\n\r", ch); } else if (!str_cmp(argument, "no")) { clan->pkill = FALSE; send_to_char("Clan is no longer a pkill clan.\n\r", ch); } else { cedit_pkill(ch, ""); return FALSE; } return TRUE; } CEDIT_FUN( cedit_rank ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH], r_name[MAX_STRING_LENGTH]; int rank; EDIT_CLAN( ch, clan ); if (!IS_IMMORTAL( ch ) && clan->edit_time < current_time) { send_to_char( "You do not have anymore time to edit ranks. Use {Rtime buy{x to buy more time.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: rank <rank number> who <name> - sets the who name of the rank\n\r" " rank <rank number> name <name> - sets the full name of the rank\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!is_number(arg)) { send_to_char("Please specify a numerical rank.\n\r", ch); return FALSE; } rank = atoi(arg); if (rank < 0 || rank > TOTAL_CLAN_RANK) { send_to_char("Please specify a valid rank number.\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!str_cmp(arg, "who")) { strcpy(r_name, strip_spaces(argument)); if (strlen_color(r_name) > 3) { send_to_char( "Rank who names must not be longer than 3 characters(without colours).\n\r", ch); return FALSE; } free_string(clan->r_who[rank]); clan->r_who[rank] = str_dup(r_name); sprintf(r_name, "Rank {R%d{x who name changed to %s{x.", rank, clan->r_who[rank]); append_clan_log(clan, ENTRY_CHANGED, ch->name, r_name); strcat(r_name, "\n\r"); send_to_char(r_name, ch); } else if (!str_cmp(arg, "name")) { if (strlen_color(argument) > MAX_CLAN_RANK_LENGTH) { sprintf( r_name, "Full rank names must not exceed %d characters(without colours).\n\r", MAX_CLAN_RANK_LENGTH ); send_to_char(r_name, ch); return FALSE; } free_string(clan->r_name[rank]); clan->r_name[rank] = str_dup(argument); sprintf(r_name, "Rank {R%d{x full name changed to %s{x.", rank, clan->r_name[rank]); append_clan_log(clan, ENTRY_CHANGED, ch->name, r_name); strcat(r_name, "\n\r"); send_to_char(r_name, ch); } else { cedit_rank(ch, ""); return FALSE; } return TRUE; } CEDIT_FUN( cedit_room ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH]; int i; EDIT_CLAN( ch, clan ); if (clan->independent) { send_to_char("Only proper clans may have assets.\n\r", ch); return FALSE; } if (argument[0] == '\0') { send_to_char( "Cedit syntax: room edit <type> - edit the specified room(e.g. smithy)\n\r" " room buy <item> - buy a room\n\r" " room req <item> - find out what the room needs and costs to buy\n\r" " room list - list the available rooms for sale\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (arg[0] == '\0') { cedit_room(ch, ""); return FALSE; } if (!str_prefix(arg, "edit")) { for (i = 0; i < CROOM_MAX; i++) if (!str_prefix(argument, croom_table[i].name)) break; if (i == CROOM_MAX) { send_to_char("Room type not found.\n\r", ch); return FALSE; } if (clan->cRoom[i] == NULL) { send_to_char("The clan does not have that type of room.\n\r", ch); return FALSE; } SET_EDIT_ITEM( ch, clan->cRoom[i] ); SET_EDIT_TYPE( ch, ED_RCEDIT ); } else if (!str_prefix(arg, "buy")) return upgrade_process(ch, argument, room_prices, TRUE ); else if (!str_prefix(arg, "list")) { upgrade_list_table(ch, room_prices); return FALSE; } else if (!str_prefix(arg, "req")) return upgrade_process(ch, argument, room_prices, FALSE ); else cedit_room(ch, ""); return FALSE; } CEDIT_FUN( cedit_show ) { BUFFER *output = new_buf(); CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; char buf[MAX_STRING_LENGTH], borderbuf[MAX_STRING_LENGTH], *temp, temp2[MAX_STRING_LENGTH]; int i, time; bool found; EDIT_CLAN( ch, clan ); add_buf( output, "{B+- {GCEDIT MAIN {B-----------------------------------------------------------+\n\r"); sprintf(buf, "{WUID: {R%d", clan->id); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); sprintf(buf, "{WMembers:{w %2d {WPKill: %s {WIndependent: {w%s", clan->members, clan->pkill ? "{ryes" : "{wno", clan->independent ? "yes" : "no"); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); if (IS_IMMORTAL( ch )) { sprintf(buf, "{WLower clan vnum: {w%7d {WUpper clan vnum: {w%7d", clan->vnum[0], clan->vnum[1]); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (clan->enemy) { sprintf(buf, "{WClan enemy: {x%s", strip_bespaces(clan->enemy->c_name)); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (clan->Penemy.data) { sprintf(buf, "{WClan petitioned to be enemy: {x%s", strip_bespaces( clan->Penemy.data->c_name)); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } time = (clan->edit_time - current_time) / TIME_MINUTE; if (time > 0) { sprintf( buf, "{B|-{G Basic data ({R%4d {gminutes editing time{G){B -------------------------------|\n\r", time); add_buf(output, buf); } else add_buf( output, "{B|-{G Basic data {B-----------------------------------------------------------|\n\r"); sprintf(borderbuf, "%s", end_string(clan->c_name, MAX_CLAN_WHO_LENGTH )); sprintf(buf, "{W Clan name:{B [{w%s{B] {W Clan who name: {B[{x%s{B]", end_string(clan->name, MAX_CLAN_WHO_LENGTH ), borderbuf); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); for (i = (TOTAL_CLAN_RANK - 1); i >= 0; i--) { sprintf(borderbuf, "%s", end_string(clan->r_who[i], 3)); sprintf(buf, "{W Rank {w%d {B[{x%s{B] [{x%s{B] {w%6d {WPoints", i, borderbuf, end_string(clan->r_name[i], MAX_CLAN_RANK_LENGTH ), clan_rank_table[i].points); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } for (temp = clan->description, i = 0; *temp; i++, temp++) { if ((*temp == '\n' && *(temp + 1) == '\r') || (*temp == '\r' && *(temp + 1) == '\n')) { temp2[i] = ' '; temp++; continue; } else if (*temp == '\n' || *temp == '\r') { temp2[i] = ' '; continue; } temp2[i] = *temp; } temp2[i] = '\0'; temp = temp2; temp = length_argument(temp, borderbuf, 55); sprintf(buf, " {WDescription: {w%s", borderbuf); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); while (*temp != '\0') { temp = length_argument(temp, buf, 55); sprintf(borderbuf, "{B| {w%s {B|\n\r", end_string(buf, 55)); add_buf(output, borderbuf); } add_buf( output, "{B|-{G Funds {B----------------------------------------------------------------|\n\r"); sprintf(buf, "{W Platinum: {w%8ld {WQuest points: {w%8ld", clan->platinum, clan->qps); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); add_buf( output, "{B|-{G Skills {B---------------------------------------------------------------|\n\r"); for (found = FALSE, i = 0; i < 2; i++) { if (clan->skills[i] < 0) continue; found = TRUE; sprintf(buf, "{x %s {W: %s {B-{w %s", end_string( clan_skill_table[clan->skills[i]].name, 21), clan_skill_table[clan->skills[i]].major ? "{CMajor" : "{cMinor", clan->r_name[get_p_rank_index(clan_skill_table[clan->skills[i]].points)]); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (!found) add_buf( output, "{B| {wNone. {B|\n\r"); add_buf( output, "{B|-{G Rooms {B----------------------------------------------------------------|\n\r"); for (found = FALSE, i = 0; i < CROOM_MAX; i++) { if (clan->cRoom[i] == NULL) continue; found = TRUE; sprintf(buf, "{W %-22.22s: {B%s", capitalize(croom_table[i].name), clan->cRoom[i]->name); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (!found) add_buf( output, "{B| {wNone. {B|\n\r"); add_buf( output, "{B|-{G Mobs {B-----------------------------------------------------------------|\n\r"); for (found = FALSE, i = 0; i < CMOB_MAX; i++) { if (clan->cMob[i] == NULL) continue; found = TRUE; sprintf(buf, "{W L{C%3d{W %-17.17s: {x%s", clan->cMob[i]->level, capitalize(cmob_table[i].name), clan->cMob[i]->short_descr); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (!found) add_buf( output, "{B| {wNone. {B|\n\r"); add_buf( output, "{B|-{G Objects {B--------------------------------------------------------------|\n\r"); for (found = FALSE, i = clan->vnum[0]; i <= clan->vnum[1]; i++) { if ((pObj = get_obj_index(i)) == NULL) continue; found = TRUE; sprintf(buf, " {W{R%-5d{W %-16.16s: {x%s", i, capitalize(flag_string( type_flags, pObj->item_type)), pObj->short_descr); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } if (!found) add_buf( output, "{B| {wNone. {B|\n\r"); add_buf( output, "{B+------------------------------------------------------------------------+{x\n\r"); page_to_char(output->string, ch); free_buf(output); return FALSE; } CEDIT_FUN( cedit_skill ) { SET_EDIT_TYPE( ch, ED_SCEDIT ); scedit_show(ch, argument); return TRUE; } CEDIT_FUN( cedit_time ) { CLAN_DATA *clan; char buf[MAX_STRING_LENGTH]; int time; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "Cedit syntax: time buy - buy another 30 minutes editing time for clan data\n\r" " time status - see how long you have left to edit basic clan data\n\r" " Note: another 30 minutes will cost 300 platinum.\n\r", ch); return FALSE; } else if (!str_prefix(argument, "buy")) { if (clan->platinum < 300) { send_to_char( "You cannot afford another 30 minutes of editing time.\n\r", ch); return FALSE; } clan->platinum -= 300; append_clan_log(clan, ENTRY_UPGRADE, ch->name, "Editing time purchased: {R300 {CP{clatinum."); clan->edit_time = ((clan->edit_time < current_time) ? current_time : clan->edit_time) + (30 * TIME_MINUTE); send_to_char( "You have another {R30{x minutes to edit your clan name, description and ranks.\n\r", ch); return TRUE; } else if (!str_prefix(argument, "status")) { time = (clan->edit_time - current_time) / TIME_MINUTE; if (time <= 0) strcpy( buf, "You do not have any more time remaining to edit your clan name, description and ranks. Use {Rtime buy{x to buy more.\n\r"); else sprintf( buf, "You have %d minutes remaining to edit your clan name, description and ranks.\n\r", time); send_to_char(buf, ch); return FALSE; } cedit_time(ch, ""); return FALSE; } CEDIT_FUN( cedit_war ) { CLAN_DATA *clan, *warClan; DESCRIPTOR_DATA *d; ROSTER_DATA *roster, *chRoster; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH], temp[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); GET_ROSTER( ch, chRoster ); if (argument[0] == '\0') { send_to_char( "Cedit syntax: war declare <clan name> - declare war on a clan (must be accepted by them)\n\r" " war cancel - end a war with a clan or cancel a request\n\r" " war status - see who you are at war at or who you have petitioned or who have petitioned you\n\r" " war accept <clan name> - accept a declaration of war\n\r", ch); return FALSE; } argument = one_argument(argument, arg); if (!str_prefix(arg, "declare")) { if (argument[0] == '\0') { cedit_war(ch, ""); return FALSE; } if ((warClan = get_clan_by_name(argument)) == NULL) { send_to_char("The clan you specified was not found.\n\r", ch); return FALSE; } if (clan == warClan) { send_to_char("Do you really hate your clan that much?\n\r", ch); return FALSE; } if (clan->independent) { send_to_char("Only proper clans may wage war.\n\r", ch); return FALSE; } if (warClan->independent) { send_to_char("You can only declare war on proper clans.\n\r", ch); return FALSE; } if (clan->pkill && !warClan->pkill) { send_to_char( "You can only declare war on player-killing clans.\n\r", ch); return FALSE; } if (!clan->pkill && warClan->pkill) { send_to_char( "You can only declare war on a non-player-killing clan.\n\r", ch); return FALSE; } if (clan->Penemy.data) { sprintf(buf, "You have already petitioned %s{x for war.\n\r", strip_bespaces(clan->Penemy.data->c_name)); return FALSE; } if (clan->enemy) { sprintf(buf, "You are already at war with %s{x.\n\r", strip_bespaces(clan->enemy->c_name)); send_to_char(buf, ch); return FALSE; } if (warClan->enemy) { strcpy(temp, strip_bespaces(warClan->enemy->c_name)); sprintf(buf, "%s{x is already at war with %s{x.\n\r", strip_bespaces(warClan->c_name), temp); send_to_char(buf, ch); return FALSE; } clan->Penemy.data = warClan; sprintf( buf, "%s{x has petitioned for war against your clan. Use {Rwar accept{x in {Rcedit{x to accept.\n\r", strip_bespaces(clan->c_name)); for (roster = roster_list; roster != NULL; roster = roster->next) { if (roster->clan != warClan || roster->character == NULL) continue; send_to_char(buf, roster->character); } sprintf(buf, "War requested against %s{x.", strip_bespaces( warClan->c_name)); append_clan_log(clan, ENTRY_WAR, ch->name, buf); sprintf(buf, "Request for war received from %s{x.", strip_bespaces( clan->c_name)); append_clan_log(warClan, ENTRY_WAR, ch->name, buf); strcat(buf, "\n\r"); send_to_char(buf, ch); return TRUE; } else if (!str_prefix(arg, "cancel")) { if (clan->Penemy.data != NULL) { send_to_char("Petition cancelled.\n\r", ch); sprintf(buf, "War request against %s{x withdrawn.\n\r", strip_bespaces(clan->Penemy.data->c_name)); clan->Penemy.data = NULL; append_clan_log(clan, ENTRY_WAR, ch->name, buf); return FALSE; } else if ((warClan = clan->enemy) == NULL) { send_to_char("This clan doesn't have an enemy at the moment.\n\r", ch); return FALSE; } send_to_char("War cancelled.\n\r", ch); clan->enemy = NULL; warClan->enemy = NULL; strcpy(temp, strip_bespaces(warClan->c_name)); sprintf( buf, "{c>{C>{c>{C PEACE {c>{C>{c> {WThe war between clan {x%s{W and clan {x%s{W has ended.{x\n\r", strip_bespaces(clan->c_name), temp); for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected != CON_PLAYING || d->character == NULL || IS_SET( d->character->comm, COMM_QUIET )) continue; send_to_char(buf, d->character); } sprintf(buf, "War ended against %s{x.", strip_bespaces(warClan->c_name)); append_clan_log(clan, ENTRY_WAR, ch->name, buf); sprintf(buf, "War ended against %s{x.", strip_bespaces(clan->c_name)); append_clan_log(warClan, ENTRY_WAR, ch->name, buf); strcat(buf, "\n\r"); send_to_char(buf, ch); return TRUE; } else if (!str_prefix(arg, "status")) { BUFFER *output; bool found = FALSE, pfound = FALSE; if (clan->enemy) { sprintf(buf, "Currently at war with: %s{x\n\r", strip_bespaces( clan->enemy->c_name)); send_to_char(buf, ch); return FALSE; } output = new_buf(); if (clan->Penemy.data) { sprintf(buf, "Currently petitioning for war: %s{x\n\r", strip_bespaces(clan->Penemy.data->c_name)); add_buf(output, buf); pfound = TRUE; } for (warClan = clan_list; warClan != NULL; warClan = warClan->next) { if (warClan->Penemy.data == NULL || warClan->Penemy.data != clan) continue; if (!found) add_buf(output, "Current petitions for war by: "); found = TRUE; add_buf(output, strip_bespaces(warClan->c_name)); add_buf(output, "\n\r {x"); } if (found || pfound) page_to_char(output->string, ch); else send_to_char("Nothing going on here at the moment.\n\r", ch); free_buf(output); } else if (!str_prefix(arg, "accept")) { CLAN_DATA *checkClan; if (argument[0] == '\0') { send_to_char( "Please specify the name of the clan you would like to accept that has petitioned your clan for war.\n\r", ch); return FALSE; } if ((warClan = get_clan_by_name(argument)) == NULL) { send_to_char("The clan you specified was not found.\n\r", ch); return FALSE; } if (warClan->Penemy.data == NULL || warClan->Penemy.data != clan) { send_to_char("That clan hasn't petitioned for war with you.\n\r", ch); return FALSE; } clan->Penemy.data = NULL; warClan->Penemy.data = NULL; clan->enemy = warClan; warClan->enemy = clan; strcpy(temp, strip_bespaces(warClan->c_name)); sprintf( buf, "{r>{R>{r>{R WAR {r>{R>{r> {GWar has broken out between clan {x%s{G and clan {x%s{G!{x\n\r", strip_bespaces(clan->c_name), temp); for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected != CON_PLAYING || d->character == NULL || IS_SET( d->character->comm, COMM_QUIET )) continue; send_to_char(buf, d->character); } for (checkClan = clan_list; checkClan != NULL; checkClan = checkClan->next) { if (checkClan->Penemy.data == NULL || (checkClan->Penemy.data != clan && checkClan->Penemy.data != warClan)) continue; checkClan->Penemy.data = NULL; } sprintf(buf, "War started against %s{x.", strip_bespaces( warClan->c_name)); append_clan_log(clan, ENTRY_WAR, ch->name, buf); sprintf(buf, "War started against %s{x.", strip_bespaces(clan->c_name)); append_clan_log(warClan, ENTRY_WAR, ch->name, buf); save_clan_data(warClan); return TRUE; } else cedit_war(ch, ""); return FALSE; } CEDIT_FUN( mcedit_buy ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH], whole_arg[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "MCedit syntax: buy <item> - buy a mob upgrade for the current mob\n\r" " buy list - show the possible upgrades available\n\r" " buy req <item> - find out what the mob upgrade needs and costs to buy\n\r", ch); return FALSE; } strcpy(whole_arg, argument); argument = one_argument(argument, arg); if (!str_cmp(arg, "list")) { upgrade_list_table(ch, mob_upgd_prices); return FALSE; } else if (!str_cmp(arg, "req")) return (upgrade_process(ch, argument, mob_upgd_prices, FALSE )); else return (upgrade_process(ch, whole_arg, mob_upgd_prices, TRUE )); } CEDIT_FUN( mcedit_desc ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { string_append(ch, &pMob->description); return TRUE; } send_to_char( "MCedit syntax: desc - set the description (the one you see when you look at the mob)\n\r", ch); return FALSE; } CEDIT_FUN( mcedit_long ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { send_to_char( "MCedit syntax: long <long description> - set the long description (the one you see when you are in a room with it and type look)\n\r" " {RNote:{x If you put in %s, it will be replaced by your clan colour name (saves typing).\n\r", ch); return FALSE; } if (strlen_color(argument) < 8) { send_to_char( "Provide a reasonable length long description please.\n\r", ch); return FALSE; } free_string(pMob->long_descr); str_replace_c(argument, "%s", strip_bespaces(clan->c_name)); strcat(argument, "\n\r"); pMob->long_descr = str_dup(argument); sprintf(buf, "Mob long description changed to: %s{x", pMob->long_descr); send_to_char(buf, ch); return TRUE; } CEDIT_FUN( mcedit_short ) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; char name[MAX_STRING_LENGTH]; int length; EDIT_CLAN( ch, clan ); EDIT_MOB( ch, pMob ); if (argument[0] == '\0') { send_to_char( "MCedit syntax: short <short description> - set the short description (the one you see when you interact with the mob)\n\r" " {RNote:{x If you put in %s, it will be replaced by your clan colour name (saves typing).\n\r", ch); return FALSE; } if ((length = strlen_color(argument)) < 5 || length > 70) { send_to_char( "Provide a reasonable length short description please.\n\r", ch); return FALSE; } str_replace_c(argument, "%s{x", strip_bespaces(clan->c_name)); free_string(pMob->short_descr); pMob->short_descr = str_dup(argument); str_replace_c(argument, strip_bespaces(clan->c_name), clan->name); strcpy(name, process_name(argument)); if (str_infix(clan->name, name)) { if (name[strlen(name) - 1] != ' ') strcat(name, " "); strcat(name, clan->name); } free_string(pMob->player_name); pMob->player_name = str_dup(name); sprintf(name, "Mob short description changed to: %s{x\n\r", pMob->short_descr); send_to_char(name, ch); sprintf(name, "Mob name (keywords) automatically changed to: %s\n\r", pMob->player_name); send_to_char(name, ch); return TRUE; } CEDIT_FUN( mcedit_show ) { BUFFER *output = new_buf(); MOB_INDEX_DATA *pMob; char buf[MAX_STRING_LENGTH]; EDIT_MOB( ch, pMob ); sprintf(buf, "{WKeyword name: {B[{w%s{B]\n\r", pMob->player_name); add_buf(output, buf); sprintf(buf, "{WLevel {B[{R%d{B]\n\r", pMob->level); add_buf(output, buf); sprintf(buf, "{WHitpoints: {B[{G%d{B]\n\r", pMob->hit[DICE_BONUS]); add_buf(output, buf); sprintf(buf, "{WMana: {B[{M%d{B]\n\r", pMob->mana[DICE_BONUS]); add_buf(output, buf); sprintf(buf, "{WDamage: {B[{C%d{B]\n\r", pMob->damage[DICE_BONUS]); add_buf(output, buf); sprintf(buf, "{WDamage type: {B[{w%s{B]\n\r", attack_table[pMob->dam_type].name); add_buf(output, buf); sprintf(buf, "{WOffensive bits: {B[{w%s{B]\n\r", flag_string(off_flags, pMob->off_flags)); add_buf(output, buf); sprintf(buf, "{WImmunity bits: {B[{w%s{B]\n\r", flag_string(imm_flags, pMob->imm_flags)); add_buf(output, buf); sprintf(buf, "{WResistance bits: {B[{w%s{B]\n\r", flag_string(res_flags, pMob->res_flags)); add_buf(output, buf); sprintf(buf, "{WEffect bits: {B[{w%s %s{B]\n\r", flag_string( affect_flags, pMob->affected_by), pMob->shielded_by == 0 ? "" : flag_string(shield_flags, pMob->shielded_by)); add_buf(output, buf); sprintf(buf, "{WAC values: {B[{WPierce{B:{w %d{B]\n\r", pMob->ac[0]); add_buf(output, buf); sprintf(buf, " {B[{WSlash{B:{w %d{B]\n\r", pMob->ac[1]); add_buf(output, buf); sprintf(buf, " {B[{WBash{B:{w %d{B]\n\r", pMob->ac[2]); add_buf(output, buf); sprintf(buf, " {B[{WExotic{B:{w %d{B]\n\r", pMob->ac[3]); add_buf(output, buf); sprintf(buf, "{WShort descr: {B[{x%s{B]\n\r", pMob->short_descr); add_buf(output, buf); sprintf(buf, "{WLong descr:\n\r {x%s{x", pMob->long_descr); add_buf(output, buf); sprintf(buf, "{WDescription:\n\r{x %s\n\r", pMob->description); add_buf(output, buf); page_to_char(output->string, ch); free_buf(output); return FALSE; } CEDIT_FUN( ocedit_buy ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH], whole_arg[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "OCedit syntax: buy <item> - buy a obj upgrade for the current obj\n\r" " buy list - show the possible upgrades available\n\r" " buy req <item> - find out what the obj upgrade needs and costs to buy\n\r", ch); return FALSE; } strcpy(whole_arg, argument); argument = one_argument(argument, arg); if (!str_cmp(arg, "list")) { upgrade_list_table(ch, obj_upgd_prices); return FALSE; } else if (!str_cmp(arg, "req")) return (upgrade_process(ch, argument, obj_upgd_prices, FALSE )); else return (upgrade_process(ch, whole_arg, obj_upgd_prices, TRUE )); } CEDIT_FUN( ocedit_long ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); if (argument[0] == '\0') { send_to_char( "OCedit syntax: long <long description> - set the long description (the one you see when you are in a room with it and type look)\n\r" " {RNote:{x If you put in %s, it will be replaced by your clan colour name (saves typing).\n\r", ch); return FALSE; } if (strlen_color(argument) < 8) { send_to_char( "Provide a reasonable length long description please.\n\r", ch); return FALSE; } free_string(pObj->description); str_replace_c(argument, "%s", strip_bespaces(clan->c_name)); // strcat( argument, "\n\r" ); pObj->description = str_dup(argument); sprintf(buf, "Obj long description changed to: %s{x", pObj->description); send_to_char(buf, ch); return TRUE; } CEDIT_FUN( ocedit_sell ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); send_to_char("Out of order, sorry!\n\r", ch); return FALSE; } CEDIT_FUN( ocedit_short ) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; char name[MAX_STRING_LENGTH]; int length; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); if (argument[0] == '\0') { send_to_char( "OCedit syntax: short <short description> - set the short description (the one you see when you interact with the object)\n\r" " {RNote:{x If you put in %s, it will be replaced by your clan colour name (saves typing).\n\r", ch); return FALSE; } if ((length = strlen_color(argument)) < 5 || length > 70) { send_to_char( "Provide a reasonable length short description please.\n\r", ch); return FALSE; } str_replace_c(argument, "%s{x", strip_bespaces(clan->c_name)); free_string(pObj->short_descr); pObj->short_descr = str_dup(argument); str_replace_c(argument, strip_bespaces(clan->c_name), clan->name); strcpy(name, process_name(argument)); if (str_infix(clan->name, name)) { if (name[strlen(name) - 1] != ' ') strcat(name, " "); strcat(name, clan->name); } free_string(pObj->name); pObj->name = str_dup(name); sprintf(name, "Obj short description changed to: %s{x\n\r", pObj->short_descr); send_to_char(name, ch); sprintf(name, "Obj name (keywords) automatically changed to: %s\n\r", pObj->name); send_to_char(name, ch); return TRUE; } CEDIT_FUN( ocedit_show ) { AFFECT_DATA *paf; BUFFER *output = new_buf(); CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); EDIT_OBJ( ch, pObj ); sprintf(buf, "{WKeyword name: {B[{w%s{B]\n\r", pObj->name); add_buf(output, buf); sprintf(buf, "{WLevel {B[{R%d{B]\n\r", pObj->level); add_buf(output, buf); sprintf(buf, "{WType: {B[{w%s{B]\n\r", flag_string(type_flags, pObj->item_type)); add_buf(output, buf); sprintf(buf, "{WWear locations: {B[{w%s{B]\n\r", flag_string(wear_flags, pObj->wear_flags)); add_buf(output, buf); sprintf(buf, "{WObject flags: {B[{w%s{B]\n\r", flag_string(extra_flags, pObj->extra_flags)); add_buf(output, buf); sprintf(buf, "{WShort Descr: {B[{w%s{B]\n\r", pObj->short_descr); add_buf(output, buf); sprintf(buf, "{WLong Descr: {B[{w%s{B]\n\r\n\r", pObj->description); add_buf(output, buf); switch (pObj->item_type) // Lazy so I used Asgard's obj value stuff, just stripped down a bit { default: /* No values. */ break; case ITEM_LIGHT: if (pObj->value[2] == -1 || pObj->value[2] == 999) /* ROM OLC */ strcpy(buf, "{WLight: {GInfinite\n\r"); else sprintf(buf, "{WLight: {B[{R%d{B]\n\r", pObj->value[2]); add_buf(output, buf); break; case ITEM_WAND: case ITEM_STAFF: sprintf(buf, "{WLevel: {B[{R%d{B]\n\r" "{WCharges Total: {B[{R%d{B]\n\r" "{WSpell: {B[{w%s{B]\n\r\n\r", pObj->value[0], pObj->value[1], pObj->value[3] != -1 ? skill_table[pObj->value[3]].name : "none"); add_buf(output, buf); break; case ITEM_PORTAL: sprintf(buf, "{WCharges: {B[{R%d{B]\n\r" "{WExit Flags: {B[{w%s{B]\n\r" "{WPortal Flags: {B[{w%s{B]\n\r" "{WGoes to (area): {B[{w%s{B]\n\r\n\r", pObj->value[0], flag_string(exit_flags, pObj->value[1]), flag_string( portal_flags, pObj->value[2]), vnum_lookup( portloc_table, pObj->value[3])); add_buf(output, buf); break; case ITEM_FURNITURE: sprintf(buf, "{WMax people: {B[{R%d{B]\n\r" "{WMax weight: {B[{R%d{B]\n\r" "{WFurniture Flags: {B[{w%s{B]\n\r" "{WHeal bonus: {B[{R%d{B]\n\r" "{WMana bonus: {B[{R%d{B]\n\r\n\r", pObj->value[0], pObj->value[1], flag_string(furniture_flags, pObj->value[2]), pObj->value[3], pObj->value[4]); add_buf(output, buf); break; case ITEM_SCROLL: case ITEM_POTION: case ITEM_PILL: sprintf(buf, "{WLevel: {B[{R%d{B]\n\r" "{WSpell 1: {B[{w%s{B]\n\r" "{WSpell 2: {B[{w%s{B]\n\r" "{WSpell 3: {B[{w%s{B]\n\r" "{WSpell 4: {B[{w%s{B]\n\r\n\r", pObj->value[0], pObj->value[1] != -1 ? skill_table[pObj->value[1]].name : "none", pObj->value[2] != -1 ? skill_table[pObj->value[2]].name : "none", pObj->value[3] != -1 ? skill_table[pObj->value[3]].name : "none", pObj->value[4] != -1 ? skill_table[pObj->value[4]].name : "none"); add_buf(output, buf); break; /* ARMOR for ROM */ /* case ITEM_ARMOR: sprintf( buf, "{WAc pierce: {B[{R%d{B]\n\r" "{WAc bash: {B[{R%d{B]\n\r" "{WAc slash: {B[{R%d{B]\n\r" "{WAc exotic: {B[{R%d{B]\n\r", pObj->value[0], pObj->value[1], pObj->value[2], pObj->value[3] ); add_buf( output, buf ); add_buf( output, "{WAC is {wvariable{W.\n\r" ); break; */ /* WEAPON changed in ROM: */ /* I had to split the output here, I have no idea why, but it helped -- Hugin */ /* It somehow fixed a bug in showing scroll/pill/potions too ?! */ case ITEM_WEAPON: sprintf(buf, "{WAverage damage: {B[{R%d{B]\n\r", (1 + pObj->value[2]) * pObj->value[1] / 2); add_buf(output, buf); sprintf(buf, "{WWeapon type: {B[{w%s{B]\n\r", flag_string( weapon_class, pObj->value[0])); add_buf(output, buf); sprintf(buf, "{WNumber of dice: {B[{R%d{B]\n\r", pObj->value[1]); add_buf(output, buf); sprintf(buf, "{WType of dice: {B[{R%d{B]\n\r", pObj->value[2]); add_buf(output, buf); sprintf(buf, "{WDamage type: {B[{w%s{B]\n\r", attack_table[pObj->value[3]].name); add_buf(output, buf); sprintf(buf, "{WWpn flags: {B[{w%s{B]\n\r\n\r", flag_string( weapon_type2, pObj->value[4])); add_buf(output, buf); break; case ITEM_CONTAINER: sprintf(buf, "{WWeight: {B[{R%d{W kg{B]\n\r" "{WFlags: {B[{w%s{B]\n\r" "{WCapacity: {B[{R%d{B]\n\r" "{WWeight Mult: {B[{R%d{B]\n\r\n\r", pObj->value[0], flag_string(container_flags, pObj->value[1]), pObj->value[3], pObj->value[4]); add_buf(output, buf); break; case ITEM_DRINK_CON: sprintf(buf, "{WCapacity: {B[{R%d{B]\n\r", pObj->value[0]); add_buf(output, buf); break; case ITEM_FOUNTAIN: sprintf(buf, "{WLiquid Total: {B[{R%d{B]\n\r" "{WLiquid: {B[{w%s{B]\n\r\n\r", pObj->value[0], liq_table[pObj->value[2]].liq_name); add_buf(output, buf); break; case ITEM_FOOD: sprintf(buf, "{WFood hours: {B[{R%d{B]\n\r\n\r", pObj->value[0]); add_buf(output, buf); break; } for (paf = pObj->affected; paf != NULL; paf = paf->next) { if (paf->modifier != 0 && paf->location != APPLY_NONE) { sprintf(buf, "{WModifies: {B[{w%s{B] {Wby {B[{R%d{B]\n\r", affect_loc_name(paf->location), paf->modifier); add_buf(output, buf); } if (paf->bitvector) { switch (paf->where) { case TO_AFFECTS: sprintf(buf, "{WAffects user: {B[{w%s{B]\n\r", affect_bit_name(paf->bitvector)); break; case TO_OBJECT: sprintf(buf, "{WAdds obj flag: {B[{w%s{B]\n\r", extra_bit_name(paf->bitvector)); break; case TO_WEAPON: break; case TO_IMMUNE: sprintf(buf, "{WImmunity to: {B[{w%s{B]\n\r", imm_bit_name( paf->bitvector)); break; case TO_RESIST: sprintf(buf, "{WResistance to: {B[{w%s{B]\n\r", imm_bit_name( paf->bitvector)); break; case TO_VULN: sprintf(buf, "{WVulnerability to:{B[{w%s{B]\n\r", imm_bit_name( paf->bitvector)); break; case TO_SHIELDS: sprintf(buf, "{WAdds shield: {B[{w%s{B]\n\r", shield_bit_name(paf->bitvector)); break; default: sprintf(buf, "{WAdds unknown affect {B[{R%d{B] {Wat {B[{R%d{B]\n\r", paf->bitvector, paf->where); break; } if (paf->where != TO_WEAPON) add_buf(output, buf); } } add_buf(output, "{x"); page_to_char(output->string, ch); free_buf(output); return FALSE; } CEDIT_FUN( rcedit_buy ) { CLAN_DATA *clan; char arg[MAX_INPUT_LENGTH], whole_arg[MAX_INPUT_LENGTH]; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "RCedit syntax: buy <item> - buy a room upgrade for the current room\n\r" " buy list - show the possible upgrades available\n\r" " buy req <item> - find out what the room upgrade needs and costs to buy\n\r", ch); return FALSE; } strcpy(whole_arg, argument); argument = one_argument(argument, arg); if (!str_cmp(arg, "list")) { upgrade_list_table(ch, room_upgd_prices); return FALSE; } else if (!str_cmp(arg, "req")) return (upgrade_process(ch, argument, room_upgd_prices, FALSE )); else return (upgrade_process(ch, whole_arg, room_upgd_prices, TRUE )); } CEDIT_FUN( rcedit_desc ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; EDIT_CLAN( ch, clan ); EDIT_ROOM( ch, pRoom ); if (argument[0] == '\0') { string_append(ch, &pRoom->description); return TRUE; } send_to_char("RCedit syntax: desc - set the room description\n\r", ch); return FALSE; } CEDIT_FUN( rcedit_exdesc ) { CLAN_DATA *clan; EXTRA_DESCR_DATA *ex; ROOM_INDEX_DATA *pRoom; char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH]; int i; EDIT_CLAN( ch, clan ); EDIT_ROOM( ch, pRoom ); if (argument[0] == '\0') { send_to_char( "RCedit syntax: exdesc add <keyword> - add an extra description\n\r" " exdesc delete <keyword> - delete an extra description\n\r" " exdesc edit <keyword> - edit an existing extra description\n\r" " exdesc format <keyword> - format the extra description\n\r", ch); return FALSE; } argument = one_argument(argument, arg1); argument = one_argument(argument, arg2); if (!str_prefix(arg1, "add")) { if (arg2[0] == '\0') { send_to_char("Please specify a keyword to add\n\r", ch); return FALSE; } for (ex = pRoom->extra_descr, i = 0; ex != NULL; ex = ex->next, i++) if (!str_cmp(arg2, ex->keyword)) break; if (ex != NULL) { send_to_char( "There is already an existing extra description with that keyword.\n\r", ch); return FALSE; } if (i >= 2) { send_to_char( "There can only be 2 extra descriptions per clan room.\n\r", ch); return FALSE; } ex = new_extra_descr(); free_string(ex->keyword); ex->keyword = str_dup(arg2); free_string(ex->description); ex->description = str_dup(""); ex->next = pRoom->extra_descr; pRoom->extra_descr = ex; string_append(ch, &ex->description); } else if (!str_prefix(arg1, "edit")) { if (arg2[0] == '\0') { send_to_char("Please specify a keyword to edit\n\r", ch); return FALSE; } for (ex = pRoom->extra_descr; ex != NULL; ex = ex->next) if (!str_cmp(arg2, ex->keyword)) break; if (ex == NULL) { send_to_char( "There isn't an extra description with the keyword you specified.\n\r", ch); return FALSE; } string_append(ch, &ex->description); } else if (!str_prefix(arg1, "delete")) { EXTRA_DESCR_DATA *ex_prev; if (arg2[0] == '\0') { send_to_char("Please specify a keyword to delete\n\r", ch); return FALSE; } for (ex = pRoom->extra_descr, ex_prev = NULL; ex != NULL; ex_prev = ex, ex = ex->next) if (!str_cmp(arg2, ex->keyword)) break; if (ex == NULL) { send_to_char( "There isn't an extra description with the keyword you specified.\n\r", ch); return FALSE; } if (ex_prev == NULL) pRoom->extra_descr = ex->next; else ex_prev->next = ex->next; free_extra_descr(ex); send_to_char("Extra description deleted.\n\r", ch); } else if (!str_prefix(arg1, "format")) { if (arg2[0] == '\0') { send_to_char("Please specify a keyword to format\n\r", ch); return FALSE; } for (ex = pRoom->extra_descr; ex != NULL; ex = ex->next) if (!str_cmp(arg2, ex->keyword)) break; if (ex == NULL) { send_to_char( "There isn't an extra description with the keyword you specified.\n\r", ch); return FALSE; } ex->description = format_string(ex->description); send_to_char("Extra description formatted.\n\r", ch); } else { rcedit_exdesc(ch, ""); return FALSE; } return TRUE; } CEDIT_FUN( rcedit_name ) { CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); EDIT_ROOM( ch, pRoom ); if (argument[0] == '\0') { send_to_char("RCedit syntax: name <room name>\n\r", ch); return FALSE; } if (strlen_color(argument) < 4) { send_to_char("Provide a reasonable length name please.\n\r", ch); return FALSE; } free_string(pRoom->name); pRoom->name = str_dup(argument); sprintf(buf, "Room name changed to: {B%s{x\n\r", pRoom->name); send_to_char(buf, ch); return TRUE; } CEDIT_FUN( rcedit_show ) { BUFFER *output = new_buf(); CLAN_DATA *clan; ROOM_INDEX_DATA *pRoom; char buf[MAX_STRING_LENGTH]; EDIT_CLAN( ch, clan ); EDIT_ROOM( ch, pRoom ); sprintf(buf, "{WRoom name: {y[{B%s{y]\n\r", pRoom->name); add_buf(output, buf); sprintf(buf, "{WHP regen rate: {B[{R%d{B]\n\r", pRoom->heal_rate); add_buf(output, buf); sprintf(buf, "{WMana regen rate: {B[{R%d{B]\n\r", pRoom->mana_rate); add_buf(output, buf); sprintf(buf, "{WRoom flags: {B[{w%s{B]\n\r", flag_string(room_flags, pRoom->room_flags)); add_buf(output, buf); if (pRoom->extra_descr) { EXTRA_DESCR_DATA *ed; add_buf(output, "{WExdesc keywords: {B[{w"); for (ed = pRoom->extra_descr; ed; ed = ed->next) { add_buf(output, ed->keyword); if (ed->next) add_buf(output, " "); } add_buf(output, "{B]\n\r"); } sprintf(buf, "{WDescription:\n\r{x %s", pRoom->description); add_buf(output, buf); add_buf(output, "{x"); page_to_char(output->string, ch); free_buf(output); return FALSE; } CEDIT_FUN( scedit_buy ) { CLAN_DATA *clan; char buf[MAX_STRING_LENGTH]; int i; bool major = FALSE, minor = FALSE; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "SCedit syntax: buy <clan skill {Rcommand{x name> - buy a clan skill\n\r" " {RNote:{x once bought, clan skills can be sold back, but only for\n\r" " one third of the original price, so pick carefully.\n\r", ch); return FALSE; } for (i = 0; clan_skill_table[i].cmd[0] != '\0'; i++) if (!str_prefix(argument, clan_skill_table[i].cmd)) break; if (clan_skill_table[i].cmd[0] == '\0') { send_to_char("Clan skill not found.\n\r", ch); return FALSE; } int j, freeslot = -1; for (j = 0; j < 2; j++) { if (clan->skills[j] == i) { send_to_char("The clan already has that skill.\r\n", ch); return FALSE; } else if (clan->skills[j] == -1) freeslot = j; else { if (clan_skill_table[clan->skills[j]].major) major = TRUE; else minor = TRUE; } } if (freeslot == -1) { send_to_char("Your clan cannot purchase any more skills.\r\n", ch); return FALSE; } if ((clan_skill_table[i].major && major) || (!clan_skill_table[i].major && minor)) { send_to_char( "Each clan is allowed one major skill and one minor skill.\n\r", ch); return FALSE; } if (clan->platinum < clan_skill_table[i].platinum || clan->qps < clan_skill_table[i].qps) { send_to_char( "There isn't enough in the clan accounts to purchase that skill.\n\r", ch); return FALSE; } clan->skills[freeslot] = i; clan->platinum -= clan_skill_table[i].platinum; clan->qps -= clan_skill_table[i].qps; sprintf(buf, "%s{x clan skill purchased for %d platinum and %d questpoints", clan_skill_table[i].name, clan_skill_table[i].platinum, clan_skill_table[i].qps); append_clan_log(clan, ENTRY_UPGRADE, ch->name, buf); sprintf(buf, "%s{x clan skill purchased.\n\r", clan_skill_table[i].name); send_to_char(buf, ch); return TRUE; } CEDIT_FUN( scedit_sell ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *vch; CLAN_DATA *clan; int i; EDIT_CLAN( ch, clan ); if (argument[0] == '\0') { send_to_char( "SCedit syntax: sell <clan skill {Rcommand {xname> - sell skill for a {Rthird{x of the original price\n\r", ch); return FALSE; } for (i = 0; clan_skill_table[i].cmd[0] != '\0'; i++) if (!str_prefix(argument, clan_skill_table[i].cmd)) break; if (clan_skill_table[i].cmd[0] == '\0') { send_to_char("Clan skill not found.\n\r", ch); return FALSE; } if (!clan_has_skill(clan, i)) { send_to_char("You do not own that skill.\r\n", ch); return FALSE; } if (clan_skill_table[i].platinum > 0) clan->platinum += clan_skill_table[i].platinum / 3; if (clan_skill_table[i].qps > 0) clan->qps += clan_skill_table[i].qps / 3; sprintf(buf, "%s{x clan skill sold for %d platinum and %d questpoints", clan_skill_table[i].name, (clan_skill_table[i].platinum/3), (clan_skill_table[i].qps/3)); append_clan_log(clan, ENTRY_UPGRADE, ch->name, buf); int j; for (j = 0; j < 2; j++) if (clan->skills[j] == i) clan->skills[j] = -1; send_to_char("Skill sold.\n\r", ch); for (vch = char_list; vch != NULL; vch = vch->next) clanskill_check(ch); return TRUE; } CEDIT_FUN( scedit_show ) { BUFFER *output = new_buf(); CLAN_DATA *clan; char buf[MAX_STRING_LENGTH], borderbuf[MAX_STRING_LENGTH], *temp; int i; EDIT_CLAN( ch, clan ); add_buf( output, "{B+- {GCEDIT SKILLS {B---------------------------------------------------------+\n\r"); for (i = 0; clan_skill_table[i].cmd[0] != '\0'; i++) { if (i > 0) add_buf( output, "{B|------------------------------------------------------------------------|\n\r"); sprintf(buf, "{WName:{x %s {WCommand: {w%s", end_string( clan_skill_table[i].name, 24), clan_skill_table[i].cmd); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); if (clan_has_skill(clan, i)) { sprintf(buf, "{WClaimed by this clan{W."); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); } sprintf(buf, "{WType: %s {WRank required:{w %s", clan_skill_table[i].major ? "{CMajor" : "{cMinor", clan->r_name[get_p_rank_index(clan_skill_table[i].points)]); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); sprintf(buf, "{WPlatinum:{w %-7d {WQuest points:{w %d", clan_skill_table[i].platinum, clan_skill_table[i].qps); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); temp = clan_skill_table[i].description; temp = length_argument(temp, borderbuf, 57); sprintf(buf, "{WDescription: {w%s", borderbuf); sprintf(borderbuf, "{B| %s {B|\n\r", end_string(buf, 70)); add_buf(output, borderbuf); while (*temp != '\0') { temp = length_argument(temp, buf, 57); sprintf(borderbuf, "{B| {w%s {B|\n\r", end_string(buf, 57)); add_buf(output, borderbuf); } } add_buf( output, "{B+------------------------------------------------------------------------+{x\n\r"); page_to_char(output->string, ch); free_buf(output); return FALSE; } /* Handler for input whilst in main cedit */ void cedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; ROSTER_DATA *roster; char command[MAX_INPUT_LENGTH], whole_argument[MAX_INPUT_LENGTH]; int cmd, trust; bool immortal = IS_IMMORTAL( ch ); smash_tilde(argument); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (clan->upgrade != NULL && clan->u_rost == roster) { upgd_handler(ch, argument); return; } strcpy(whole_argument, argument); argument = one_argument(argument, command); if (command[0] == '\0') { send_to_char( "Use {Rcommands{x to show available commands, or {Rdone{x to exit the editor.\n\r", ch); cedit_show(ch, ""); return; } else if (!str_cmp(command, "done")) { cedit_done(ch); return; } else if (!str_prefix(command, "commands")) { show_cedit_commands(ch, argument, main_cedit_table); return; } if (immortal) trust = get_trust(ch); else trust = roster->trust; for (cmd = 0; main_cedit_table[cmd].cmd[0] != '\0'; cmd++) { if ((immortal && main_cedit_table[cmd].trust == TRUST_NONE) || (!immortal && main_cedit_table[cmd].m_trust == TRUST_NONE)) continue; if ((immortal && trust < main_cedit_table[cmd].trust) || (!immortal && trust < main_cedit_table[cmd].m_trust) || str_prefix( command, main_cedit_table[cmd].cmd)) continue; printf_player(ch, "(CEDIT) %s", whole_argument); if ((*main_cedit_table[cmd].func)(ch, argument)) save_clan_data(clan); return; } // send_to_char( "Command not found. Type {Rcommands{x for a list of commands.\n\r", ch ); interpret(ch, whole_argument); } /* Handler for input whilst in mob cedit */ void mcedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; MOB_INDEX_DATA *pMob; ROSTER_DATA *roster; char command[MAX_INPUT_LENGTH], whole_argument[MAX_INPUT_LENGTH]; int cmd, trust; bool immortal = IS_IMMORTAL( ch ); smash_tilde(argument); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (clan->upgrade != NULL && clan->u_rost == roster) { upgd_handler(ch, argument); return; } strcpy(whole_argument, argument); argument = one_argument(argument, command); if (command[0] == '\0') { send_to_char( "Use {Rcommands{x to show available commands, or {Rdone{x to exit the editor.\n\r", ch); mcedit_show(ch, ""); return; } else if (!str_cmp(command, "done")) { cedit_done(ch); return; } else if (!str_prefix(command, "commands")) { show_cedit_commands(ch, argument, mob_cedit_table); return; } if (immortal) trust = get_trust(ch); else trust = roster->trust; for (cmd = 0; mob_cedit_table[cmd].cmd[0] != '\0'; cmd++) { if ((immortal && mob_cedit_table[cmd].trust == TRUST_NONE) || (!immortal && mob_cedit_table[cmd].m_trust == TRUST_NONE)) continue; if ((immortal && trust < mob_cedit_table[cmd].trust) || (!immortal && trust < mob_cedit_table[cmd].m_trust) || str_prefix(command, mob_cedit_table[cmd].cmd)) continue; printf_player(ch, "(MCEDIT) %s", whole_argument); if ((*mob_cedit_table[cmd].func)(ch, argument)) { EDIT_MOB( ch, pMob ); reset_clan_mob(pMob, FALSE ); save_clan_data(clan); save_area(get_clan_area()); } return; } // send_to_char( "Command not found. Type {Rcommands{x for a list of commands.\n\r", ch ); interpret(ch, whole_argument); } /* Handler for input whilst in obj cedit */ void ocedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; OBJ_INDEX_DATA *pObj; ROSTER_DATA *roster; char command[MAX_INPUT_LENGTH], whole_argument[MAX_INPUT_LENGTH]; int cmd, trust; bool immortal = IS_IMMORTAL( ch ); smash_tilde(argument); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (clan->upgrade != NULL && clan->u_rost == roster) { upgd_handler(ch, argument); return; } strcpy(whole_argument, argument); argument = one_argument(argument, command); if (command[0] == '\0') { send_to_char( "Use {Rcommands{x to show available commands, or {Rdone{x to exit the editor.\n\r", ch); ocedit_show(ch, ""); return; } else if (!str_cmp(command, "done")) { cedit_done(ch); return; } else if (!str_prefix(command, "commands")) { show_cedit_commands(ch, argument, obj_cedit_table); return; } if (immortal) trust = get_trust(ch); else trust = roster->trust; for (cmd = 0; obj_cedit_table[cmd].cmd[0] != '\0'; cmd++) { if ((immortal && obj_cedit_table[cmd].trust == TRUST_NONE) || (!immortal && obj_cedit_table[cmd].m_trust == TRUST_NONE)) continue; if ((immortal && trust < obj_cedit_table[cmd].trust) || (!immortal && trust < obj_cedit_table[cmd].m_trust) || str_prefix(command, obj_cedit_table[cmd].cmd)) continue; printf_player(ch, "(OCEDIT) %s", whole_argument); if ((*obj_cedit_table[cmd].func)(ch, argument)) { EDIT_OBJ( ch, pObj ); reset_clan_obj(pObj, FALSE ); save_clan_data(clan); save_area(get_clan_area()); } return; } // send_to_char( "Command not found. Type {Rcommands{x for a list of commands.\n\r", ch ); interpret(ch, whole_argument); } /* Handler for input whilst in room cedit */ void rcedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; ROSTER_DATA *roster; char command[MAX_INPUT_LENGTH], whole_argument[MAX_INPUT_LENGTH]; int cmd, trust; bool immortal = IS_IMMORTAL( ch ); smash_tilde(argument); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (clan->upgrade != NULL && clan->u_rost == roster) { upgd_handler(ch, argument); return; } strcpy(whole_argument, argument); argument = one_argument(argument, command); if (command[0] == '\0') { send_to_char( "Use {Rcommands{x to show available commands, or {Rdone{x to exit the editor.\n\r", ch); rcedit_show(ch, ""); return; } else if (!str_cmp(command, "done")) { cedit_done(ch); return; } else if (!str_prefix(command, "commands")) { show_cedit_commands(ch, argument, room_cedit_table); return; } if (immortal) trust = get_trust(ch); else trust = roster->trust; for (cmd = 0; room_cedit_table[cmd].cmd[0] != '\0'; cmd++) { if ((immortal && room_cedit_table[cmd].trust == TRUST_NONE) || (!immortal && room_cedit_table[cmd].m_trust == TRUST_NONE)) continue; if ((immortal && trust < room_cedit_table[cmd].trust) || (!immortal && trust < room_cedit_table[cmd].m_trust) || str_prefix( command, room_cedit_table[cmd].cmd)) continue; if ((*room_cedit_table[cmd].func)(ch, argument)) { printf_player(ch, "(RCEDIT) %s", whole_argument); save_clan_data(clan); save_area(get_clan_area()); } return; } // send_to_char( "Command not found. Type {Rcommands{x for a list of commands.\n\r", ch ); interpret(ch, whole_argument); } /* Handler for input whilst in skill cedit */ void scedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; ROSTER_DATA *roster; char command[MAX_INPUT_LENGTH], whole_argument[MAX_INPUT_LENGTH]; int cmd, trust; bool immortal = IS_IMMORTAL( ch ); smash_tilde(argument); strcpy(whole_argument, argument); argument = one_argument(argument, command); EDIT_CLAN( ch, clan ); GET_ROSTER( ch, roster ); if (command[0] == '\0') { send_to_char( "Use {Rcommands{x to show available commands, or {Rdone{x to exit the editor.\n\r", ch); scedit_show(ch, ""); return; } else if (!str_cmp(command, "done")) { cedit_done(ch); return; } else if (!str_prefix(command, "commands")) { show_cedit_commands(ch, argument, skill_cedit_table); return; } if (immortal) trust = get_trust(ch); else trust = roster->trust; for (cmd = 0; skill_cedit_table[cmd].cmd[0] != '\0'; cmd++) { if ((immortal && skill_cedit_table[cmd].trust == TRUST_NONE) || (!immortal && skill_cedit_table[cmd].m_trust == TRUST_NONE)) continue; if ((immortal && trust < skill_cedit_table[cmd].trust) || (!immortal && trust < skill_cedit_table[cmd].m_trust) || str_prefix( command, skill_cedit_table[cmd].cmd)) continue; printf_player(ch, "(SCEDIT) %s", whole_argument); if ((*skill_cedit_table[cmd].func)(ch, argument)) save_clan_data(clan); return; } // send_to_char( "Command not found. Type {Rcommands{x for a list of commands.\n\r", ch ); interpret(ch, whole_argument); } /* Function for cedit COMMAND */ void do_cedit(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH]; if (!HAS_ROSTER( ch )) // No mobs. return; argument = one_argument(argument, arg); smash_tilde(argument); GET_ROSTER( ch, roster ); if (IS_IMMORTAL( ch )) { if (get_trust(ch) < SUPREME) { send_to_char("You don't get access to this. Get back to work!\n\r", ch); return; } if (!str_cmp(arg, "list")) { BUFFER *output = new_buf(); int i; for (i = 1, clan = clan_list; clan != NULL; i++, clan = clan->next) { sprintf(buf, "{R%3d{B){x %s{w %s ", i, end_string(clan->c_name, MAX_CLAN_WHO_LENGTH ), clan->name); add_buf(output, end_string(buf, 40)); if (i % 2 == 0 // Organise as four per line || clan->next == NULL) add_buf(output, "{x\n\r"); } if (i > 1) send_to_char(output->string, ch); else send_to_char("There are no clans!\n\r", ch); free_buf(output); return; } else if (!str_cmp(arg, "create")) { cedit_create(ch, argument); return; } else if ((clan = get_clan_by_name(arg)) == NULL) { send_to_char( "Clan not found. Use cedit list for a list of clans.\n\r", ch); return; } if ((clan->id == CLAN_NONE || clan->id == CLAN_LONER || clan->id == CLAN_PK_OUTCAST || clan->id == CLAN_NONPK_OUTCAST || clan->id == CLAN_IMMORTAL) && str_cmp(ch->name, "Nico")) { send_to_char("This clan cannot be edited.\n\r", ch); return; } } else { clan = roster->clan; if (clan->independent) { if (IS_SET( roster->flags, ROST_CONFIRM_NEW )) { char c_name[MAX_STRING_LENGTH], *name; REMOVE_BIT( roster->flags, ROST_CONFIRM_NEW ); strcpy(c_name, argument); name = strip_spaces(argument); name = strip_spec_char_col(name); if (!str_cmp(arg, "confirm") && *name != '\0') { if (strlen_color(c_name) > MAX_CLAN_WHO_LENGTH) { send_to_char( "The clan who name(ie the one you provided) has to be 12 characters or less.\n\r", ch); return; } if (ch->platinum < PRICE_CLAN_PLATINUM || ch->questpoints < PRICE_CLAN_QP) // Bust the cheaters { send_to_char("Where did all the dough go?\n\r", ch); return; } clan = new_clan_data(TRUE); free_string(clan->name); clan->name = str_dup(name); free_string(clan->c_name); clan->c_name = str_dup(c_name); clan->edit_time = current_time + (2 * TIME_HOUR); if (roster->clan->pkill) clan->pkill = TRUE; roster->trust = TRUST_LDR; // Set trust to leader trust roster->clan = clan; // Make character's clan equal new clan roster->petition = NULL; // Stop any accidental petition accepts ch->platinum -= PRICE_CLAN_PLATINUM; // Deduct price from ch to put into clan ch->questpoints -= PRICE_CLAN_QP; // Ditto clan->qps = PRICE_CLAN_QP; // Price of clan is invested into clan clan->platinum = PRICE_CLAN_PLATINUM; // Price of clan is invested into clan (clan->members)++; assign_clan_vnums(clan); send_to_char( "{GCongratulations! You have created your clan!{x\n\r" "You have two day to edit basic clan data such as name and clan ranks.\n\r" "After this time, you will need to buy extra time - this does not effect clan upgrades..\n\r" "{RAny inappropriate clan names or ranks will be dealt with.{x\n\r", ch); append_clan_log(clan, ENTRY_CREATE, ch->name, "{wClan created"); save_all_clans(); save_roster_data(roster); } else { send_to_char("Clan creation status removed.\n\r", ch); return; } } else if (!str_cmp(arg, "buy")) { if (IS_SET(roster->flags, ROST_NEWBIE)) { send_to_char( "Newbies can't create clans. Type \"{Rnotnewbie{x\" to un-newbie yourself.\r\n", ch); return; } if (ch->platinum < PRICE_CLAN_PLATINUM || ch->questpoints < PRICE_CLAN_QP) // Say no to the poor people { sprintf( buf, "You need {R%d{x platinum and {R%d{x Quest points to buy a clan.\n\r", PRICE_CLAN_PLATINUM, PRICE_CLAN_QP ); send_to_char(buf, ch); return; } SET_BIT( roster->flags, ROST_CONFIRM_NEW ); send_to_char( "Type \"{Gcedit confirm <clanname>{x\" to confirm your decision to buy a clan.\n\r" "The clan name you specify can be the who name of the clan, but it cannot exceed 12 characters.\n\r", ch); sprintf( buf, "The cost will be {R%d{x platinum and {R%d{x Quest points.\n\r", PRICE_CLAN_PLATINUM, PRICE_CLAN_QP ); send_to_char(buf, ch); send_to_char( "Please note, if you are inactive for a long period of time, you will lose your leadership status.\n\r" "Type \"{Rcedit <anything else>{x\" to cancel.\n\r", ch); return; } else { sprintf( buf, "Use {Rcedit buy{x to buy a clan for {Y%d{x platinum and {Y%d{x Quest points.\n\r", PRICE_CLAN_PLATINUM, PRICE_CLAN_QP ); send_to_char(buf, ch); return; } } } SET_EDIT_ITEM( ch, NULL ); SET_EDIT_CLAN( ch, clan ); SET_EDIT_TYPE( ch, ED_CEDIT ); //cedit_show(ch, ""); } /****************************** CLAN MANAGEMENT COMMANDS ******************************/ /* For Immortals to guild people without going into cedit */ void do_guild(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan; char name[MAX_INPUT_LENGTH]; argument = one_argument(argument, name); if (argument[0] == '\0' || name[0] == '\0') { send_to_char("Syntax: guild <character> <clan>\n\r", ch); return; } if ((clan = get_clan_by_name(argument)) == NULL) { send_to_char("Clan not found.\n\r", ch); return; } SET_EDIT_CLAN( ch, clan ); if (cedit_guild(ch, name)) save_clan_data(clan); SET_EDIT_CLAN( ch, NULL ); } /* For Immortals to set the newbie flag */ void do_newbie(CHAR_DATA *ch, char *argument) { ROSTER_DATA *roster; if (argument[0] == '\0') { send_to_char( "Syntax: newbie <player> - set the newbie flag on a player\n\r", ch); return; } if ((roster = get_roster_by_name(argument, FALSE)) == NULL) { send_to_char("Player not found.\n\r", ch); return; } if (IS_SET( roster->flags, ROST_NEWBIE )) { send_to_char("That player is already a newbie.\n\r", ch); return; } if (!roster->clan->pkill) { send_to_char("That player is not a player-killer.\n\r", ch); return; } SET_BIT( roster->flags, ROST_NEWBIE ); send_to_char("Player newbiefied.\n\r", ch); if (roster->character) send_to_char("Your newbie flag has been set.\n\r", roster->character); } /* Remove newbie flag */ void do_notnewbie(CHAR_DATA *ch, char *argument) { ROSTER_DATA *roster; if (!HAS_ROSTER( ch )) return; GET_ROSTER( ch, roster ); if (!IS_SET( roster->flags, ROST_NEWBIE )) { send_to_char("You've already un-newbified.\n\r", ch); return; } if (!str_cmp(argument, "confirm")) { REMOVE_BIT( roster->flags, ROST_NEWBIE ); send_to_char("Welcome to the world of proper player-killing!\n\r", ch); return; } send_to_char( "If you un-newbify yourself, you leave yourself open to full player-killing.\n\r" "It is recommended that you find yourself a clan to join before you un-newbify.\n\r" "If you are ready to remove your newbie flag, type \"{Rnotnewbie confirm{x\".\n\r", ch); } /* Command to become a player-killer */ void do_go_pkill(CHAR_DATA *ch, char *argument) { ROSTER_DATA *roster; if (!HAS_ROSTER( ch )) return; GET_ROSTER( ch, roster ); if (ch->pcdata->tier == 1 && ch->level > 25) { send_to_char("The deadline for this tier was level 25.\n\r" "Last chance will be next tier, before reaching level 26.\n\r", ch); return; } else if (ch->pcdata->tier == 3 || (ch->pcdata->tier == 2 && ch->level > 25)) { send_to_char( "You should have decided this earlier. Level 25, tier 2 was the deadline.\n\r", ch); return; } if (roster->clan->pkill) { send_to_char("You are already a player-killer.\n\r", ch); return; } if (IS_SET( roster->flags, ROST_CONFIRM_PK )) { REMOVE_BIT( roster->flags, ROST_CONFIRM_PK ); if (!str_cmp(argument, "yes")) { roster->clan = get_clan_by_id(CLAN_LONER); (roster->clan->members)++; SET_BIT( roster->flags, ROST_NEWBIE ); send_to_char( "Congratulations, you are now a player-killer!\n\r" "To start with, you will be marked as a newbie.\n\r" "This means you can only player-kill other newbie player-killers.\n\r" "In turn, only other newbie player-killers can player-kill you.\n\r" "You can only join a clan if you remove this flag using {Rnotnewbie{x.\n\r" "It is recommended you build your character before doing so.\n\r", ch); return; } send_to_char("Player-kill confirmation status removed.\n\r", ch); return; } send_to_char( "Player-killing isn't for the faint of heart but can be rewarding.\n\r" "Expect to be killed - even the best lose sometimes.\n\r" "Type \"{Rpkill yes{x\" to confirm your choice or \"{Gpkill <anything>{x\" to cancel.\n\r" "The deadline for this choice is level 25, tier 2.\n\r", ch); SET_BIT( roster->flags, ROST_CONFIRM_PK ); } /* Petition clan for membership */ void do_petition(CHAR_DATA *ch, char *argument) { CHAR_DATA *vch; CLAN_DATA *clan; ROSTER_DATA *roster, *vchRoster; char buf[MAX_STRING_LENGTH]; if (!HAS_ROSTER( ch )) return; GET_ROSTER( ch, roster ); if (!roster->clan->independent) { send_to_char("Type loner to leave your clan.\n\r" "{RNOTE: {xIt will cost you a third of your donation points.\n\r", ch); return; } if (roster->clan->id == CLAN_PK_OUTCAST || roster->clan->id == CLAN_NONPK_OUTCAST) { send_to_char("You're an outcast. No one wants you.\n\r", ch); return; } if (IS_SET( roster->flags, ROST_NEWBIE )) { send_to_char( "Newbies can't join clans - type notnewbie to unnewbie yourself.\n\r", ch); return; } if (argument[0] == '\0') { send_to_char( "Syntax: petition <clan> - petition a clan for membership\n\r" " petition cancel - cancel your current clan petition\n\r", ch); if (roster->petition) { sprintf(buf, "You are currently petitioning %s{x for membership.\n\r", strip_bespaces(roster->petition->c_name)); send_to_char(buf, ch); } return; } if (!str_cmp(argument, "cancel")) { send_to_char("Clan petition cleared.\n\r", ch); sprintf( buf, "{RPETITION CANCEL {r>{R>{r> {w%s {Whas cancelled their petition for clan membership.{x\n\r", ch->name); for (vch = char_list; vch != NULL; vch = vch->next) { if (!HAS_ROSTER( vch )) continue; GET_ROSTER( vch, vchRoster ); if (roster->petition == vchRoster->clan) send_to_char(buf, vch); } roster->petition = NULL; return; } if ((clan = get_clan_by_name(argument)) == NULL) { send_to_char("Clan not found.\n\r", ch); return; } if (roster->petition) { sprintf(buf, "You have already petitioned %s{x for membership.\n\r", strip_bespaces(roster->petition->c_name)); send_to_char(buf, ch); send_to_char("Type {Rpetition cancel{x to cancel petition.\n\r", ch); return; } if (roster->clan->pkill && !clan->pkill) { send_to_char( "You're a player killer - you cannot petition that clan as its a non-pk clan.\n\r", ch); return; } else if (!roster->clan->pkill && clan->pkill) { send_to_char( "You're not a player killer - you cannot petition that clan as its a player-killing clan.\n\r", ch); return; } if (clan->independent) { send_to_char("Petition a proper clan.\n\r", ch); return; } if (((clan->pkill && clan->members >= MAX_PK_CLAN_MEMBERS) || (!clan->pkill && clan->members >= MAX_NONPK_CLAN_MEMBERS)) && !clan->independent) { send_to_char( "The clan has already reached the maximum number of memebers.\n\r", ch); return; } roster->petition = clan; sprintf(buf, "Clan %s{x petitioned for membership.\n\r", strip_bespaces( clan->c_name)); send_to_char(buf, ch); sprintf( buf, "{GPETITION {r>{R>{r> {w%s {Whas petitioned for clan membership.{x\n\r", ch->name); for (vch = char_list; vch != NULL; vch = vch->next) { if (!HAS_ROSTER( vch )) continue; GET_ROSTER( vch, vchRoster ); if (clan == vchRoster->clan) send_to_char(buf, vch); } } /* Escape the grasps of a clan */ void do_loner(CHAR_DATA *ch, char *argument) { ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH]; if (!HAS_ROSTER( ch )) return; GET_ROSTER( ch, roster ); if (roster->clan->independent) { send_to_char("You can't be any more alone.\n\r", ch); return; } if (roster->trust == TRUST_LDR) { send_to_char( "You're the leader of your clan - ask an immortal first!\n\r", ch); return; } if (IS_SET( roster->flags, ROST_CONFIRM_LONER )) { REMOVE_BIT( roster->flags, ROST_CONFIRM_LONER ); if (!str_cmp(argument, "yes")) { roster->dPoints = roster->dPoints * 2 / 3; roster->trust = TRUST_ALL; roster->penalty_time = 0; REMOVE_BIT( roster->flags, ROST_INACTIVE ); if (IS_SET( roster->flags, ROST_EXILE_GRACE )) { REMOVE_BIT( roster->flags, ROST_EXILE_GRACE ); send_to_char( "You have avoided being put into the outcast clan for voluntarily leaving.\n\r", ch); } if (roster->clan && !roster->clan->independent) roster->clan->members--; if (roster->clan->pkill) roster->clan = get_clan_by_id(CLAN_LONER); else roster->clan = get_clan_by_id(CLAN_NONE); send_to_char("You are now a {Rloner{x.\n\r", ch); sprintf(buf, "Your donation points have been reduced to {R%ld{x.\n\r", roster->dPoints); send_to_char(buf, ch); return; } send_to_char("Loner confirmation status removed.\n\r", ch); } else { SET_BIT( roster->flags, ROST_CONFIRM_LONER ); send_to_char( "If you choose to loner yourself, you will lose a third of your points.\n\r" "Type {Rloner yes{x to confirm, or loner with anything else to clear.\n\r", ch); if (IS_SET( roster->flags, ROST_EXILE_GRACE )) send_to_char( "This is a better option than getting exiled, as you lose fewer points.\n\r" "You will also be able to get reclanned straight away, rather than waiting a week.\n\r", ch); } } /* Exile a player */ bool exile_player(ROSTER_DATA *roster) { if (roster->clan->independent) return FALSE; if (IS_SET( roster->flags, ROST_EXILE_GRACE )) // If they were graced { REMOVE_BIT( roster->flags, ROST_EXILE_GRACE ); if (roster->character) send_to_char( "{RThe grace period in which you could quit voluntarily has expired.{x\n\r", roster->character); append_clan_log(roster->clan, ENTRY_EXILE, roster->name, "{wAutomatically exiled from clan - end of grace"); } if (roster->clan && !roster->clan->independent) roster->clan->members--; if (roster->clan->pkill) roster->clan = get_clan_by_id(CLAN_PK_OUTCAST); // PK go here else roster->clan = get_clan_by_id(CLAN_NONPK_OUTCAST); // Non-pk go here roster->trust = TRUST_ALL; // Trust back to 0 roster->dPoints /= 2; // Halve their donation points roster->penalty_time = current_time + TIME_WEEK; // They get out of the outcast clan in a week REMOVE_BIT( roster->flags, ROST_INACTIVE ); REMOVE_BIT( roster->flags, ROST_CONFIRM_NEW ); REMOVE_BIT( roster->flags, ROST_CONFIRM_PK ); REMOVE_BIT( roster->flags, ROST_CONFIRM_LONER ); if (roster->character) send_to_char("{RYou have been exiled from your clan!{x\n\r", roster->character); return FALSE; } /********************************** GENERAL COMMANDS **********************************/ /* Clan talk */ void do_ctalk(CHAR_DATA *ch, char *argument) { CLAN_DATA *clan = NULL; DESCRIPTOR_DATA *d; ROSTER_DATA *roster = NULL, *vchRoster; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH]; if (IS_NPC( ch )) { if ((clan = get_clan_by_vnum(ch->pIndexData->vnum)) == NULL) return; } else if (IS_IMMORTAL( ch ) && get_trust(ch) >= IMPLEMENTOR) { argument = one_argument(argument, arg); if (arg[0] == '\0' || (clan = get_clan_by_name(arg)) == NULL) { send_to_char("Syntax: clan <clan name> <what you want to say>\n\r", ch); return; } } else { GET_ROSTER( ch, roster ); if (roster == NULL) return; clan = roster->clan; if (clan->independent) { send_to_char("You aren't in a clan!\n\r", ch); return; } } if (argument[0] == '\0') { if (IS_SET( ch->comm, COMM_NOCLAN )) { send_to_char("{RClan{x channel is now {GON{x\n\r", ch); REMOVE_BIT( ch->comm, COMM_NOCLAN ); } else { send_to_char("{RClan{x channel is now {ROFF{x\n\r", ch); SET_BIT( ch->comm, COMM_NOCLAN ); } return; } if (!IS_IMMORTAL(ch)) { if (IS_SET(ch->comm, COMM_NOCHANNELS)) { send_to_char("The gods have revoked your channel priviliges.\n\r", ch); return; } else if (ch->in_room->vnum == ROOM_VNUM_CORNER) { send_to_char( "Just keep your nose in the corner like a good little player.\n\r", ch); return; } // else if ( IS_SET(ch->in_room->room_flags,ROOM_SILENCED) ) // { // send_to_char( "You have lost your powers of speech in this room!\n\r",ch ); // return; // } } REMOVE_BIT( ch->comm, COMM_NOCLAN ); sprintf(buf, "{y[{x%s {W-{x %s{y]{x You '{M%s{x'\n\r", strip_bespaces( clan->c_name), IS_NPC(ch) ? "Mob" : (IS_IMMORTAL(ch) && clan->id != CLAN_IMMORTAL) ? "{WI{wm{Dm" : clan->r_who[get_r_rank_index( roster)], argument); send_to_char(buf, ch); sprintf(buf, "{y[{x%s {W-{x %s{y]{x %s '{M%s{x'\n\r", strip_bespaces( clan->c_name), IS_NPC(ch) ? "Mob" : (IS_IMMORTAL(ch) && clan->id != CLAN_IMMORTAL) ? "{WI{wm{Dm" : clan->r_who[get_r_rank_index( roster)], PERS(ch,ch), argument); for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected != CON_PLAYING || d->character == NULL || d->character == ch || IS_SET(d->character->comm, COMM_QUIET) || IS_SET(d->character->comm, COMM_NOCLAN)) continue; GET_ROSTER( d->character, vchRoster ); if (vchRoster == NULL) continue; if ((IS_IMMORTAL( d->character ) && get_trust(d->character) >= IMPLEMENTOR) || vchRoster->clan == clan) send_to_char(buf, d->character); } } /* Whack a bounty on someones head or show the current bounties */ void do_bounty(CHAR_DATA *ch, char *argument) { DESCRIPTOR_DATA *d; ROSTER_DATA *vchRoster; char arg[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH]; int amt; if (argument[0] == '\0') { send_to_char("Syntax: bounty <player> <platinum>\n\r" " bounty list\n\r", ch); return; } argument = one_argument(argument, arg); if (!str_cmp(arg, "list")) { BUFFER *output = new_buf(); int capBounty, maxBounty; bool found = FALSE; add_buf(output, "{B+-{G Bounty List{B ------------------+{x\n\r"); add_buf(output, "{B| {WName {B| {WBounty {B|\n\r"); for (capBounty = -1;;) { for (vchRoster = roster_list, maxBounty = 0; vchRoster != NULL; vchRoster = vchRoster->next) { if (IS_SET( vchRoster->flags, ROST_DELETED )) continue; if (capBounty > -1 && vchRoster->bounty >= capBounty) continue; if (vchRoster->bounty <= maxBounty) continue; maxBounty = vchRoster->bounty; } if (maxBounty <= 0) break; found = TRUE; for (vchRoster = roster_list; vchRoster != NULL; vchRoster = vchRoster->next) { if (IS_SET( vchRoster->flags, ROST_DELETED ) || vchRoster->bounty != maxBounty) continue; sprintf( buf, "{B|{w %s {B|{Y %-9ld {B|\n\r", (vchRoster->character && vchRoster->character == ch) ? end_string( "{RYou", 18) : end_string(vchRoster->name, 18), vchRoster->bounty); add_buf(output, buf); } capBounty = maxBounty; } add_buf(output, "{B+--------------------------------+{x\n\r"); if (found) page_to_char(output->string, ch); else send_to_char("No one has a bounty at the moment.\n\r", ch); free_buf(output); return; } else if ((vchRoster = get_roster_by_name(arg, FALSE)) == NULL) { send_to_char("Player not found.\n\r", ch); return; } if (!is_number(argument) || (amt = atoi(argument)) < 50) { send_to_char("The minimum bounty is 50 platinum.\n\r", ch); return; } if (ch->platinum < amt) { send_to_char("You cannot cover the cost.\r\n", ch); return; } ch->platinum -= amt; vchRoster->bounty += amt; save_roster_data(vchRoster); sprintf( buf, "{CBOUNTY {r>{R>{r> {WA bounty of {Y%d{W platinum has been offered for the head of {R%s{W! (Total bounty {Y%ld{W){x\n\r", amt, vchRoster->name, vchRoster->bounty); for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected != CON_PLAYING || d->character == NULL || IS_SET( d->character->comm, COMM_QUIET )) continue; send_to_char(buf, d->character); } } /*************************************** CHARTS ***************************************/ // Overall clan charts, individual charts, roster, clist /* Displays all the clans and stats */ void do_clist(CHAR_DATA *ch, char *argument) { BUFFER *output = new_buf(); CLAN_DATA *clan; ROSTER_DATA *roster; char buf[MAX_STRING_LENGTH], name[MAX_STRING_LENGTH], *temp, temp2[MAX_STRING_LENGTH]; int trust = get_trust(ch), i; GET_ROSTER( ch, roster ); add_buf( output, "{B+- {WThe Clans of "GAME_COL_NAME"{B --------------------------------------------+\n\r"); for (clan = clan_list; clan != NULL; clan = clan->next) { sprintf(name, "%s {W({w%s{W)", clan->c_name, clan->name); sprintf(buf, "{B| %6s {%cClan:{x %s {B|\n\r", clan->pkill ? "{R>{r>{RPK{r<{R<" : "{yNON-PK", (roster && roster->clan == clan) ? 'G' : 'W', end_string(name, 46)); add_buf(output, buf); if (trust >= SUPREME) sprintf( buf, "{B| {WMembers:{w %6d {W%s Points:{w %6ld {WQuest:{w %6ld {WPlatinum:{w %6ld {B|\n\r", clan->members, clan->pkill ? "PKill" : "Arena", clan->pkilldata->kPoints, clan->qps, clan->platinum); else sprintf( buf, "{B| {WMembers:{w %6d {W%s Points:{w %6ld {B|\n\r", clan->members, clan->pkill ? "PKill" : "Arena", clan->pkilldata->kPoints); add_buf(output, buf); sprintf( buf, "{B| {WKills:{g %6d {WDeaths:{r %6d {WWins:{g %6d {WLosses:{r %6d {B|\n\r", clan->pkilldata->kills, clan->pkilldata->deaths, clan->pkilldata->wins, clan->pkilldata->losses); add_buf(output, buf); for (temp = clan->description, i = 0; *temp; i++, temp++) { if ((*temp == '\n' && *(temp + 1) == '\r') || (*temp == '\r' && *(temp + 1) == '\n')) { temp2[i] = ' '; temp++; continue; } else if (*temp == '\n' || *temp == '\r') { temp2[i] = ' '; continue; } temp2[i] = *temp; } temp2[i] = '\0'; temp = temp2; temp = length_argument(temp, name, 64); sprintf(buf, "{WDescription: {w%s", name); sprintf(name, "{B| %s {B|\n\r", end_string(buf, 77)); add_buf(output, name); while (*temp != '\0') { temp = length_argument(temp, buf, 64); sprintf(name, "{B| {w%s {B|\n\r", end_string(buf, 64)); add_buf(output, name); } add_buf( output, "{B+-------------------------------------------------------------------------------+\n\r"); } add_buf(output, "{x"); page_to_char(output->string, ch); free_buf(output); } /* Show details on a clan */ void do_clan_roster(CHAR_DATA *ch, char *argument) { BUFFER *output; CLAN_DATA *clan; ROSTER_DATA *roster, *chRoster; char buf[MAX_STRING_LENGTH], name[500], rankName[500]; int maxPoints, capPoints, i; bool found = FALSE; if (argument[0] == '\0') { send_to_char( "Syntax: roster <clanname> - display the roster of a clan\n\r", ch); return; } if ((clan = get_clan_by_name(argument)) == NULL) { send_to_char("Clan not found.\n\r", ch); return; } if (clan->id == CLAN_IMMORTAL && !IS_IMMORTAL( ch )) { send_to_char("Mind your own business.\n\r", ch); return; } GET_ROSTER( ch, chRoster ); output = new_buf(); sprintf(buf, "{B+- {GClan Roster of{x %s {B", strip_bespaces(clan->c_name)); add_buf(output, buf); for (i = (67 - strlen_color(strip_bespaces(clan->c_name))); i > 0; i--) add_buf(output, "-"); add_buf(output, "+\n\r"); add_buf( output, "{B|{W Rank {B| {WName {B| {WPoints {B| {WKills {B| {WDeaths {B| {WWins {B| {WLosses {B|\n\r"); for (capPoints = -1;;) // Initialise capPoints as -1 because we haven't found out what the highest value is yet { for (maxPoints = -1, roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; // Display only those in the desired clan if (roster->clan != clan || (capPoints >= 0 && get_total_points( roster) >= capPoints)) // Next highest value must be below previous highest value continue; // (only if its not the very first highest value) else if (get_total_points(roster) > maxPoints) // See if its the highest value of this round maxPoints = get_total_points(roster); } if (maxPoints < 0) // Break out from it all if there aren't any more records that are less than cap points break; for (roster = roster_list; roster != NULL; roster = roster->next) { if (IS_SET( roster->flags, ROST_DELETED )) continue; if (roster->clan == clan && get_total_points(roster) == maxPoints) // Go through all the players with the same point value as the current max value { found = TRUE; sprintf(name, "%s%s", (chRoster && roster == chRoster) ? "{GYou" : capitalize(roster->name), roster->trust == TRUST_LDR ? " {W({RLdr{W)" : roster->trust == TRUST_VLR ? " {W({CVlr{W)" : ""); sprintf(rankName, "%s", clan->independent ? "{wI{Dndependent " : end_string(clan->r_name[get_r_rank_index( roster)], MAX_CLAN_RANK_LENGTH )); sprintf( buf, "{B|{w %s {B|{w %s {B|{Y %-6ld {B|{g %-6d {B|{r %-6d {B|{g %-6d {B|{r %-6d {B|\n\r", rankName, end_string(name, 18), get_total_points(roster), roster->pkilldata->kills, roster->pkilldata->deaths, roster->pkilldata->wins, roster->pkilldata->losses); add_buf(output, buf); } } capPoints = maxPoints; } add_buf( output, "{B+-------------------------------------------------------------------------------------+{x\n\r"); if (found) page_to_char(output->string, ch); else { sprintf(buf, "There isn't anyone in %s{x\n\r", strip_bespaces( clan->c_name)); send_to_char(buf, ch); } free_buf(output); } /* Display the top 20 */ void do_rank(CHAR_DATA *ch, char *argument) { BUFFER *output; ROSTER_DATA *roster, *chRoster; char buf[MAX_STRING_LENGTH], arg[MAX_INPUT_LENGTH]; int maxPoints, capPoints, rankCount; bool pkOnly = FALSE, npkOnly = FALSE; if (argument[0] == '\0') { send_to_char( "Syntax: rank pk - shows the top 20 PK players\n\r" " rank nonpk - shows the top 20 NON-PK players\n\r" " rank all - shows the top 20 PK/NON-PK players\n\r" " rank <person> arena - shows how many points you would get for killing the person in the arena\n\r" " rank <person> pk - shows how many points you would get for killing the person in pk\n\r", ch); return; } argument = one_argument(argument, arg); GET_ROSTER( ch, chRoster ); if (!str_cmp(arg, "pk")) pkOnly = TRUE; else if (!str_cmp(arg, "nonpk")) npkOnly = TRUE; else if (str_cmp(arg, "all")) { if (chRoster == NULL) return; if ((roster = get_roster_by_name(arg, FALSE)) == NULL) { send_to_char("Player not found.\n\r", ch); return; } if (roster == chRoster) { send_to_char( "Suicide is a sin. You don't gain points from it.\n\r", ch); return; } if (!str_cmp(argument, "arena")) { sprintf( buf, "You would receive {R%d{x kill points for killing {R%s{x in the arena.\n\r", rank_kill(chRoster, roster, TRUE, TRUE ), roster->name); send_to_char(buf, ch); return; } else if (!str_cmp(argument, "pk")) { if (!chRoster->clan->pkill || !roster->clan->pkill) { send_to_char( "You both have to be player killers to use this option.\n\r", ch); return; } sprintf( buf, "You would receive {R%d{x kill points for killing {R%s{x in pk.\n\r", rank_kill(chRoster, roster, FALSE, TRUE ), roster->name); send_to_char(buf, ch); return; } send_to_char( "Please specify {Rpk{x or {Rarena{x after the player's name.\n\r", ch); return; } output = new_buf(); if (pkOnly) { add_buf( output, "{B+-{G Top 20 PK Players {B------------------------------------------------------------------+\n\r"); add_buf( output, "{B|{W No. {B|{W Clan {B|{W Name {B|{W Points {B|{W Kills {B|{W Deaths {B|{W Wins {B|{W Losses {B|\n\r"); } else if (npkOnly) { add_buf( output, "{B+-{G Top 20 NON-PK Players {B--------------------------------------------------------------+\n\r"); add_buf( output, "{B|{W No. {B|{W Clan {B|{W Name {B|{W Points {B|{W Kills {B|{W Deaths {B|{W Wins {B|{W Losses {B|\n\r"); } else { add_buf( output, "{B+-{G Top 20 ALL Players {B-----------------------------------------------------------------------+\n\r"); add_buf( output, "{B|{W PK {B|{W No. {B|{W Clan {B|{W Name {B|{W Points {B|{W Kills {B|{W Deaths {B|{W Wins {B|{W Losses {B|\n\r"); } for (capPoints = -1, rankCount = 0;;) // Initialise capPoints as -1 because we haven't found out what the highest value is yet { for (maxPoints = -1, roster = roster_list; roster != NULL; roster = roster->next) { if (capPoints >= 0 && roster->pkilldata->kPoints >= capPoints) // Next highest value must be below previous highest value continue; // (only if its not the very first highest value) else if (roster->pkilldata->kPoints > maxPoints) // See if its the highest value of this round maxPoints = roster->pkilldata->kPoints; } if (maxPoints <= 0) // Break out from it all if there aren't any more records that are less than cap points and less than 0 break; for (roster = roster_list; roster != NULL; roster = roster->next) { if ((pkOnly && !roster->clan->pkill) || (npkOnly && roster->clan->pkill)) continue; if (rankCount < 20 && roster->pkilldata->kPoints == maxPoints) // Go through all the players with the same point value as the current max value { rankCount++; if (!pkOnly && !npkOnly) sprintf( buf, "{B| %3s {B|{R %-3d {B|{x %s {B|{w %-18s {B|{Y %-6ld {B|{g %-6d {B|{r %-6d {B|{g %-6d {B|{r %-6d {B|\n\r", roster->clan->pkill ? "{YYes" : "{yNo ", rankCount, end_string(roster->clan->c_name, MAX_CLAN_WHO_LENGTH ), (chRoster && roster == chRoster) ? "You" : capitalize( roster->name), roster->pkilldata->kPoints, roster->pkilldata->kills, roster->pkilldata->deaths, roster->pkilldata->wins, roster->pkilldata->losses); else sprintf( buf, "{B|{R %-3d {B|{x %s {B|{w %-18s {B|{Y %-6ld {B|{g %-6d {B|{r %-6d {B|{g %-6d {B|{r %-6d {B|\n\r", rankCount, end_string(roster->clan->c_name, MAX_CLAN_WHO_LENGTH ), (chRoster && roster == chRoster) ? "You" : capitalize( roster->name), roster->pkilldata->kPoints, roster->pkilldata->kills, roster->pkilldata->deaths, roster->pkilldata->wins, roster->pkilldata->losses); add_buf(output, buf); } } if (rankCount >= 20) // Only top twenty break; capPoints = maxPoints; } if (pkOnly || npkOnly) add_buf( output, "{B+--------------------------------------------------------------------------------------+{x\n\r"); else add_buf( output, "{B+--------------------------------------------------------------------------------------------+{x\n\r"); if (rankCount > 0) page_to_char(output->string, ch); else send_to_char( "There isn't a top 20! Go kill someone and become number one!\n\r", ch); free_buf(output); } /* Display the table of pk history */ void do_pk_history(CHAR_DATA *ch, char *argument) { BUFFER *output; char buf[MAX_STRING_LENGTH], temp[MAX_STRING_LENGTH], flgs[30]; int i, invalid; if (max_pkhist_entries <= 0) { send_to_char("There isn't any PK history.\n\r", ch); return; } output = new_buf(); add_buf( output, "{B+-{G Pkill History {B--------------------------------------------------------------------------------------------------+\n\r"); add_buf( output, "{B| {WFLG {B|{W Killer {B|{W Clan {B|{W Lvl {B|{W Victim {B|{W Clan {B|{W Lvl {B|{W Time {B|\n\r"); for (i = 0; i < max_pkhist_entries; i++) { if (pkhist_table[i].killer == NULL || pkhist_table[i].victim == NULL) continue; if (IS_SET( pkhist_table[i].flags, PKHIST_INVALID ) || (pkhist_table[i].time + TIME_SPAMKILL_LIMIT) < current_time) invalid = TRUE; else invalid = FALSE; sprintf(temp, "%s", pkhist_table[i].kClan ? end_string( pkhist_table[i].kClan->c_name, MAX_CLAN_WHO_LENGTH ) : end_string("Unknown", MAX_CLAN_WHO_LENGTH )); sprintf( flgs, "%s%s%s", IS_SET( pkhist_table[i].flags, PKHIST_ARENA ) ? "{CA" : " ", (invalid || IS_SET( pkhist_table[i].flags, PKHIST_CHINVALID )) ? "{RI" : "{GV", (IS_SET( pkhist_table[i].flags, PKHIST_CHINVALID ) && !invalid) ? "{rE" : " "); sprintf( buf, "{B| %s {B|{w %-17.17s {B|{x %s {B|{R %-3d {B|{w %-17.17s {B|{w %s {B|{R %-3d {B|{w %24.24s {B|\n\r", flgs, pkhist_table[i].killer->name, temp, pkhist_table[i].kLevel, pkhist_table[i].victim->name, pkhist_table[i].vClan ? end_string( pkhist_table[i].vClan->c_name, MAX_CLAN_WHO_LENGTH ) : end_string("Unknown", MAX_CLAN_WHO_LENGTH ), pkhist_table[i].vLevel, ctime(&(pkhist_table[i].time))); add_buf(output, buf); } add_buf( output, "{B+------------------------------------------------------------------------------------------------------------------+{x\n\r"); page_to_char(output->string, ch); free_buf(output); } /*************************************** CHECKS ***************************************/ bool is_enemy(CHAR_DATA *ch, CHAR_DATA *vch) { CLAN_DATA *chClan, *vchClan; chClan = get_clan_by_ch(ch); vchClan = get_clan_by_ch(vch); if (chClan == NULL || vchClan == NULL) return FALSE; if (chClan->independent || vchClan->independent) return FALSE; return chClan->enemy == vchClan; } bool clan_can_use(CHAR_DATA *ch, OBJ_DATA *obj) { return can_wear_clan_eq(ch, obj, FALSE ); } bool is_clan_obj(OBJ_DATA *obj) { return is_full_clan_obj(obj, NULL, FALSE ); } bool is_clan_obj_ind(OBJ_INDEX_DATA *pObj) { return is_full_clan_obj_index(pObj, NULL, FALSE ); } bool is_clead(CHAR_DATA *ch) { ROSTER_DATA *roster; GET_ROSTER( ch, roster ); if (roster == NULL) return TRUE; return roster->trust == TRUST_LDR; } bool is_clan(CHAR_DATA *ch) { return (!is_indep(ch)); } bool is_pkill(CHAR_DATA *ch) { CLAN_DATA *clan; if ((clan = get_clan_by_ch(ch)) == NULL) return FALSE; return clan->pkill; } bool is_indep(CHAR_DATA *ch) { CLAN_DATA *clan; if ((clan = get_clan_by_ch(ch)) == NULL) return TRUE; return clan->independent; } /* Check if the object index is part of the clan area and whether it is part of the clan specified (if applicable ) */ bool is_full_clan_obj_index(OBJ_INDEX_DATA *pObj, CLAN_DATA *clan, bool checkclan) { if (pObj == NULL || pObj->area == NULL) return FALSE; if (checkclan && clan == NULL) return FALSE; if (!checkclan && pObj->area == get_clan_area()) return TRUE; if (checkclan && pObj->vnum >= clan->vnum[0] && pObj->vnum <= clan->vnum[1]) return TRUE; return FALSE; } /* Check if the object is part of the clan area and whether it is part of the clan specified (if applicable ) */ bool is_full_clan_obj(OBJ_DATA *obj, CLAN_DATA *clan, bool checkclan) { if (obj == NULL || obj->pIndexData == NULL) return FALSE; return is_full_clan_obj_index(obj->pIndexData, clan, checkclan); } /* Check if the mob index is part of the clan area and whether it is part of the clan specified (if applicable ) */ bool is_clan_mob_index(MOB_INDEX_DATA *pMob, CLAN_DATA *clan, bool checkclan) { if (pMob == NULL || pMob->area == NULL) return FALSE; if (checkclan && clan == NULL) return FALSE; if (!checkclan && pMob->area == get_clan_area()) return TRUE; if (checkclan && pMob->vnum >= clan->vnum[0] && pMob->vnum <= clan->vnum[1]) return TRUE; return FALSE; } /* Check if the mob is part of the clan area and whether it is part of the clan specified (if applicable ) */ bool is_clan_mob(CHAR_DATA *mob, CLAN_DATA *clan, bool checkclan) { if (mob == NULL || mob->pIndexData == NULL) return FALSE; return is_clan_mob_index(mob->pIndexData, clan, checkclan); } bool is_clan_mob_type(CHAR_DATA *mob, CLAN_DATA *clan, int type) { if (mob->pIndexData == NULL || type >= CMOB_MAX) return FALSE; if (clan == NULL) if ((clan = get_clan_by_vnum(mob->pIndexData->vnum)) == NULL) return FALSE; if (clan->cMob[type] != NULL && clan->cMob[type] == mob->pIndexData) return TRUE; return FALSE; } /* Check if the room index is part of the clan area and whether it is part of the clan specified (if applicable ) */ bool is_clan_room(ROOM_INDEX_DATA *pRoom, CLAN_DATA *clan, bool checkclan) { CLAN_DATA *tclan; if (pRoom == NULL) return FALSE; if (checkclan && clan == NULL) return FALSE; tclan = get_clan_by_vnum(pRoom->vnum); if ((!checkclan && tclan != NULL) || (checkclan && tclan == clan)) return TRUE; return FALSE; } /* Check whether the two are in the same clan */ bool is_same_clan(CHAR_DATA *ch, CHAR_DATA *vch) { CLAN_DATA *chClan, *vchClan; chClan = get_clan_by_ch(ch); vchClan = get_clan_by_ch(vch); // Basically an npc check. if (chClan == NULL && vchClan == NULL) return FALSE; if ((chClan && chClan->independent) || (vchClan && vchClan->independent)) return FALSE; return (chClan == vchClan); } /* Check whether a person can kill another */ bool can_pkill_other(CHAR_DATA *ch, CHAR_DATA *vch, bool quiet) { ROSTER_DATA *chRoster, *vchRoster; int i; GET_ROSTER( ch, chRoster ); GET_ROSTER( vch, vchRoster ); if (chRoster == NULL || vchRoster == NULL) return TRUE; if (IS_IMMORTAL( ch ) && get_trust(ch) >= 108) return TRUE; // Both player killers if (chRoster->clan->pkill && vchRoster->clan->pkill) { if (!chRoster->clan->independent && chRoster->clan == vchRoster->clan) { if (!quiet) send_to_char("You cannot attack clan members.\n\r", ch); return FALSE; } // Newbie flag if they're not both flagged or unflagged, they can't fight if (!IS_SET( chRoster->flags, ROST_NEWBIE ) && IS_SET( vchRoster->flags, ROST_NEWBIE )) { if (!quiet) send_to_char("Trying to attack newbies, eh?\n\r", ch); return FALSE; } else if (IS_SET( chRoster->flags, ROST_NEWBIE ) && !IS_SET( vchRoster->flags, ROST_NEWBIE )) { if (!quiet) send_to_char( "Notnewbie yourself to fight with the Big Boys.\n\r", ch); return FALSE; } for (i = 0; i < max_pkhist_entries; i++) // Check spamkill { if (!pkhist_table[i].killer || !pkhist_table[i].victim || (pkhist_table[i].time + TIME_SPAMKILL_LIMIT) < current_time || IS_SET( pkhist_table[i].flags, PKHIST_INVALID )) continue; if (pkhist_table[i].killer == vchRoster && pkhist_table[i].victim == chRoster) { if (!quiet) send_to_char( "Because you are the initiator, your victim will be able to attack you again.\n\r", ch); SET_BIT( pkhist_table[i].flags, PKHIST_INVALID ); } if (pkhist_table[i].kClan && pkhist_table[i].vClan && !is_indep(ch) && pkhist_table[i].vClan == chRoster->clan && pkhist_table[i].kClan == vchRoster->clan && !IS_SET( pkhist_table[i].flags, PKHIST_CHINVALID )) { if (!quiet) send_to_char( "The clan members of the person you are attacking may now enter your clan hall.\n\r", ch); SET_BIT( pkhist_table[i].flags, PKHIST_CHINVALID ); } else if (pkhist_table[i].killer == chRoster && pkhist_table[i].victim == vchRoster) { if (!quiet) send_to_char( "You have already killed that person in the last hour.\n\r", ch); return FALSE; // ch has killed vch in the last hour so he can't attack again. } else if (pkhist_table[i].victim == vchRoster && pkhist_table[i].kClan && pkhist_table[i].kClan == chRoster->clan) { if (!quiet) send_to_char( "A member of your clan has already killed that person in the last hour.\n\r", ch); return FALSE; // Someone in ch's clan has killed vict already } } return TRUE; } //First case: killer=nonpk, vict=nonpk/pk. Second case: killer=pk, vict=nonpk if (!quiet && !chRoster->clan->pkill) send_to_char( "You're non-pk so you cannot fight other players outside the arena.\n\r", ch); else if (!quiet && !vchRoster->clan->pkill) send_to_char( "They're non-pk and cannot be fought outside the arena.\n\r", ch); return FALSE; } bool can_pkill(CHAR_DATA *ch, CHAR_DATA *victim) { if (!is_pkill(ch) || !is_pkill(victim)) return FALSE; if (IS_SET (victim->act, PLR_TWIT)) return TRUE; if (victim->pcdata->tier < 2 && ch->pcdata->tier > 2) { send_to_char("Pick on someone your own size.\n\r", ch); return FALSE; } if (ch->pcdata->tier < 2 && victim->pcdata->tier > 2) { send_to_char( "They would crush you in moments, better advance first.\n\r", ch); return FALSE; } if (ch->level > victim->level + 10) { send_to_char("Pick on someone your own size.\n\r", ch); return FALSE; } if (ch->level < victim->level - 10) { send_to_char("Pick on someone your own size.\n\r", ch); return FALSE; } return can_pkill_other(ch, victim, FALSE ); } /* See whether person can wear the obj * Remove pieces if over the limit */ bool can_wear_clan_eq(CHAR_DATA *ch, OBJ_DATA *obj, bool remove) { ROSTER_DATA *roster; OBJ_DATA *checkObj; int max, count; if (IS_IMMORTAL( ch ) || !is_full_clan_obj(obj, NULL, FALSE )) return TRUE; GET_ROSTER( ch, roster ); // No need for null checks after because those are handled by get_eq_wear_max if ((max = clan_eq_wear_max(ch)) <= 0 || !is_full_clan_obj(obj, roster->clan, TRUE )) return FALSE; for (count = 0, checkObj = ch->carrying; checkObj != NULL; checkObj = checkObj->next_content) { if (!is_full_clan_obj(checkObj, NULL, FALSE ) || checkObj->wear_loc == WEAR_NONE) continue; if (is_full_clan_obj(checkObj, roster->clan, TRUE )) { count++; if (count >= max) { if (!remove) return FALSE; unequip_char(ch, checkObj); act("$p slips off you.", ch, checkObj, NULL, TO_CHAR ); act("$p slips off $n.", ch, checkObj, NULL, TO_ROOM ); } } else { unequip_char(ch, checkObj); // Bust the naughty players who keep another clans eq on act("$p slips off you.", ch, checkObj, NULL, TO_CHAR ); act("$p slips off $n.", ch, checkObj, NULL, TO_ROOM ); } } return TRUE; } /* Update the spamkill/pk history table */ void update_pkhist(ROSTER_DATA *chRoster, ROSTER_DATA *vchRoster, bool arena) { PKHIST_DATA *pkhist; max_pkhist_entries++; if (pkhist_table == NULL && (pkhist = malloc(sizeof(PKHIST_DATA))) == NULL) // If there aren't any entries in the table { printf_debug("Error allocating memory for pkhist_table, sizeof %d", sizeof(PKHIST_DATA)); return; } else if ((pkhist = realloc(pkhist_table, sizeof(PKHIST_DATA) * max_pkhist_entries)) == NULL) { printf_debug("Error reallocating memory for pkhist_table, sizeof %d", sizeof(PKHIST_DATA) * max_pkhist_entries); return; } pkhist[max_pkhist_entries - 1].killer = chRoster; pkhist[max_pkhist_entries - 1].kClan = chRoster->clan; pkhist[max_pkhist_entries - 1].victim = vchRoster; pkhist[max_pkhist_entries - 1].vClan = vchRoster->clan; pkhist[max_pkhist_entries - 1].time = current_time; pkhist[max_pkhist_entries - 1].flags = arena ? PKHIST_ARENA|PKHIST_INVALID : 0; if (vchRoster->character) // Should always be true, but just in case pkhist[max_pkhist_entries - 1].vLevel = vchRoster->character->level + tier_level_bonus(vchRoster->character); else pkhist[max_pkhist_entries - 1].vLevel = 0; if (chRoster->character) // Should always be true, but just in case pkhist[max_pkhist_entries - 1].kLevel = chRoster->character->level + tier_level_bonus(chRoster->character); else pkhist[max_pkhist_entries - 1].kLevel = 0; pkhist_table = pkhist; save_pkhist_data(); } // Helper function. int rank_kill_ch(CHAR_DATA *ch, CHAR_DATA *vch, bool arena, bool simulate) { if (IS_NPC(ch) || IS_NPC(vch)) return 0; ROSTER_DATA *chRoster, *vchRoster; GET_ROSTER(ch, chRoster); GET_ROSTER(vch, vchRoster); int result = rank_kill(chRoster, vchRoster, arena, simulate); if (!simulate && result > 0) { char buf[MAX_STRING_LENGTH]; sprintf(buf, "You have won {Y%d{x %s points!\r\n", result, arena ? "arena" : "pkill"); send_to_char(buf, ch); // Pkill highlanders gain points only outside arena, non-pkill, only inside arena. /* if (ch->class == CLASS_BARBARIAN) { // OLD //ch->pcdata->power[POWER_POINTS] = ((ch->pcdata->arank - 1500) * 100) // + 5000; //NEW - CHECK ch->pcdata->power[POWER_POINTS] = chRoster->pkilldata->kPoints; update_power(ch); } if (vch->class == CLASS_BARBARIAN) { // OLD //vch->pcdata->power[POWER_POINTS] = ((vch->pcdata->arank - 1500) // * 100) + 5000; //NEW - CHECK vch->pcdata->power[POWER_POINTS] = vchRoster->pkilldata->kPoints; update_power(vch); } */ } return result; } /* Reward and return the number of points a player gets for killing someone else */ int rank_kill(ROSTER_DATA *chRoster, ROSTER_DATA *vchRoster, bool arena, bool simulate) { DESCRIPTOR_DATA *d; int result;//, max = 500; if (chRoster == NULL || vchRoster == NULL) return 0; if (chRoster->clan->id == CLAN_IMMORTAL || vchRoster->clan->id == CLAN_IMMORTAL || chRoster == vchRoster) return 0; if ((chRoster->character && IS_IMMORTAL( chRoster->character )) || (vchRoster->character && IS_IMMORTAL( vchRoster->character ))) return 0; if (chRoster->clan == vchRoster->clan && !chRoster->clan->independent) return 0; // If we're pkill and in the arena, we don't get points. if (chRoster->clan->pkill && arena) return 0; /* What was i smoking? if ((chRoster->clan->pkill && vchRoster->clan->pkill && !arena) || (!chRoster->clan->pkill && !vchRoster->clan->pkill)) max += 2000; result = (((vchRoster->pkilldata->kPoints * 2 + vchRoster->dPoints / 6) * 115 / 100) - (chRoster->pkilldata->kPoints * 2 + chRoster->dPoints / 6)) / 3; */ result = UMAX(3, vchRoster->pkilldata->kPoints*4/10); if (chRoster->clan->enemy && vchRoster->clan->enemy && chRoster->clan->enemy == vchRoster->clan && vchRoster->clan->enemy == chRoster->clan) { // max = max * 2; result = (result*13) / 100; } // result = URANGE( 10, result, max ); if (!simulate && is_main_server()) update_pkhist(chRoster, vchRoster, arena); if (!simulate) { if (vchRoster->bounty > 0 && chRoster->character && ((!vchRoster->clan->pkill && arena) || !arena)) { char buf[MAX_STRING_LENGTH]; int len = strlen(vchRoster->name); sprintf( buf, "{CBOUNTY {r>{R>{r> {R%s{W has {GCOLLECTED{W the {Y%ld{W platinum bounty on {R%s'%s{W head!{x\n\r", chRoster->name, vchRoster->bounty, vchRoster->name, vchRoster->name[len - 1] == 's' ? "" : "s"); for (d = descriptor_list; d != NULL; d = d->next) { if (d->connected != CON_PLAYING || d->character == NULL || IS_SET( d->character->comm, COMM_QUIET )) continue; send_to_char(buf, d->character); } chRoster->character->platinum += vchRoster->bounty; vchRoster->bounty = 0; } chRoster->pkilldata->kPoints += result; chRoster->pkilldata->kills++; chRoster->pkilldata->wins++; chRoster->clan->pkilldata->kills++; chRoster->clan->pkilldata->wins++; // Only adjust victim's stuff only if pkill and out of arena or nopkill and in arena. if (!vchRoster->clan->pkill || !arena) { vchRoster->pkilldata->kPoints = UMAX(0, vchRoster->pkilldata->kPoints - UMAX(3, vchRoster->pkilldata->kPoints*25/100)); vchRoster->clan->pkilldata->deaths++; vchRoster->clan->pkilldata->losses++; vchRoster->pkilldata->deaths++; vchRoster->pkilldata->losses++; } if (IS_SET(chRoster->flags, ROST_NEWBIE) && chRoster->pkilldata->kPoints >= 10) { REMOVE_BIT(chRoster->flags, ROST_NEWBIE); if (chRoster->character) send_to_char("{RYour newbie flag has expired. You are now a FULL player-killer.\n\r", chRoster->character); save_roster_data(chRoster); } } return result; } void clan_entry_trigger(CHAR_DATA *ch, bool greet) { ROSTER_DATA *chRoster; CLAN_DATA *clan; CHAR_DATA *guard; char buf[MAX_STRING_LENGTH]; int i; if (IS_NPC( ch ) || ch->in_room == NULL) return; if ((clan = get_clan_by_vnum(ch->in_room->vnum)) == NULL) return; GET_ROSTER( ch, chRoster ); for (i = 0; i < max_pkhist_entries; i++) // Check spamkill { if (!pkhist_table[i].killer || !pkhist_table[i].victim || !pkhist_table[i].kClan || (pkhist_table[i].time + TIME_SPAMKILL_LIMIT) < current_time || IS_SET( pkhist_table[i].flags, PKHIST_INVALID )) continue; if (pkhist_table[i].victim == chRoster && pkhist_table[i].kClan == clan) { sprintf( buf, "{REven though you were killed by a member of the {x%s{R clan within the hour, for trespassing you can now be killed again.{x\n\r", strip_bespaces(clan->c_name)); send_to_char(buf, ch); SET_BIT( pkhist_table[i].flags, PKHIST_INVALID ); } } for (guard = ch->in_room->people; guard != NULL; guard = guard->next_in_room) if (IS_NPC( guard ) && is_clan_mob_type(guard, clan, CMOB_GUARD )) break; if (guard == NULL) return; if (is_same_clan(ch, guard)) { if (greet) { sprintf(buf, "Greetings, %s", ch->name); do_say(guard, buf); } return; } if (get_trust(ch) >= SUPREME) return; if (ch->level <= 75 || IS_AFFECTED( ch, AFF_CHARM )) { switch (number_range(0, 5)) { case 0: strcpy(buf, "$n{x says '{mThis area is restricted friend.{x'"); break; case 1: strcpy(buf, "$n{x looks at you and gestures silently."); break; case 2: strcpy(buf, "$n{x asks '{mEver dance with the devil in the pale moon light?{x'"); break; case 3: strcpy(buf, "$n{x says '{mBegone from this place.{x'"); break; case 4: strcpy(buf, "$n{x says '{mLeave now or suffer.{x'"); break; case 5: strcpy(buf, "$n{x says '{mWelcome, too bad you cannot stay.{x'"); break; default: strcpy(buf, "$n{x says '{mAdios.{x'"); break; } act(buf, guard, NULL, ch, TO_ROOM ); char_from_room(ch); char_to_room(ch, get_room_index(VNUM_MARKET_SQUARE)); do_look(ch, "auto"); return; } sprintf(buf, "Help! I'm being attacked by %s!", guard->short_descr); do_yell(ch, buf); do_ctalk(guard, "Intruder! Intruder!"); multi_hit(guard, ch, TYPE_UNDEFINED ); if (IS_SET( ch->plyr,PLAYER_RUNNING )) REMOVE_BIT( ch->plyr,PLAYER_RUNNING ); } /************************************* CLAN SKILLS ************************************/ /* Interpreter for clan skill commands, called at the end of interpret * if ch isn't an NPC, is in a clan and the command they entered wasn't * picked up by interpret. Returns true if valid clanskill found. */ bool interpret_clan_cmd(CHAR_DATA *ch, char *command, char *argument) { ROSTER_DATA *roster; int cmd, total; GET_ROSTER( ch, roster ); if (!roster || roster->pkilldata == NULL) return FALSE; total = get_total_points(roster); for (cmd = 0; clan_skill_table[cmd].func != NULL; cmd++) { if (get_trust(ch) < SUPREME && (!clan_has_skill(roster->clan, cmd) || total < clan_skill_table[cmd].points)) continue; if (str_prefix(command, clan_skill_table[cmd].cmd)) continue; if (ch->position < clan_skill_table[cmd].position) { switch (ch->position) { case POS_DEAD: send_to_char("Lie still; you are DEAD.\n\r", ch); break; case POS_MORTAL: case POS_INCAP: send_to_char("You are hurt far too bad for that.\n\r", ch); break; case POS_STUNNED: send_to_char("You are too stunned to do that.\n\r", ch); break; case POS_SLEEPING: send_to_char("In your dreams, or what?\n\r", ch); break; case POS_RESTING: send_to_char("Nah... You feel too relaxed...\n\r", ch); break; case POS_SITTING: send_to_char("Better stand up first.\n\r", ch); break; case POS_FIGHTING: send_to_char("No way! You are still fighting!\n\r", ch); break; } return FALSE; } (*clan_skill_table[cmd].func)(ch, argument); return TRUE; } return FALSE; } /* The following clan skills were written originally by Gabe Volker and rewritten by Deryck Arnold */ void do_adrenaline(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_adrenaline)) { affect_strip(ch, gsn_adrenaline); send_to_char("Your fury subsides.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_adrenaline; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = ch->level * 6 / 10; affect_to_char(ch, &af); send_to_char( "You feel the adrenaline being pumped through your veins.\n\r", ch); act("$n's eyes turn red and roll back into $n's skull!", ch, NULL, NULL, TO_ROOM ); } void do_battle_fury(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_battle_fury)) { affect_strip(ch, gsn_battle_fury); send_to_char("Your battle fury subsides.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_battle_fury; af.level = ch->level; af.bitvector = 0; af.duration = -1; af.modifier = ch->level / 7; af.location = APPLY_DAMROLL; affect_to_char(ch, &af); af.location = APPLY_HITROLL; affect_to_char(ch, &af); af.location = APPLY_AC; af.bitvector = SHD_STEEL; af.modifier = -ch->level / 7; affect_to_char(ch, &af); send_to_char( "Your eyes invert for a moment as you are consumed by fury!\n\r", ch); act("$n gets a wicked look in $s eyes!", ch, NULL, NULL, TO_ROOM ); } void do_bloodlust(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_bloodlust)) { affect_strip(ch, gsn_bloodlust); send_to_char("Your lust for blood subsides.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_bloodlust; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = ch->level / 6; affect_to_char(ch, &af); af.location = APPLY_HITROLL; affect_to_char(ch, &af); af.location = APPLY_AC; af.modifier = -ch->level / 6; affect_to_char(ch, &af); send_to_char("A terrible lust for blood begins to take hold.\n\r", ch); send_to_char("Your eyes burn red as the lust overwhelms you!\n\r", ch); act("$n's eyes turn red as the bloodlust overwhelms them!", ch, NULL, NULL, TO_ROOM ); act("$n's eyes turn bloodshot!", ch, NULL, NULL, TO_ROOM ); } /* Hides the GreenBlade from mortal eyes * GreenBlade appears as a green cloaked figure * Only Immortals and Clan Members see the real name when concealed * Restricts: * -None * Benefits: * - General, lower Ac, small hit/dam, bit of regen. * - Overall vanishment * Functionality: * - Employ Identity or Morph * - Use gsn_concealClan1 */ void do_conceal(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; /*if (ch->morph_form[0] && ch->morph_form[0] != MORPH_CONCEAL) { send_to_char( "You cannot conceal yourself while in another morphed form.\n\r", ch); return; }*/ if (is_affected(ch, gsn_conceal)) affect_strip(ch, gsn_conceal); if (is_affected(ch, gsn_conceal2)) affect_strip(ch, gsn_conceal2); if (is_affected(ch, gsn_concealClan2)) affect_strip(ch, gsn_concealClan2); if (ch->morph_form[0] == MORPH_CONCEAL || is_affected(ch, gsn_concealClan1)) { affect_strip(ch, gsn_concealClan1); if (ch->long_descr != NULL && ch->long_descr[0] != '\0') { free_string(ch->long_descr); ch->long_descr = str_dup(""); } ch->morph_form[0] = 0; send_to_char("You expose yourself to the lands.\n\r", ch); return; } send_to_char("You conceal your presence.\n\r", ch); act("$n wraps a cloak around $mself.", ch, NULL, NULL, TO_ROOM ); // Put up here to make sure $n is a name, not a morphed name af.where = TO_AFFECTS; af.type = gsn_concealClan1; af.level = ch->level; af.location = APPLY_MORPH_FORM; af.modifier = MORPH_CONCEAL; af.bitvector = AFF_SNEAK; af.duration = -1; affect_to_char(ch, &af); af.bitvector = 0; af.location = APPLY_HITROLL; af.modifier = ch->level / 8; affect_to_char(ch, &af); af.location = APPLY_DAMROLL; affect_to_char(ch, &af); } void do_divide(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_divide)) { affect_strip(ch, gsn_divide); send_to_char("The divide closes slowly.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_divide; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = ch->level / 7; affect_to_char(ch, &af); af.location = APPLY_HITROLL; affect_to_char(ch, &af); af.location = APPLY_AC; af.bitvector = SHD_STONE; af.modifier = -ch->level / 7; affect_to_char(ch, &af); act("$n's body becomes one with the divide!", ch, NULL, NULL, TO_ROOM); send_to_char("A great divide engulfs you!\n\r", ch); } void do_faith(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim; int chance = number_range(75, 100), dam = 0; if (ch->stunned > 0) { send_to_char("You're far too stunned to proclaim your faith!\n\r", ch); return; } if ((victim = ch->fighting) == NULL) { if (argument[0] == '\0') { send_to_char( "Who would you like to proclaim your blind faith towards?\n\r", ch); return; } if ((victim = get_char_room(ch, argument)) == NULL) { send_to_char("You proclaim your faith aloud to the room.\n\r", ch); return; } } if (victim == ch) { send_to_char( "You have already proven your faith towards yourself.\n\r", ch); return; } if (ch->mana < 100) { send_to_char("You don't have enough energy to muster.\n\r", ch); return; } if (is_safe(ch, victim)) return; if (number_percent() < chance) { dam = dice(ch->level, 13); if (saves_spell(ch->level, victim, DAM_LIGHT)) dam = dam * 3 / 4; ch->mana -= 100; send_to_char( "You call upon your faith and suddenly the room erupts in blinding light!\n\r", ch); act( "$n utters words of his faith and suddenly the room erupts in blinding light!", ch, NULL, NULL, TO_ROOM ); spell_blindness(gsn_blindness, ch->level * 3 / 2, ch, (void *) victim, TARGET_CHAR ); } else { ch->mana -= 50; send_to_char("You momentarily lose faith.\n\r", ch); act("$n utters words of his faith but falters halfway!", ch, NULL, NULL, TO_ROOM ); } damage(ch, victim, dam, gsn_blind_faith, DAM_LIGHT, TRUE, 0); WAIT_STATE( ch, PULSE_VIOLENCE ) ;} void do_modi(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (argument[0] == '\0') { send_to_char("Syntax: modi anger - damroll boost\n\r" " modi concentration - hitroll boost\n\r" " modi calm - removes both effects\n\r", ch); return; } if (!str_prefix(argument, "anger")) { if (is_affected(ch, gsn_concentration)) { affect_strip(ch, gsn_concentration); send_to_char("Your concentration diminishes.\n\r", ch); } if (is_affected(ch, gsn_modis_anger)) affect_strip(ch, gsn_modis_anger); af.where = TO_AFFECTS; af.type = gsn_modis_anger; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = ch->level * 4 / 10; affect_to_char(ch, &af); send_to_char( "You release your stored energy and bellow a mighty battlecry!\n\r", ch); send_to_char("You feel the Wrath of Modi enter your body!\n\r", ch); act("$n bellows a mighty battlecry and begins frothing at the mouth.", ch, NULL, NULL, TO_ROOM ); act("$n's eyes turn blood red.", ch, NULL, NULL, TO_ROOM ); } else if (!str_prefix(argument, "calm")) { if (is_affected(ch, gsn_modis_anger)) { affect_strip(ch, gsn_modis_anger); send_to_char("Your anger subsides.\n\r", ch); } if (is_affected(ch, gsn_concentration)) // Not using else/if in case somehow someone has both affects. { affect_strip(ch, gsn_concentration); send_to_char("Your concentration diminishes.\n\r", ch); } send_to_char("You feel calm and collected.\n\r", ch); } else if (!str_prefix(argument, "concentration")) { if (is_affected(ch, gsn_modis_anger)) { affect_strip(ch, gsn_modis_anger); send_to_char("Your anger subsides.\n\r", ch); } if (is_affected(ch, gsn_concentration)) affect_strip(ch, gsn_concentration); af.where = TO_AFFECTS; af.type = gsn_concentration; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_HITROLL; af.modifier = ch->level * 4 / 10; affect_to_char(ch, &af); send_to_char( "You concentrate on the determination of Modi and your aim improves!\n\r", ch); act("$n's eyes turn light blue with white steaks.", ch, NULL, NULL, TO_ROOM ); } else do_modi(ch, ""); } void do_shadow_form(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_shadow_form)) { affect_strip(ch, gsn_shadow_form); send_to_char("The shadows begin to subside.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_shadow_form; af.level = ch->level; af.duration = -1; af.location = APPLY_AC; af.modifier = -ch->level * 6 / 10; af.bitvector = 0; affect_to_char(ch, &af); send_to_char("The shadows form all around you!\n\r", ch); act("The shadows form all around $n!", ch, NULL, NULL, TO_ROOM); } void do_solar_flare(CHAR_DATA *ch, char *argument) { CHAR_DATA *victim, *victim_next; if (ch->in_room == NULL) return; if (ch->stunned > 0) { send_to_char("You're far too stunned to hurl anything!\n\r", ch); return; } act("$n hurls a solar flare into the room! {Y{zF{W{zL{Y{zA{W{zS{Y{zH{x!!!", ch, NULL, NULL, TO_ROOM ); act("You hurl a solar flare into the room! {Y{zF{W{zL{Y{zA{W{zS{Y{zH{x!!!", ch, NULL, NULL, TO_CHAR ); if (number_percent() < 2) { act("You accidentally stare at the flare as it explodes!", ch, NULL, NULL, TO_CHAR ); spell_blindness(gsn_blindness, ch->level * 3 / 4, ch, (void *) ch, TARGET_CHAR ); } for (victim = ch->in_room->people; victim != NULL; victim = victim_next) { victim_next = victim->next_in_room; if (is_safe_quiet(ch, victim)) continue; if (number_percent() < 80) spell_blindness(gsn_blindness, ch->level * 3 / 4, ch, (void *) victim, TARGET_CHAR ); if (victim->fighting == NULL) multi_hit(victim, ch, TYPE_UNDEFINED ); } WAIT_STATE( ch, PULSE_VIOLENCE ) ;} void do_vmight(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; if (is_affected(ch, gsn_vmight)) { affect_strip(ch, gsn_vmight); send_to_char("The Might of the Vanir fades from your mind.\n\r", ch); return; } af.where = TO_AFFECTS; af.type = gsn_vmight; af.level = ch->level; af.duration = -1; af.bitvector = 0; af.location = APPLY_DAMROLL; af.modifier = ch->level / 5; affect_to_char(ch, &af); af.bitvector = SHD_STONE; af.location = APPLY_AC; af.modifier = -ch->level / 5; affect_to_char(ch, &af); send_to_char( "You begin to feel the might of the Vanir all around you!\n\r", ch); act("$n begins channeling the Might of the Vanir!", ch, NULL, NULL, TO_ROOM ); act("$n's eyes fade to black!", ch, NULL, NULL, TO_ROOM ); } void do_wform(CHAR_DATA *ch, char *argument) { AFFECT_DATA af; /*if (ch->morph_form[0] && ch->morph_form[0] != MORPH_CONCEAL2) { send_to_char( "You cannot transform yourself while in another morphed form.\n\r", ch); return; }*/ if (is_affected(ch, gsn_conceal)) affect_strip(ch, gsn_conceal); if (is_affected(ch, gsn_conceal2)) affect_strip(ch, gsn_conceal2); if (is_affected(ch, gsn_concealClan1)) affect_strip(ch, gsn_concealClan1); if (ch->morph_form[0] == MORPH_CONCEAL2 || is_affected(ch, gsn_concealClan2)) { affect_strip(ch, gsn_concealClan2); if (ch->long_descr != NULL && ch->long_descr[0] != '\0') { free_string(ch->long_descr); ch->long_descr = str_dup(""); } ch->morph_form[0] = 0; send_to_char("You transform back into a human.\n\r", ch); return; } send_to_char("You transform into a wolf.\n\r", ch); act("$n's body spasms slightly as $e turns into a wolf!", ch, NULL, NULL, TO_ROOM ); // Put up here to make sure $n is a name, not a morphed name af.where = TO_AFFECTS; af.type = gsn_concealClan2; af.level = ch->level; af.location = APPLY_MORPH_FORM; af.modifier = MORPH_CONCEAL2; af.bitvector = AFF_SNEAK; af.duration = -1; affect_to_char(ch, &af); af.bitvector = 0; af.location = APPLY_HITROLL; af.modifier = ch->level / 8; affect_to_char(ch, &af); af.location = APPLY_DAMROLL; affect_to_char(ch, &af); } /******************************** INTEGRATION FUNCTIONS *******************************/ void make_rosters(CHAR_DATA *ch, char *argument) { ROSTER_DATA *roster; FILE *fp; char name[MAX_STRING_LENGTH]; int played; if (str_cmp(ch->name, "Nico")) { send_to_char("Restricted command.\n\r", ch); return; } if ((fp = fopen("rostlist.txt", "r")) == NULL) { send_to_char("No rostlist.\n\r", ch); return; } while (!feof(fp)) { strcpy(name, fread_word(fp)); if (name[0] == '#') break; roster = new_roster_data(TRUE); free_string(roster->name); roster->name = str_dup(capitalize(name)); roster->pkilldata = new_pkill_data(); roster->last_login = current_time; if (fread_number(fp) > 0) roster->clan = get_clan_by_id(CLAN_LONER); played = fread_number(fp); if (fread_number(fp) > 0) { SET_BIT( roster->flags, ROST_NEWBIE ); // roster->newbie_time = current_time + (TIME_NEWBIE_GRACE * played // /TIME_HOUR); } if (fread_number(fp) > 0) roster->clan = get_clan_by_id(CLAN_IMMORTAL); } update_all_rosters(); fclose(fp); } /* Required to make sure everyone stays pk/nonpk after change void prep_rosters( CHAR_DATA *ch, char *argument ) { CHAR_DATA *vch; FILE *fp, *fpList, *fpOut; char name[MAX_STRING_LENGTH]; if ( str_cmp( ch->name, "Nico" ) ) { send_to_char( "Restricted command.\n\r", ch ); return; } */// system( "dir -1 ../player/*/* > ../player/names.txt" ); /* if ( (fpList = fopen( "../player/names.txt", "a" )) == NULL ) { send_to_char( "Error reading names.txt for writing", ch ); return; } fprintf( fpList, "#\n" ); fclose( fpList ); if ( (fpList = fopen( "../player/names.txt", "r" )) == NULL ) { send_to_char( "Error reading names.txt for reading", ch ); return; } if ( (fpOut = fopen( "rostlist.txt", "w" )) == NULL ) { send_to_char( "Error opening rostlist.txt for writing", ch ); fclose( fpList ); return; } while ( !feof( fpList ) ) { strcpy( name, fread_word( fpList ) ); if ( name[0] == '#' ) break; vch = new_char( ); vch->pcdata = new_pcdata( ); if ( ( fp = fopen( name, "r" ) ) != NULL ) { char *word = fread_word( fp ); if ( !str_cmp( word, "#PLAYER" ) ) fread_char( vch, fp); fclose( fp ); } if ( vch->name[0] == '\0' || !str_cmp( vch->name, "Nico" ) ) // Stops dual rosters for me { free_pcdata( vch->pcdata ); free_char( vch ); continue; } fprintf( fpOut, "%s %d %d %d %d\n", vch->name, clan_table[vch->clan].pkill, vch->played, IS_SET( vch->plyr, PLAYER_NEWBIE ) ? 1 : 0, IS_IMMORTAL( vch ) ? 1 : 0 ); free_pcdata( vch->pcdata ); free_char( vch ); } fclose( fpList ); fprintf( fpOut, "#\n" ); fclose( fpOut ); unlink( "../player/names.txt" ); }*/