/**************************************************************************/
// oedit.cpp - olc object editor
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and 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) *
* >> Oblivion 1.2 is copyright 1996 Wes Wagner *
**************************************************************************/
#include "include.h" // dawn standard includes
#include "olc.h"
#include "security.h"
DECLARE_OLC_FUN( oedit_create );
void do_classlist( char_data *ch, char *);
/**************************************************************************/
extern gameset_value_type gameset_value[];
/**************************************************************************/
void do_material_list( char_data *ch, char *argument)
{
name_linkedlist_type* materials_list=NULL, *plist;
OBJ_INDEX_DATA *pObjIndex;
int vnum,count;
BUFFER *output;
char buf[MIL];
if(IS_NULLSTR(argument)){
logf("do_material_list(): Sorting materials");
// add all objects to the linked list, duplicates=false
for(vnum=0; vnum<MAX_KEY_HASH; vnum ++){
count=0;
for ( pObjIndex = obj_index_hash[vnum];
pObjIndex != NULL;
pObjIndex = pObjIndex->next )
{
count++;
addlist(&materials_list,pObjIndex->material, 0, false, false);
if(count>20000){
bugf("Count=%5d, objvnum=%d", count, pObjIndex->vnum);
}
}
}
logf("do_material_list(): Displaying materials to buffer");
// go thru displaying all objects
output = new_buf();
count=0;
for(plist=materials_list;plist; plist=plist->next){
sprintf(buf, "%3d> %s\n", ++count, plist->name);
add_buf( output, buf );
}
logf("do_material_list(): Sending buffer to player");
ch->printlnf( "%d material%s total.",
count,
count==1 ? "" : "s" );
ch->sendpage(buf_string(output));
free_buf(output);
}else{
// do a search for a specified item
count=0;
output = new_buf();
for(vnum=0; vnum<33000; vnum++){
pObjIndex =get_obj_index(vnum);
if(pObjIndex){
if(is_name(argument,pObjIndex->material)){
sprintf(buf, "%3d> [%5d] %s `Smaterial='%s'`x\n",
++count, pObjIndex->vnum,
pObjIndex->short_descr, pObjIndex->material);
add_buf( output, buf );
}
}
if(count>400){
ch->println( "You can only list up to 400 items at once, be more specific." );
break;
}
}
// display the list to the character
ch->printlnf( "Displaying %d material%s total.",
count,
count==1 ? "" : "s" );
ch->sendpage(buf_string(output));
free_buf(output);
}
}
/**************************************************************************/
void do_oedit( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
char arg1[MSL];
int value;
// do security checks
if (!HAS_SECURITY(ch, 2))
{
ch->println( "You must have an olc security 2 or higher to use this command." );
return;
}
argument = one_argument( argument, arg1 );
if ( is_number( arg1 ) )
{
value = atoi( arg1 );
if ( !( pObj = get_obj_index( value )))
{
ch->println( "OEdit: That vnum does not exist." );
return;
}
// officially reserved vnum range
if(value<500){
ch->println("Warning: all mobs, rooms and objects below vnum 500 are officially reserved for the dawn codebase.");
if(!HAS_SECURITY(ch,9)){
ch->println("As a result of this reservation, only those with security 9 can edit in that vnum range.");
return;
}
}
if ( !IS_BUILDER( ch, pObj->area, BUILDRESTRICT_OBJECTS) )
{
ch->println( "Insufficient security to modify object." );
return;
}
ch->desc->pEdit = (void *)pObj;
ch->desc->editor = ED_OBJECT;
ch->wraplnf( "`=rYou are now editing object: '`r%s`=r' vnum: `Y%d`x",
pObj->short_descr, pObj->vnum);
ch->println( "`=rType `=Cdone`=r to finish editing." );
return;
}
else
{
if ( !str_cmp( arg1, "create" ) )
{
value = atoi( argument );
if ( argument[0] == '\0' || value == 0 )
{
ch->println( "Syntax: oedit create <vnum>" );
return;
}
// officially reserved vnum range
if(value<500){
ch->println("Warning: all mobs, rooms and objects below vnum 500 are officially reserved for the dawn codebase.");
if(!HAS_SECURITY(ch,9)){
ch->println("As a result of this reservation, only those with security 9 can edit in that vnum range.");
return;
}
}
pArea = get_vnum_area( value );
if ( !pArea )
{
ch->println( "OEdit: That vnum is not assigned an area." );
return;
}
if ( !IS_BUILDER( ch, pArea, BUILDRESTRICT_OBJECTS ))
{
ch->println( "Insufficient security to modify object." );
return;
}
if ( oedit_create( ch, argument ) )
{
SET_BIT( pArea->olc_flags, OLCAREA_CHANGED );
ch->desc->editor = ED_OBJECT;
EDIT_OBJ(ch, pObj);
ch->wraplnf( "`=rcreated object `r%d `g(stored in %s)`x",
pObj->vnum, !pObj->area ? "`RNo Area!!!" : pObj->area->file_name );
ch->println( "Type `=Cdone`x to finish editing." );
}
return;
}
}
ch->wrapln( "OEdit: Type the vnum of the object you want to edit or 'oedit create <vnum>" );
return;
}
/**************************************************************************/
// by Kal - June 98
AFFECT_DATA * dup_affects_list(AFFECT_DATA* affect)
{
AFFECT_DATA * pAffect;
if (affect==NULL)
return (NULL);
pAffect= new_affect();
// use recursion to maintain the order of affects
pAffect->next = dup_affects_list(affect->next);
pAffect->where = affect->where;
pAffect->type = affect->type;
pAffect->duration = affect->duration;
pAffect->location = affect->location;
pAffect->modifier = affect->modifier;
pAffect->bitvector = affect->bitvector;
return (pAffect);
}
/**************************************************************************/
/*
* Object Editor Functions.
*/
/**************************************************************************/
void show_obj_values( char_data *ch, OBJ_INDEX_DATA *obj )
{
switch( obj->item_type )
{
default: // No values.
break;
case ITEM_LIGHT:
if ( obj->value[2] == -1)
ch->println( "[v2] Light: Infinite[-1]" );
else
ch->printlnf( "[v2] Light: [%d]", obj->value[2] );
break;
case ITEM_INSTRUMENT:
ch->printlnf( "[v0] Bardic Spell Mod: [%d]", obj->value[0] );
if ( obj->value[1] == -1 )
ch->println("[v1] Uses before retuning: Infinite[-1]");
else
ch->printlnf( "[v1] Uses before retuning: [%d]", obj->value[1] );
break;
case ITEM_COMPONENT:
ch->printlnf( "[v0] Charges: [%d]", obj->value[0] );
ch->printlnf( "[v1] Spell: %s",
obj->value[1] != -1 ? skill_table[obj->value[1]].name : "none" );
break;
case ITEM_WAND:
case ITEM_STAFF:
ch->printlnf( "[v0] Level: [%d]", obj->value[0] );
ch->printlnf( "[v1] Charges Total: [%d]", obj->value[1] );
ch->printlnf( "[v2] Charges Left: [%d]", obj->value[2] );
ch->printlnf( "[v3] Spell: %s",
obj->value[3] != -1 ? skill_table[obj->value[3]].name : "none" );
break;
case ITEM_POULTICE:
ch->printlnf( "[v0] Level: [%d]", obj->value[0] );
ch->printlnf( "[v1] Applications Total: [%d]", obj->value[1] );
ch->printlnf( "[v2] Applications Left: [%d]", obj->value[2] );
ch->printlnf( "[v3] Spell: %s",
obj->value[3] != -1 ? skill_table[obj->value[3]].name : "none" );
break;
case ITEM_PORTAL:
ch->printlnf( "[v0] Charges: [%d]", obj->value[0] );
ch->printlnf( "[v1] Exit Flags: %s", flag_string( exit_flags, obj->value[1] ));
ch->printlnf( "[v2] Portal Flags: %s", flag_string( portal_flags, obj->value[2] ));
ch->printlnf( "[v3] Goes to (vnum): [%d]", obj->value[3] );
if(CAN_WEAR(obj, OBJWEAR_TAKE))
{
ch->wrapln( "`#`RNOTE:`& Because this portal is takeable, it wont be able "
"to be used in no recall rooms/areas\r\n");
}
break;
case ITEM_TOKEN:
ch->printlnf( "[v0] Token: [%s]", flag_string( token_flags, obj->value[0] ));
break;
case ITEM_FURNITURE:
ch->printlnf( "[v0] Max people: [%d]", obj->value[0] );
ch->printlnf( "[v1] Max weight: [%d]", obj->value[1] );
ch->printlnf( "[v2] Furniture Flags: %s", flag_string( furniture_flags, obj->value[2] ));
ch->printlnf( "[v3] Heal bonus: [%d]", obj->value[3] );
ch->printlnf( "[v4] Mana bonus: [%d]", obj->value[4] );
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
ch->printlnf( "[v0] Level: [%d]", obj->value[0] );
ch->printlnf( "[v1] Spell: %s", obj->value[1] != -1 ? skill_table[obj->value[1]].name : "none" );
ch->printlnf( "[v2] Spell: %s", obj->value[2] != -1 ? skill_table[obj->value[2]].name : "none" );
ch->printlnf( "[v3] Spell: %s", obj->value[3] != -1 ? skill_table[obj->value[3]].name : "none" );
ch->printlnf( "[v4] Spell: %s", obj->value[4] != -1 ? skill_table[obj->value[4]].name : "none" );
break;
case ITEM_ARMOR:
ch->printlnf( "[v0] Ac pierce [%d]", obj->value[0] );
ch->printlnf( "[v1] Ac bash [%d]", obj->value[1] );
ch->printlnf( "[v2] Ac slash [%d]", obj->value[2] );
ch->printlnf( "[v3] Ac exotic [%d]", obj->value[3] );
break;
case ITEM_PARCHMENT:
ch->printlnf( "[v0] Unused [%d]", obj->value[0] );
ch->printlnf( "[v1] Blank = 0 [%d]", obj->value[1] );
ch->printlnf( "[v2] Unsealed = 0 [%d]", obj->value[2] );
ch->printlnf( "[v3] Language [%s]",
language_safe_lookup_by_id(obj->value[3])->name);
break;
case ITEM_WEAPON:
ch->printlnf( "[v0] Weapon class: %s",
flag_string( weapon_class_types, obj->value[0] ));
ch->printlnf( "[v1] Number of dice: [%d] (avedam %d)",
obj->value[1],
(int) (obj->value[1]+(obj->value[1] * obj->value[2]))/2);
ch->printlnf( "[v2] Type of dice: [%d]", obj->value[2] );
ch->printlnf( "[v3] Attack Type: %s", attack_table[obj->value[3]].name );
ch->printlnf( "[v4] Special type: %s", flag_string( weapon_flags, obj->value[4] ) );
ch->printlnf( "Average damage is %d",
(int) (obj->value[1]+(obj->value[1] * obj->value[2]))/2);
break;
case ITEM_CAULDRON:
case ITEM_CONTAINER:
case ITEM_FLASK:
case ITEM_MORTAR:
ch->printlnf( "[v0] Weight: [%d lbs]", obj->value[0]);
ch->printlnf( "[v1] Flags: [%s]", flag_string( container_flags, obj->value[1] ));
ch->printlnf( "[v2] Key: [%d] (%s)",
obj->value[2],
get_obj_index(obj->value[2]) ? get_obj_index(obj->value[2])->short_descr : "none");
ch->printlnf( "[v3] Capacity [%d lbs]", obj->value[3]);
ch->printlnf( "[v4] Weight Mult [%d]", obj->value[4] );
ch->wrapln("`YNotes:`x v0 = is the maximum combined weight the container can hold... that is "
"obtained by adding all objects in the containers true weights together.`1"
"v3 = is the maximum weight any single object can be to be able to be put inside the container.");
break;
case ITEM_FOUNTAIN:
case ITEM_DRINK_CON:
ch->printlnf( "[v0] Liquid Total: [%d] (-1 = infinite)", obj->value[0] );
ch->printlnf( "[v1] Liquid Left: [%d] (-1 = infinite)", obj->value[1] );
ch->printlnf( "[v2] Liquid: %s", liq_table[obj->value[2]].liq_name );
ch->printlnf( "[v3] Poisoned: %s", obj->value[3] != 0 ? "Yes": "No" );
break;
case ITEM_FOOD:
ch->printlnf( "[v0] Food hours: [%d]", obj->value[0] );
ch->printlnf( "[v1] Full hours: [%d]", obj->value[1] );
ch->printlnf( "[v3] Poisoned: %s", obj->value[3] != 0 ? "Yes" : "No" );
break;
case ITEM_MONEY:
ch->printlnf( "[v0] Silver: [%d]", obj->value[0] );
ch->printlnf( "[v1] Gold: [%d]", obj->value[1] );
break;
}
return;
}
/**************************************************************************/
bool set_obj_values( char_data *ch, OBJ_INDEX_DATA *pObj, int value_num, char *argument)
{
int value;
switch( pObj->item_type )
{
default:
break;
case ITEM_LIGHT:
switch ( value_num )
{
default:
ch->println( "Only valid option is V2, which is the hours of light a light provides (-1 = Infinite)." );
do_help( ch, "OLC-ITEM-LIGHT" );
return false;
case 2:
ch->println( "HOURS OF LIGHT SET.\r\n" );
pObj->value[2] = atoi( argument );
break;
}
break;
case ITEM_WAND:
case ITEM_STAFF:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-STAFF-WAND" );
return false;
case 0:
value=atoi( argument );
if(value==pObj->value[0]){
ch->println( "Spell level unchanged." );
}else{
ch->printlnf( "Spell level changed from %d to %d.\r\n", // Extra lf
pObj->value[0], value);
pObj->value[0] = value;
}
break;
case 1:
ch->println( "TOTAL NUMBER OF CHARGES SET.\r\n" ); // Extra lf
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "CURRENT NUMBER OF CHARGES SET.\r\n" );// Extra lf
pObj->value[2] = atoi( argument );
break;
case 3:
ch->println( "SPELL TYPE SET.\r\n" ); // Extra lf
pObj->value[3] = skill_lookup( argument );
break;
}
break;
case ITEM_POULTICE:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-POULTICE" );
return false;
case 0:
value=atoi( argument );
if(value==pObj->value[0]){
ch->println( "Spell level unchanged." );
}else{
ch->printlnf( "Spell level changed from %d to %d.\r\n", // Extra lf
pObj->value[0], value);
pObj->value[0] = value;
}
break;
case 1:
ch->println( "TOTAL NUMBER OF APPLICATIONS SET.\r\n" );
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "CURRENT NUMBER OF APPLICATIONS SET.\r\n" );
pObj->value[2] = atoi( argument );
break;
case 3:
ch->println( "SPELL TYPE SET.\r\n" );
pObj->value[3] = skill_lookup( argument );
break;
}
break;
case ITEM_INSTRUMENT:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-INSTRUMENT" );
return false;
case 0:
ch->println( "BARDIC SONG MOD SET." );
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "# OF SONGS BEFORE RETUNING SET. (-1 is infinite)" );
pObj->value[1] = atoi(argument);
break;
}
break;
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-SCROLL-POTION-PILL" );
return false;
case 0:
value=atoi( argument );
if(value==pObj->value[0]){
ch->println( "Spell level unchanged." );
}else{
ch->printlnf( "Spell level changed from %d to %d.\r\n", // Extra lf
pObj->value[0], value);
pObj->value[0] = value;
}
break;
case 1:
ch->println( "SPELL TYPE 1 SET.\r\n" ); // Extra lf
pObj->value[1] = skill_lookup( argument );
break;
case 2:
ch->println( "SPELL TYPE 2 SET.\r\n" ); // Extra lf
pObj->value[2] = skill_lookup( argument );
break;
case 3:
ch->println( "SPELL TYPE 3 SET.\r\n" ); // Extra lf
pObj->value[3] = skill_lookup( argument );
break;
case 4:
ch->println( "SPELL TYPE 4 SET.\r\n" ); // Extra lf
pObj->value[4] = skill_lookup( argument );
break;
}
break;
case ITEM_PARCHMENT:
switch ( value_num )
{
default: return false;
case 0: return false;
case 1:
ch->println( "Written on field set. Blank = 0 all else means it can't be written on." );
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "Sealed field set. Unsealed = 0 all else means it's sealed." );
pObj->value[2] = atoi( argument );
break;
case 3:
pObj->value[3] = language_safe_lookup(argument)->unique_id;
ch->printlnf( "Language set to '%s'.", language_safe_lookup(argument)->name);
break;
}
break;
case ITEM_ARMOR:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-ARMOR" );
return false;
case 0:
ch->println( "AC PIERCE SET.\r\n" ); // Extra lf
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "AC BASH SET.\r\n" ); // Extra lf
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "AC SLASH SET.\r\n" ); // Extra lf
pObj->value[2] = atoi( argument );
break;
case 3:
ch->println( "AC EXOTIC SET.\r\n" ); // Extra lf
pObj->value[3] = atoi( argument );
break;
}
break;
case ITEM_WEAPON:
switch ( value_num )
{
default:
ch->println( "Valid v0 weapon class:");
show_olc_flags_types_value(ch, weapon_class_types,"v0", pObj->value[0]);
ch->println( "v1 = number of dice to roll.");
ch->println( "v2 = type of dice to roll.");
ch->println( "v3 = weapon attack type.");
ch->println( "v4 = special weapon type.");
show_olc_flags_types_value(ch, weapon_flags,"v4", pObj->value[4]);
ch->println( "");
ch->println( "SeeAlso: HELP `=_OLC-ITEM-WEAPON");
return false;
case 0:
{
if ( ( value = flag_value( weapon_class_types, argument ) ) != NO_FLAG ){
ch->println( "WEAPON CLASS SET.\r\n" );
pObj->value[0] = flag_value( weapon_class_types, argument );
}else{
ch->println( "Valid v0 weapon classes include:");
show_olc_flags_types_value(ch, weapon_class_types,"v0", pObj->value[0]);
return false;
}
}
break;
case 1:
ch->println( "NUMBER OF DICE SET.\r\n" );
pObj->value[1] = atoi( argument );
ch->printlnf( "Average damage is now %d.",
(int) (pObj->value[1]+(pObj->value[1] * pObj->value[2]))/2);
break;
case 2:
ch->println( "TYPE OF DICE SET.\r\n" );
pObj->value[2] = atoi( argument );
ch->printlnf( "Average damage is now %d.",
(int) (pObj->value[1]+(pObj->value[1] * pObj->value[2]))/2);
break;
case 3:
{
int att=attack_lookup_with_error( argument );
if(att<0){
ch->printlnf("Attack type '%s' not found, must be one of the following:",
argument);
for ( att= 0; attack_table[att].name != NULL; att++)
{
ch->printf(" %-12s", attack_table[att].name);
if(att%4==3){
ch->print_blank_lines(1);
}
}
}else{
ch->println( "WEAPON ATTACK TYPE SET.\r\n" );
pObj->value[3] = att;
}
}
break;
case 4:
ch->println( "SPECIAL WEAPON TYPE TOGGLED.\r\n" );
pObj->value[4] ^= (flag_value( weapon_flags, argument ) != NO_FLAG
? flag_value( weapon_flags, argument ) : 0 );
break;
}
break;
case ITEM_PORTAL:
switch ( value_num )
{
default:
ch->printlnf( "Valid v1 portal exit flags are: %s", flag_string( exit_flags, -1));
ch->printlnf( "Valid v2 portal flags are: %s", flag_string( portal_flags, -1));
return false;
case 0:
ch->println( "CHARGES SET.\r\n" );
pObj->value[0] = atoi ( argument );
break;
case 1:
if ( ( value = flag_value( exit_flags, argument ) ) != NO_FLAG )
TOGGLE_BIT(pObj->value[1], value);
else
{
ch->printlnf( "Valid v1 portal exit flags are: %s",
flag_string( exit_flags, -1));
do_help ( ch, "OLC-ITEM-PORTAL" );
return false;
}
ch->println( "PORTAL EXIT FLAG SET.\r\n" );
break;
case 2:
if ( ( value = flag_value( portal_flags, argument ) ) != NO_FLAG )
TOGGLE_BIT(pObj->value[2], value);
else
{
ch->printlnf( "Valid v2 portal flags are: %s",
flag_string( portal_flags, -1));
do_help ( ch, "OLC-ITEM-PORTAL" );
return false;
}
ch->println( "PORTAL EXIT FLAG SET.\r\n" );
break;
case 3:
ch->println( "EXIT VNUM SET.\r\n" );
pObj->value[3] = atoi ( argument );
break;
}
break;
case ITEM_TOKEN:
switch ( value_num )
{
default:
do_help(ch, "OLC-ITEM-TOKEN" );
return false;
case 0:
ch->println( "Token Flag Toggled.\r\n" );
pObj->value[0] = ( flag_value( token_flags, argument ) != NO_FLAG
? flag_value( token_flags, argument ) : 0 );
break;
}
break;
case ITEM_COMPONENT:
switch ( value_num )
{
default:
do_help(ch, "OLC-ITEM-COMPONENT" );
return false;
case 0:
ch->println( "Charges set.\r\n" );
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "Spell set.\r\n" );
pObj->value[1] = skill_lookup( argument );
break;
}
break;
case ITEM_FURNITURE:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-FURNITURE" );
return false;
case 0:
ch->println( "NUMBER OF PEOPLE SET.\r\n" );
pObj->value[0] = atoi ( argument );
break;
case 1:
ch->println( "MAX WEIGHT SET.\r\n" );
pObj->value[1] = atoi ( argument );
break;
case 2:
ch->printlnf( "Valid v2 Furniture flags are: %s", flag_string( furniture_flags, -1));
ch->println( "FURNITURE FLAGS TOGGLED.\r\n" );
pObj->value[2] ^= (flag_value( furniture_flags, argument ) != NO_FLAG
? flag_value( furniture_flags, argument ) : 0);
break;
case 3:
ch->println( "HEAL BONUS SET.\r\n" );
pObj->value[3] = atoi ( argument );
break;
case 4:
ch->println( "MANA BONUS SET.\r\n" );
pObj->value[4] = atoi ( argument );
break;
}
break;
case ITEM_CAULDRON:
case ITEM_CONTAINER:
case ITEM_FLASK:
case ITEM_MORTAR:
switch ( value_num )
{
int value;
default:
do_help( ch, "OLC-ITEM-CONTAINER" );
ch->printlnf( "Valid v1 flags include: %s", flag_string( container_flags, -1));
return false;
case 0:
ch->wraplnf( "Maximum combined weight the container can hold changed "
"from %d lbs to %d lbs.",
pObj->value[0], atoi( argument ));
pObj->value[0] = atoi( argument );
ch->wrapln("`YNotes:`x v0 = is the maximum combined weight the container can hold... that is "
"obtained by adding all objects in the containers true weights together.`1"
"v3 = is the maximum weight any single object can be to be able to be put inside the container.");
break;
case 1:
if ( ( value = flag_value( container_flags, argument ) ) != NO_FLAG ){
TOGGLE_BIT(pObj->value[1], value);
}else{
ch->printlnf( "Valid v1 container flags are: %s", flag_string( container_flags, -1));
do_help ( ch, "OLC-ITEM-CONTAINER" );
return false;
}
ch->println( "CONTAINER FLAG SET.\r\n" );
break;
case 2:
if ( atoi(argument) != 0 )
{
if ( !get_obj_index( atoi( argument ) ) )
{
ch->println( "THERE IS NO SUCH ITEM.\r\n" );
return false;
}
if ( get_obj_index( atoi( argument ) )->item_type != ITEM_KEY )
{
ch->println( "THAT ITEM IS NOT A KEY.\r\n" );
return false;
}
}
ch->println( "CONTAINER KEY SET.\r\n" );
pObj->value[2] = atoi( argument );
break;
case 3:
ch->wraplnf( "Maximum weight any single object able to be put "
"into the container changed from %d lbs to %d lbs.",
pObj->value[3], atoi( argument ));
pObj->value[3] = atoi( argument );
ch->wrapln("`YNotes:`x v0 = is the maximum combined weight the container can hold... that is "
"obtained by adding all objects in the containers true weights together.`1"
"v3 = is the maximum weight any single object can be to be able to be put inside the container.");
break;
case 4:
ch->println( "WEIGHT MULTIPLIER SET.\r\n" );
pObj->value[4] = atoi ( argument );
break;
}
break;
case ITEM_DRINK_CON:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-DRINK" );
return false;
case 0:
ch->println( "MAXIMUM AMOUT OF LIQUID HOURS SET.\r\n" );
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "CURRENT AMOUNT OF LIQUID HOURS SET.\r\n" );
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "LIQUID TYPE SET.\r\n" );
pObj->value[2] = ( liq_lookup(argument) != -1 ?
liq_lookup(argument) : 0 );
break;
case 3:
ch->println( "POISON VALUE TOGGLED.\r\n" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_FOUNTAIN:
switch (value_num)
{
default:
do_help( ch, "OLC-ITEM-FOUNTAIN" );
return false;
case 0:
ch->println( "MAXIMUM AMOUT OF LIQUID HOURS SET.\r\n" );
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "CURRENT AMOUNT OF LIQUID HOURS SET.\r\n" );
pObj->value[1] = atoi( argument );
break;
case 2:
ch->println( "LIQUID TYPE SET.\r\n" );
pObj->value[2] = ( liq_lookup( argument ) != -1 ?
liq_lookup( argument ) : 0 );
break;
case 3:
ch->println( "POISON VALUE TOGGLED.\r\n" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_FOOD:
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-FOOD" );
return false;
case 0:
ch->println( "HOURS OF FOOD SET.\r\n" );
pObj->value[0] = atoi( argument );
break;
case 1:
ch->println( "HOURS OF FULL SET.\r\n" );
pObj->value[1] = atoi( argument );
break;
case 3:
ch->println( "POISON VALUE TOGGLED.\r\n" );
pObj->value[3] = ( pObj->value[3] == 0 ) ? 1 : 0;
break;
}
break;
case ITEM_MONEY:
{
int v=atoi(argument);
switch ( value_num )
{
default:
do_help( ch, "OLC-ITEM-MONEY" );
return false;
case 0:
ch->printlnf( "SILVER AMOUNT CHANGED FROM %d TO %d.", pObj->value[0], v);
pObj->value[0]=v;
break;
case 1:
ch->printlnf( "GOLD AMOUNT CHANGED FROM %d TO %d.", pObj->value[1], v);
pObj->value[1]=v;
break;
}
}
break;
}
show_obj_values( ch, pObj );
return true;
}
/**************************************************************************/
bool oedit_show( char_data *ch, char *)
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *paf;
int cnt;
EDIT_OBJ(ch, pObj);
ch->printlnf( "`=rVnum: `x%-5d `=rType: `x%-10s `=rLevel: "
"`x%-3d `=rArea[%d]: `x%s",
pObj->vnum, flag_string( item_types, pObj->item_type ) , pObj->level,
pObj->area ? pObj->area->vnum : 0,
pObj->area ? pObj->area->file_name : "`RNo Area!!!`x");
ch->printf( "`=rCost: `x%-7d ",pObj->cost );
ch->printf( "`=rWeight: `x%-3.1f lbs ", ((double)pObj->weight)/10);
ch->printf( "`=rCondition: `x%-6d ", pObj->condition );
ch->printlnf( "`=rMaterial: `x%-14s", pObj->material );
// sizes
ch->printf( "`=rAbsolute size: `x%-6d ", pObj->absolute_size );
ch->printlnf( "`=rRelative size: `x%-6d", pObj->relative_size );
ch->printlnf( "`=rName: `=x%s", pObj->name);
ch->printlnf( "`=rShort desc: `=x%s`x", pObj->short_descr);
if (has_colour(pObj->short_descr))
{
ch->print( "`sShort desc: `x" );
ch->printlnbw(pObj->short_descr);
}
ch->printlnf( "`=rLong descr: `=x%s`x", pObj->description);
if (has_colour(pObj->description))
{
ch->print( "`sLong descr: `x" );
ch->printlnbw(pObj->description);
}
// Extended descriptions
show_char_extended(ch, pObj->extra_descr, false);
mxp_display_olc_flags(ch, wear_flags, pObj->wear_flags, "wear", "Wear Flags:");
mxp_display_olc_flags(ch, objextra_flags, pObj->extra_flags, "extra", "Extra Flags:");
mxp_display_olc_flags(ch, objextra2_flags, pObj->extra2_flags, "extra2", "Extra2 Flags:");
// mxp_display_olc_flags(ch, objextra3_flags, pObj->extra3_flags, "extra3", "Extra3 Flags:");
if ( IS_SET ( pObj->attune_flags, ATTUNE_NEED_TO_USE ))
{
mxp_display_olc_flags(ch, attune_flags, pObj->attune_flags, "attune", "Attune Flags:");
}
if ( pObj->ospec_fun )
{
ch->printlnf( "`=rSpecial function: `R%s`x", ospec_name( pObj->ospec_fun ) );
}
if(pObj->item_type!=ITEM_PORTAL){
if(pObj->class_allowances){
mxp_display_olc_flags(ch, classnames_flags, pObj->class_allowances, "classallow", "Class Allowances:");
}else{
ch->printlnf( "`=r%s: `xall classes`x", mxp_create_send(ch, "classallow", "Class Allowances"));
}
}
for ( cnt = 0, paf = pObj->affected; paf; paf = paf->next )
{
if ( cnt == 0 ) {
ch->println( "`=rNumber Modifier Affects" );
ch->println( "------ -------- -------`x" );
}
if ( paf->where == WHERE_SKILLS )
{
ch->printf( "[%4d] %-8d Skill - %s",
cnt, paf->modifier, skill_table[paf->type].name );
}
else if ( paf->where == WHERE_OBJECTSPELL )
{
ch->printf( "[%4d] ObjectSpell %s - level=%d, duration=%d",
cnt, skill_table[paf->type].name, paf->level, paf->duration);
}else{
if(paf->location==APPLY_NONE){
ch->printf( "[%4d] ", cnt);
}else{
ch->printf( "[%4d] %8d %s",
cnt,
paf->modifier,
flag_string( apply_types, paf->location ) );
}
}
// say what the 'none' do
if (paf->bitvector){
ch->printlnf( "%s", to_affect_string( paf, pObj->level ));
}else{
ch->println("");
}
cnt++;
}
ch->print( "`x" );
if(pObj->restrict){
OBJRESTRICT_LIST_DATA *pr;
ch->println( "`=r========ClassGroups Object Restrictions========" );
ch->println( "`=r ClassGroup Affect Profile Prority" );
ch->println( "-------------------- ----------------------- ---------`x" );
for ( cnt=0, pr = pObj->restrict; pr; pr = pr->next, cnt++)
{
ch->printlnf( "[%4d] %-20.20s %10s %3d",
cnt,
pr->classgroup->name,
pr->affectprofile->name,
pr->priority);
}
ch->println( "note: if multiple classgroup matches, only highest priority is applied.`x" );
}
ch->print( "`x" );
show_obj_values( ch, pObj );
return false;
}
/**************************************************************************/
bool oedit_addrestrict( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
classgroup_type *cg;
affectprofile_type *ap;
OBJRESTRICT_LIST_DATA *pr;
char classgroup[MIL];
char affectprofile[MIL];
char strprority[MIL];
int priority;
EDIT_OBJ(ch, pObj);
argument = one_argument( argument, classgroup);
argument = one_argument( argument, affectprofile);
one_argument( argument, strprority);
if ( IS_NULLSTR(classgroup) || IS_NULLSTR(affectprofile))
{
if(!codehelp(ch,"oedit_addrestrict", CODEHELP_ALL_BUT_PLAYERS)){
ch->println("Syntax: addrestrict <classgrouping> <affectprofile> [priority]");
ch->println("showaffectprofile lists all affect profiles.");
}
return false;
}
if (pObj->item_type == ITEM_TRASH){
ch->println("You can't add classgroup restrictions to objects of type trash.");
return false;
}
if(IS_NULLSTR(strprority)){
priority=-1;
}else if(!is_number(strprority)){
ch->println("The priority must be a number between 0 and 100.");
return false;
}else{
priority=atoi(strprority);
};
if(priority>100 || priority<-1){
ch->println("The priority must be a number between 0 and 100.");
return false;
}
// check the parameters
cg=classgroup_lookup(classgroup);
if(!cg)
{
int index;
ch->printlnf( "No such classgroup '%s'", classgroup);
ch->println( "The classgroup must be one of the following:" );
for(index=0; !IS_NULLSTR(classgroup_table[index].name);index++){
ch->printlnf( "%-15s - %s",
classgroup_table[index].name,
classgroup_table[index].description);
}
return false;
}
ap=affectprofile_lookup(affectprofile);
if(!ap)
{
int index;
ch->printlnf( "No such affectprofile %s'", affectprofile);
ch->println( "The affectprofile must be one of the following:" );
for(index=0; !IS_NULLSTR(affectprofile_table[index].name);index++){
ch->printlnf( "%-15s - %s",
affectprofile_table[index].name,
affectprofile_table[index].description);
}
return false;
}
pr=new OBJRESTRICT_LIST_DATA;
pr->affectprofile=ap;
pr->classgroup=cg;
pr->priority=priority;
// add to the linked list
pr->next=pObj->restrict;
pObj->restrict=pr;
// create bit quick lookup
SET_BIT(pObj->objrestrict,(1<<pObj->restrict->classgroup->bitindex));
ch->printlnf( "Object Classgroup restriction added:\r\n"
" classgroup=%s, affectprofile=%s, priority=%d.",
pr->classgroup->name, pr->affectprofile->name, pr->priority);
return true;
}
/**************************************************************************/
bool oedit_delrestrict( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
OBJRESTRICT_LIST_DATA *pr, *pr_next;
int value;
int cnt = 0;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR( argument ))
{
ch->println( "Syntax: delrestrict <#affectprofile>" );
return false;
}
if ( !is_number( argument ))
{
ch->println( "#affectprofile must be a number." );
oedit_delrestrict(ch,"");
return false;
}
value = atoi( argument );
if ( value < 0 )
{
ch->println( "Only non-negative restrict-numbers allowed." );
return false;
}
pr=pObj->restrict;
if ( !pr )
{
ch->println( "OEdit: There a no classgroup restrictions on this object." );
return false;
}
if( value == 0 ) // First case: Remove first affect
{
pr = pObj->restrict;
pObj->restrict = pr->next;
}
else // Affect to remove is not the first
{
while ( ( pr_next = pr->next ) && ( ++cnt < value ) ){
pr = pr_next;
}
if( pr_next ) // See if it's the next affect
{
pr->next = pr_next->next;
}
else // Doesn't exist
{
ch->println( "No such restrict." );
return false;
}
}
ch->printlnf( "Object Classgroup restriction %d removed:\r\n"
" classgroup=%s, affectprofile=%s, priority=%d.",
value, pr->classgroup->name, pr->affectprofile->name, pr->priority);
delete pr;
// reset the bitmask
pObj->objrestrict=0;
for(pr=pObj->restrict; pr; pr=pr->next){
SET_BIT(pObj->objrestrict,(1<<pr->classgroup->bitindex));
}
return true;
}
/**************************************************************************/
bool oedit_name ( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument) )
{
ch->println( "Syntax: name <string>" );
return false;
}
ch->printlnf( "Object name changed from '%s' to '%s'.", pObj->name, lowercase(argument));
replace_string( pObj->name, lowercase(argument));
return true;
}
/**************************************************************************/
bool oedit_short( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
// trim the spaces to the right of the short
while ( !IS_NULLSTR(argument) && is_space(argument[str_len(argument)-1]))
{
argument[str_len(argument)-1]='\0';
}
if ( IS_NULLSTR(argument) )
{
ch->println("Syntax: short <string>" );
ch->println("Note: <string> is forced to lowercase unless there are colour codes in it.");
return false;
}
if(has_colour(argument)){
ch->wraplnf( "Changed object short description from '%s' to '%s' "
"(lower case not forced due to colour codes).",
pObj->short_descr, argument);
replace_string(pObj->short_descr, argument);
}else{
ch->printlnf( "Changed object short description from '%s' to '%s'.",
pObj->short_descr, lowercase(argument));
replace_string(pObj->short_descr, lowercase(argument));
}
return true;
}
/**************************************************************************/
bool oedit_long( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
// trim the spaces to the right of the short
while ( !IS_NULLSTR(argument) && is_space(argument[str_len(argument)-1]))
{
argument[str_len(argument)-1]='\0';
}
if ( argument[0] == '\0' )
{
ch->println( "Syntax: long <string>" );
ch->println( " (this is the description of the object seen in the room when you type look.)" );
ch->println( " e.g. A large rock is resting here." );
return false;
}
char *ptemp=pObj->description;
pObj->description = str_dup( argument );
pObj->description[0] = UPPER( pObj->description[0] );
ch->printlnf( "Long description from '%s' to '%s'.",
ptemp, pObj->description);
free_string( ptemp );
return true;
}
/**************************************************************************/
bool oedit_nolong( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument) || str_cmp("confirm", argument))
{
ch->println( "Syntax: nolong confirm" );
ch->println( " This removes the long descript, allowing for hidden objects in the room" );
return false;
}
// do security checks
if (!HAS_SECURITY(ch, OEDIT_NOLONG_MINSECURITY))
{
ch->printlnf( "You must have an olc security %d or higher to use this command.",
OEDIT_NOLONG_MINSECURITY);
return false;
}
replace_string(pObj->description,"");
ch->println( "Long description cleared." );
return true;
}
/**************************************************************************/
bool set_value( char_data *ch, OBJ_INDEX_DATA *pObj, char *argument, int value )
{
if (IS_NULLSTR(argument)){
set_obj_values( ch, pObj, -1, "" );
return false;
}
if ( set_obj_values( ch, pObj, value, argument ) ){
return true;
}
return false;
}
/**************************************************************************/
/*****************************************************************************
Name: oedit_values
Purpose: Finds the object and sets its value.
Called by: The five valueX functions below.
****************************************************************************/
bool oedit_values( char_data *ch, char *argument, int value )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( set_value( ch, pObj, argument, value ) ){
return true;
}
return false;
}
/**************************************************************************/
bool oedit_value0( char_data *ch, char *argument )
{
if ( oedit_values( ch, argument, 0 ) )
return true;
return false;
}
/**************************************************************************/
bool oedit_value1( char_data *ch, char *argument )
{
if ( oedit_values( ch, argument, 1 ) )
return true;
return false;
}
/**************************************************************************/
bool oedit_value2( char_data *ch, char *argument )
{
if ( oedit_values( ch, argument, 2 ) )
return true;
return false;
}
/**************************************************************************/
bool oedit_value3( char_data *ch, char *argument )
{
if ( oedit_values( ch, argument, 3 ) )
return true;
return false;
}
/**************************************************************************/
bool oedit_value4( char_data *ch, char *argument )
{
if ( oedit_values( ch, argument, 4 ) )
return true;
return false;
}
/**************************************************************************/
bool oedit_weight( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument) || !is_number( argument ) )
{
ch->println( "Syntax: weight <number>" );
ch->println( "Where the number is in 10th of a pound.");
ch->println( "e.g. 8=0.8lbs, 20=2lbs.");
return false;
}
int value=atoi( argument);
if(value<0){
ch->println("oedit_weight(): Weight must be 0 or greater.");
oedit_weight(ch,"");
return false;
}
ch->printlnf( "Weight changed from %0.1f lbs to %0.1f lbs.",
((double)pObj->weight/10), ((double)value)/10);
pObj->weight = value;
return true;
}
/**************************************************************************/
bool oedit_cost( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument) || !is_number( argument ) )
{
ch->println( "Syntax: cost <number>" );
return false;
}
int value=atoi( argument);
if(value<0){
ch->println("oedit_cost(): Cost must be 0 or greater.");
oedit_cost(ch,"");
return false;
}
ch->printlnf( "Cost changed from %d to %d.", pObj->cost, value);
pObj->cost = value;
return true;
}
/**************************************************************************/
bool oedit_create( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AREA_DATA *pArea;
int value;
int iHash;
value = atoi( argument );
if ( argument[0] == '\0' || value == 0 )
{
ch->println( "Syntax: oedit create <vnum>" );
return false;
}
pArea = get_vnum_area( value );
if ( !pArea )
{
ch->println( "OEdit: That vnum is not assigned an area." );
return false;
}
if ( !IS_BUILDER( ch, pArea, BUILDRESTRICT_OBJECTS) )
{
ch->println( "OEdit: Vnum in an area you cannot create objects in." );
return false;
}
if ( get_obj_index( value ) )
{
ch->println( "OEdit: Object vnum already exists." );
return false;
}
pObj = new_obj_index();
pObj->vnum = value;
pObj->area = pArea;
pObj->relative_size = 50; // main size so all can wear it
if ( value > top_vnum_obj ){
top_vnum_obj = value;
}
creator = ch->name;
iHash = value % MAX_KEY_HASH;
pObj->next = obj_index_hash[iHash];
obj_index_hash[iHash] = pObj;
ch->desc->pEdit = (void *)pObj;
{ // add vnums to new object default descriptions
char buf[MIL];
sprintf(buf, "no name %d", value);
replace_string(pObj->name, buf);
sprintf(buf, "(no short description %d)", value);
replace_string(pObj->short_descr, buf);
sprintf(buf, "(no description %d)", value);
replace_string(pObj->description, buf);
}
ch->printlnf( "Object %d Created.", value );
return true;
}
/**************************************************************************/
bool oedit_ed( char_data *ch, char *argument )
{
return( generic_ed (ch, argument) );
}
/**************************************************************************/
bool oedit_extra( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
return olc_generic_flag_toggle(ch, argument, "extra", "extra", objextra_flags, &pObj->extra_flags);
}
/**************************************************************************/
bool oedit_extra2( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
return olc_generic_flag_toggle(ch, argument, "extra2", "extra2", objextra2_flags, &pObj->extra2_flags);
}
/**************************************************************************/
/*bool oedit_extra3( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
return olc_generic_flag_toggle(ch, argument, "extra3", "extra3", objextra3_flags, &pObj->extra3_flags);
}*/
/**************************************************************************/
bool oedit_wear( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
return olc_generic_flag_toggle(ch, argument, "wear", "wear", wear_flags, &pObj->wear_flags);
}
/**************************************************************************/
bool oedit_type( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
int value;
if ( !IS_NULLSTR(argument))
{
if ( ( value = flag_value( item_types, argument ) ) != NO_FLAG )
{
if(pObj->item_type == value){
ch->printlnf( "Object is already type '%s'",
flag_string( item_types, pObj->item_type ));
return false;
}
ch->printlnf( "Type changed from '%s' to '%s'.",
flag_string( item_types, pObj->item_type ),
flag_string( item_types, value ));
pObj->item_type = value;
// Clear the values.
switch (pObj->item_type)
{
case ITEM_SCROLL:
case ITEM_POTION:
case ITEM_PILL:
pObj->value[0] = -1; // set them to none
pObj->value[1] = -1;
pObj->value[2] = -1;
pObj->value[3] = -1;
pObj->value[4] = -1;
break;
case ITEM_WAND:
case ITEM_STAFF:
pObj->value[0] = 0;
pObj->value[1] = 0;
pObj->value[2] = 0;
pObj->value[3] = -1;
pObj->value[4] = 0;
break;
default:
pObj->value[0] = 0;
pObj->value[1] = 0;
pObj->value[2] = 0;
pObj->value[3] = 0;
pObj->value[4] = 0;
break;
}
return true;
}
}
show_olc_options(ch, item_types, "type", "type", pObj->item_type);
return false;
}
/**************************************************************************/
bool oedit_material( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument))
{
ch->println( "Syntax: material <string>" );
return false;
}
replace_string( pObj->material, lowercase(argument));
ch->printlnf( "Material set to '%s'.", pObj->material );
return true;
}
/**************************************************************************/
bool oedit_level( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *paf;
int value;
EDIT_OBJ(ch, pObj);
if ( argument[0] == '\0' || !is_number( argument ) )
{
ch->println( "Syntax: level <number>" );
return false;
}
value=atoi( argument );
if( pObj->level == value){
ch->println("Level unchanged.");
};
ch->printlnf( "Object level changed from %d to %d.",
pObj->level , value);
for ( paf = pObj->affected; paf; paf = paf->next )
{
paf->level=value;
}
pObj->level = value;
return true;
}
/**************************************************************************/
bool oedit_condition( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
int value;
if ( !IS_NULLSTR(argument)
&& ( value = atoi (argument ) ) >= 1
&& ( value <= 100 ) )
{
EDIT_OBJ( ch, pObj );
ch->printlnf( "Condition changed from %d to %d.",
pObj->condition, value);
pObj->condition = value;
return true;
}
ch->println("Syntax: condition <number>");
ch->println("Where number can range from 1 (ruined) to 100 (perfect).");
return false;
}
/**************************************************************************/
bool oedit_classallowances( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
int value;
if ( IS_NULLSTR(argument))
{
show_olc_options(ch, classnames_flags, "classallow", "classallowance", pObj->class_allowances);
ch->println( "note: If no class allowances are set, then all classes can use the object." );
ch->println( "If class allowances are set, then only the classes on the list can use the object." );
return false;
}
if ( ( value = flag_value( classnames_flags, argument ) ) != NO_FLAG )
{
TOGGLE_BIT(pObj->class_allowances, value);
ch->println( "Classallowances flag toggled." );
return true;
}
ch->printlnf("Unrecognised classname '%s'", argument);
return false;
}
/**************************************************************************/
bool oedit_asize( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
int value;
EDIT_OBJ(ch, pObj);
if ( argument[0] == '\0' || !is_number( argument ) )
{
ch->println( "Syntax: asize <number>" );
ch->println( "(note at this stage absolute size has no effect)" );
return false;
}
value = atoi( argument );
pObj->absolute_size = value;
ch->printlnf( "Absolute size set to %d.", value );
ch->println( "(note at this stage absolute size has no effect)" );
return true;
}
/**************************************************************************/
bool oedit_rsize( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
int value, race;
EDIT_OBJ(ch, pObj);
if ( IS_NULLSTR(argument) || !is_number( argument ) ){
ch->println( "Syntax: rsize <number>" );
ch->wrapln( "Every object has a relative size value, if this value "
"is smaller than a races lowsize, the object will be too small for that "
"race to wear (and the reverse for a races high size). "
"The default convention for an object that is wearable by "
"all races is to set the relative size to 50.");
return false;
}
value = atoi( argument );
if (value>100 || value<10)
{
ch->println( "Try a value closer to 50." );
return false;
}
{
char race_wear_list[MSL];
char race_nowear_list[MSL];
race_wear_list[0]='\0';
race_nowear_list[0]='\0';
for ( race = 1; race_table[race]; race++ )
{
if (value>=race_table[race]->low_size
&& value<=race_table[race]->high_size)
{
strcat(race_wear_list,race_table[race]->name);
strcat(race_wear_list,"\r\n");
}else{
strcat(race_nowear_list,race_table[race]->name);
if(value<race_table[race]->low_size){
strcat(race_nowear_list," - object is too small.\r\n");
}else{
strcat(race_nowear_list," - object is too big.\r\n");
}
}
}
pObj->relative_size = value;
ch->printlnf( "Relative size set to %d.", value);
if (IS_NULLSTR(race_wear_list))
{
ch->println( "Warning, no player races can wear it with that relative size value." );
}
else
{
ch->printlnf( "`YPlayer races that `Gcan`Y wear it:`x%s",
race_wear_list );
ch->printlnf( "`YPlayer races that `Rcan't`Y wear it:`x%s",
race_nowear_list );
}
}
return true;
}
/**************************************************************************/
// duplicate the object data from another
// written by Kalahn - June 98
bool oedit_copy(char_data *ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
OBJ_INDEX_DATA *pSrc; // source object
char arg1[MIL];
int value;
argument = one_argument( argument, arg1 );
if ( !is_number( arg1 ) )
{
ch->println( "Syntax: ocopy <source object vnum>" );
ch->println( " - copies the source object over the object you are currently editing!" );
ch->println( " (warning copies over everything!)" );
return false;
}
value = atoi( arg1 );
if ( !( pSrc = get_obj_index( value ) ) )
{
ch->println( "OEdit_copy: The source vnum does not exist." );
return false;
}
if ( !IS_BUILDER( ch, pSrc->area, BUILDRESTRICT_OBJECTS) && !IS_IMMORTAL(ch) )
{
ch->println( "Insufficient security to copy from the area that object\r\n"
"is stored in and your aren't an immortal." );
return false;
}
EDIT_OBJ(ch, pObj);
// copy the object details
pObj->name = str_dup(pSrc->name);
pObj->short_descr = str_dup(pSrc->short_descr);
pObj->description = str_dup(pSrc->description);
pObj->material = str_dup(pSrc->material);
pObj->item_type = pSrc->item_type;
pObj->extra_flags = pSrc->extra_flags;
pObj->extra2_flags = pSrc->extra2_flags;
//pObj->extra3_flags = pSrc->extra3_flags;
pObj->wear_flags = pSrc->wear_flags;
pObj->level = pSrc->level;
pObj->condition = pSrc->condition;
pObj->count = pSrc->count;
pObj->weight = pSrc->weight;
pObj->cost = pSrc->cost;
pObj->value[0] = pSrc->value[0];
pObj->value[1] = pSrc->value[1];
pObj->value[2] = pSrc->value[2];
pObj->value[3] = pSrc->value[3];
pObj->value[4] = pSrc->value[4];
pObj->value[4] = pSrc->value[4];
pObj->absolute_size = pSrc->absolute_size;
pObj->class_allowances = pSrc->class_allowances;
// NOTE: we aren't deallocating the existing affects and
// descriptions on the objects... we should, but I can't be
// bothered writing the code to do so right now
// COPY AFFECTS
pObj->affected =dup_affects_list(pSrc->affected);
// COPY THE EXTENDED DESCRIPTIONS
pObj->extra_descr = dup_extdescr_list(pSrc->extra_descr);
// sh_int vnum;
// sh_int reset_num;
// AREA_DATA * area;
ch->wraplnf( "`=rCopied object '%s'[%d] to vnum %d",
pSrc->short_descr, pSrc->vnum, pObj->vnum);
return true;
}
/**************************************************************************/
bool oedit_attune( char_data *ch, char *argument )
{
int value;
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if( !IS_IMMORTAL( ch )) {
ch->println( "oedit_attune(): Currently only for immortal testing." );
return false;
}
if( !IS_NULLSTR(argument))
{
if ( ( value = flag_value( attune_flags, argument ) ) != NO_FLAG )
{
TOGGLE_BIT(pObj->attune_flags, value);
ch->println( "Attune flag toggled." );
return true;
}
}
show_olc_options(ch, attune_flags, "attune", "attune", pObj->attune_flags);
return false;
}
/**************************************************************************/
bool oedit_addskill( char_data *ch, char *argument )
{
int value;
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
AFFECT_DATA *pAf;
char sn[MSL];
char mod[MSL];
int modifier;
if( !IS_IMMORTAL( ch )) {
ch->println( "oedit_addskill(): Currently only for immortal testing." );
return false;
}
argument = one_argument( argument, sn );
one_argument( argument, mod );
if ( IS_NULLSTR(sn) || IS_NULLSTR(mod) ){
ch->println( "Syntax: addskill <skillname> <modifier>" );
return false;
}
if(!is_number( mod ) ){
ch->println( "Modifier must be a number." );
oedit_addskill(ch,"");
return false;
}
modifier=atoi(mod);
if ( modifier< 0 || modifier> 50 )
{
ch->println("Value must range from 0 to 50.");
return false;
}
if (pObj->item_type == ITEM_TRASH){
ch->println( "You can't add a skill modifiers to objects of type trash." );
return false;
}
if (pObj->item_type == ITEM_RP){
ch->println( "You can't add a skill modifiers to RP objects." );
return false;
}
if (( value = skill_lookup( sn )) == -1 )
{
ch->println( "That's not a valid skill." );
return false;
}
pAf = new_affect();
pAf->location = APPLY_NONE;
pAf->modifier = modifier;
pAf->where = WHERE_SKILLS;
pAf->type = value;
pAf->duration = -1;
pAf->bitvector = 0;
pAf->level = pObj->level;
pAf->next = pObj->affected;
pObj->affected = pAf;
ch->printlnf( "Skill modifier '%s' by %d added.",
skill_table[value].name, modifier);
return true;
}
/**************************************************************************/
bool oedit_addspell( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char name[MIL];
char level[MIL];
char duration[MIL];
char use_spell_for_all_levels[MIL];
argument = one_argument( argument, name);
argument = one_argument( argument, level);
argument = one_argument( argument, duration);
argument = one_argument( argument, use_spell_for_all_levels);
if ( IS_NULLSTR(name))
{
ch->println("Syntax: addspell 'spellname' [level] [duration] [use_spell_for_all_levels]");
ch->println("Notes: If level is 0, object level is used (default).");
ch->println(" If duration is 0, spell duration is used.");
ch->println(" If duration is -1, spell is permanant while object is worn (default).");
ch->println(" If use_spell_for_all_levels is 1, then the spell will take effect ");
ch->println(" even if the spell/object is over the players level.");
return false;
}
// check the spell name is valid
int sn=skill_lookup(name);
if(sn<FIRST_SPELL || sn>LAST_SPELL){
ch->printf("oedit_addspell: Couldn't find the spell '%s' to add to object.\r\n",
name);
oedit_addspell(ch,"");
return false;
}
// get/check the numeric values
int ilevel=0;
int iduration=-1;
if(!IS_NULLSTR(level)){
if(is_number(level)){
ilevel=atoi(level);
}else{
ch->println("oedit_addspell: level must be numeric if specified.");
oedit_addspell(ch,"");
return false;
}
if(!IS_NULLSTR(duration)){
if(is_number(duration)){
iduration=atoi(duration);
}else{
ch->println("oedit_addspell: duration must be numeric if specified.");
oedit_addspell(ch,"");
return false;
}
}
}
EDIT_OBJ(ch, pObj);
if (pObj->item_type == ITEM_TRASH)
{
ch->println( "You can't add spells to objects of type trash." );
return false;
}
if (pObj->item_type == ITEM_RP)
{
ch->println( "You can't add spells to objects of RP items." );
return false;
}
pAf = new_affect();
pAf->location = APPLY_NONE;
pAf->modifier = 0;
pAf->where = WHERE_OBJECTSPELL;
pAf->type = sn;
pAf->duration = iduration;
if(!str_cmp(use_spell_for_all_levels,"1")){
pAf->bitvector = OBJSPELL_IGNORE_LEVEL;
}else{
pAf->bitvector = 0;
}
pAf->level = ilevel;
pAf->next = pObj->affected;
pObj->affected = pAf;
ch->printlnf("ObjectSpell '%s' added.", skill_table[sn].name);
return true;
}
/**************************************************************************/
bool oedit_delaffect( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
AFFECT_DATA *pAf_next;
char affect[MSL];
int value;
int cnt = 0;
EDIT_OBJ(ch, pObj);
one_argument( argument, affect );
if ( !is_number( affect ) || affect[0] == '\0' )
{
ch->println( "Syntax: delaffect <#xaffect>" );
ch->println( "Syntax: delflag <#xaffect>" );
ch->println( "Syntax: delmodifier <#xaffect>" );
return false;
}
value = atoi( affect );
if ( value < 0 )
{
ch->println( "Only non-negative affect-numbers allowed." );
return false;
}
if ( !( pAf = pObj->affected ) )
{
ch->println( "OEdit: Non-existant affect." );
return false;
}
if( value == 0 ) // First case: Remove first affect
{
pAf = pObj->affected;
pObj->affected = pAf->next;
free_affect( pAf );
}
else // Affect to remove is not the first
{
while ( ( pAf_next = pAf->next ) && ( ++cnt < value ) )
pAf = pAf_next;
if( pAf_next ) // See if it's the next affect
{
pAf->next = pAf_next->next;
free_affect( pAf_next );
}
else // Doesn't exist
{
ch->println( "No such affect." );
return false;
}
}
ch->println( "Affect removed." );
return true;
}
/**************************************************************************/
bool oedit_addmodifier( char_data *ch, char *argument )
{
int value;
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char location[MSL];
char amount[MSL];
EDIT_OBJ(ch, pObj);
argument = one_argument( argument, location );
one_argument( argument, amount );
if ( IS_NULLSTR(location) || IS_NULLSTR(amount))
{
ch->println( "Syntax: addmodifer <location> <amount>" );
ch->println( "Where <location> is one of:");
show_olc_flags_types(ch, apply_types);
ch->println( "(<amount> is a number)");
if (pObj->item_type == ITEM_TRASH){
ch->println( "You can't add modifiers to objects of type trash." );
}
if (pObj->item_type == ITEM_RP){
ch->println( "You can't add modifiers to objects of RP items." );
}
return false;
}
if(!is_number( amount ) ){
ch->println( "<amount> must be a number." );
oedit_addmodifier(ch,"");
return false;
}
if (pObj->item_type == ITEM_TRASH){
ch->println( "You can't add modifiers to objects of type trash." );
return false;
}
if (pObj->item_type == ITEM_RP){
ch->println( "You can't add modifiers to objects of RP items." );
return false;
}
if ( ( value = flag_value( apply_types, location ) ) == NO_FLAG )
{
ch->println("Valid modifiers to apply include:");
show_olc_flags_types(ch, apply_types);
return false;
}
pAf = new_affect();
pAf->location = (APPLOC)value;
pAf->modifier = atoi( amount);
pAf->where = WHERE_MODIFIER;
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = 0;
pAf->level = pObj->level;
pAf->next = pObj->affected;
pObj->affected = pAf;
ch->printlnf( "Modifing affect '%s' added to object... (use delmodifier to remove modifying affects).",
to_affect_string(pAf, pObj->level) );
return true;
}
/**************************************************************************/
// - Kal
bool oedit_addflag( char_data *ch, char *argument )
{
OBJ_INDEX_DATA *pObj;
AFFECT_DATA *pAf;
char where[MSL];
char flag[MSL];
int wherevalue, flagvalue;
EDIT_OBJ(ch, pObj);
argument = one_argument( argument, where );
argument = one_argument( argument, flag);
if(IS_NULLSTR(where)){
ch->println( "Syntax: addflag <where> <flag>" ); // flag sets the bitvector
ch->println( "e.g. addflag affects swim" );
ch->println( "Valid <where> places to apply to include:" );
show_olc_flags_types(ch, to_types);
ch->println( "The <flag>'s available depend on <where> the flag is being applied." );
if (pObj->item_type == ITEM_TRASH){
ch->println( "You can't add applies to objects of type trash." );
}
if (pObj->item_type == ITEM_RP){
ch->println( "You can't add applies to RP objects." );
}
return false;
}
if (pObj->item_type == ITEM_TRASH){
ch->println( "You can't add applies to objects of type trash." );
return false;
}
if (pObj->item_type == ITEM_RP){
ch->println( "You can't add applies to RP objects." );
return false;
}
if ( (wherevalue= flag_value( to_types, where)) == NO_FLAG ){
ch->println( "Invalid <where> location to apply a flag to... valid places <where> you can apply a flag include:" );
show_olc_flags_types(ch, to_types);
return false;
}
const flag_type *bv_flags=affect_get_bitvector_table_for_where(wherevalue);
if ( !bv_flags ){
ch->wraplnf( "oedit_addflag(): coding bug - please report: For some reason "
"affect_get_bitvector_table_for_where() returned NULL for a wherevalue of %d, "
"The most likely cause of this is a new character affect location has been "
"added but not added to affect_get_bitvector_table_for_where() or an affect "
"of another type has been added to to_types[], and should be flagged as false. "
"Until this is fixed, you cant add flags with a <where> of '%s'"
, wherevalue, where);
return false;
}
if ( IS_NULLSTR(flag) ){
oedit_addflag(ch,"");
ch->printlnf( "Valid flags when applying '%s' include:", where);
show_olc_flags_types(ch, bv_flags);
return false;
}
flagvalue=flag_value( bv_flags, flag);
if ( flagvalue== NO_FLAG )
{
ch->printlnf( "Invalid flag type '%s'.", flag);
ch->printlnf( "Valid flags when applying '%s' include:", where);
show_olc_flags_types(ch, bv_flags);
return false;
}
pAf = new_affect();
pAf->location = APPLY_NONE;
pAf->modifier = 0;
pAf->where = wherevalue;
pAf->type = -1;
pAf->duration = -1;
pAf->bitvector = flagvalue;
pAf->level = pObj->level;
pAf->next = pObj->affected;
pObj->affected = pAf;
ch->printlnf( "Flag '%s' added... (use delflag to remove flagged affects)",
to_affect_string(pAf, pObj->level));
return true;
}
/**************************************************************************/
bool oedit_delete( char_data *ch, char *)
{
ch->println("If you want to delete an object, use the 'odelete' command");
return false;
}
/**************************************************************************/
// Kal, Feb 2001
bool oedit_odelete(char_data *ch, char *argument)
{
OBJ_INDEX_DATA *pObj;
EDIT_OBJ(ch, pObj);
if (IS_NULLSTR(argument))
{
ch->titlebar("ODELETE SYNTAX");
ch->println("Syntax: odelete confirm - delete the current object");
ch->println("Syntax: odelete <number> confirm - delete object vnum <number>");
ch->println("Any object that you delete must meet the following conditions:");
ch->println("* Must not be used by any reset in any room.");
ch->println("* Must not be currently loaded in the game.");
ch->println("* Gameedit can't be making use of the object.");
ch->println("* You must have sufficient security to edit that object.");
ch->println("* Noone else can currently be editing the object.");
ch->wrapln("NOTE: It is strongly recommended that no mobprogs attempt to load the object "
"you are considering deleting... the easiest method to do this is 'textsearch mobprog <objvnum>'.");
return false;
}
// support specifying the object by vnum
char arg1[MIL];
OBJ_INDEX_DATA *pDeleteObj;
argument=one_argument(argument, arg1);
if(is_number(arg1)){
pDeleteObj=get_obj_index(atoi(arg1));
if(!pDeleteObj){
ch->printlnf("oedit_odelete(): There is no object number %s to delete.", arg1);
return false;
}
argument=one_argument(argument, arg1); // put the word 'confirm' into arg1
}else{
pDeleteObj=pObj; // deleting the object we are currently editing
}
// security check
if ( !IS_BUILDER( ch, pDeleteObj->area, BUILDRESTRICT_OBJECTS ) )
{
ch->printlnf("OEdit: Insufficient security to delete object %d.", pDeleteObj->vnum);
return false;
}
// confirm they are using 'confirm'
if(str_cmp(arg1, "confirm")){
ch->println("You must confirm your intention to delete an object.");
oedit_odelete(ch,"");
return false;
}
if(!IS_NULLSTR(ltrim_string(argument))){
ch->println("Incorrect syntax - too many arguments, or arguments in wrong order.");
oedit_odelete(ch, "");
return false;
}
int v=pDeleteObj->vnum;
// We have the object they are wanting to delete and they have
// confirmed they want to delete it, check if it isn't in use
{
int in_use=0;
// objects in game
for ( obj_data *inuse_obj= object_list; inuse_obj; inuse_obj= inuse_obj->next ){
if(inuse_obj->pIndexData==pDeleteObj){
ch->printlnf("`=rOne or more objects based on object template %d are currently in the game... use owhere <vnum> to find them.`x", v);
in_use++;
break;
}
}
// resets using this object
for( int iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
{
for( ROOM_INDEX_DATA *pRoom= room_index_hash[iHash]; pRoom; pRoom = pRoom->next )
{
for ( RESET_DATA *pReset = pRoom->reset_first; pReset; pReset = pReset->next )
{
if( pReset->arg1==v &&
(pReset->command=='P'
|| pReset->command=='O'
|| pReset->command=='G'
|| pReset->command=='E'
) )
{
ch->printlnf("object %d reset in room %d (%s).",
v, pRoom->vnum, pRoom->name);
in_use++;
}
}
}
}
for(int i=0; !IS_NULLSTR(gameset_value[i].name); i++){
if(gameset_value[i].category!=GSVC_OBJECT){
continue;
}
// get our numeric value
int value=GSINT(gameset_value[i].offset);
if(value==v){
ch->printlnf("Game setting value '%s (%s)' makes use of object %d.",
gameset_value[i].name, gameset_value[i].description, value);
in_use++;
}
}
// someone else currently editing the mob
for(connection_data *c=connection_list; c; c=c->next){
if(c!=ch->desc && c->pEdit==(void *)pDeleteObj){
ch->println("Someone else is currently editing it, so it can't currently be deleted.");
in_use++;
}
}
if(in_use){
ch->println("You can't delete this object, it is currently in use.");
oedit_odelete(ch, "");
return false;
}
}
if(pObj==pDeleteObj){
edit_done(ch);
}
ch->printlnf("Deleting object %d.", v);
// remove object from hash table
{
int i=v% MAX_KEY_HASH;
// check if we are the first entry in the hash table
if(pDeleteObj== obj_index_hash[i]){
obj_index_hash[i]=obj_index_hash[i]->next;
}else{
OBJ_INDEX_DATA *prev=obj_index_hash[i];
if(!prev){
bugf("oedit_odelete(): Trying to free object vnum %d, but not found in obj_index_hash[%d]!",
v, i);
}else{
for( ; prev->next; prev=prev->next )
{
if(prev->next==pDeleteObj){
prev->next=pDeleteObj->next; // remove the object from the link
break;
}
}
}
}
}
free_obj_index(pDeleteObj);
top_obj_index--;
ch->printlnf("Object %d Deleted.",v);
return true;
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/