// Convert a DATAList flag into a long integer value long list_flag_value( DATAExpression *flag, struct flag_type *flag_table ) { ValueList *list = flag->eval().asList(); char flagString[MAX_STRING_LENGTH]; flagString[0] = '\0'; if ( list->size == 0 ) return 0; if ( list->size == 1 ) if ( !str_cmp( "none", list->elems[0].asStr() ) ) return 0; // Any is accepted as element in a list only if flag_table is bit based else if ( !str_cmp( "any", list->elems[0].asStr() ) && !is_stat_init( flag_table ) ) { int bit = 0; for (int flag = 0; flag_table[flag].name != NULL; flag++) bit |= flag_table[flag].bit; return bit; } // Convert the list into a string for ( int i = 0; i < list->size; i++ ) { strcat( flagString, list->elems[i].asStr() ); if ( i < list->size-1 ) strcat( flagString, " " ); } list->explicit_free(); // Send the string to flag_value return flag_value( flag_table, flagString ); }
/* Area Interpreter, called by do_aedit. */ void aedit (CHAR_DATA * ch, char *argument) { AREA_DATA *pArea; char command[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH]; int cmd; int value; EDIT_AREA (ch, pArea); smash_tilde (argument); strcpy (arg, argument); argument = one_argument (argument, command); if (!IS_BUILDER (ch, pArea)) { send_to_char ("AEdit: Insufficient security to modify area.\n\r", ch); edit_done (ch); return; } if (!str_cmp (command, "done")) { edit_done (ch); return; } if (command[0] == '\0') { aedit_show (ch, argument); return; } if ((value = flag_value (area_flags, command)) != NO_FLAG) { TOGGLE_BIT (pArea->area_flags, value); send_to_char ("Flag toggled.\n\r", ch); return; } /* Search Table and Dispatch Command. */ for (cmd = 0; aedit_table[cmd].name != NULL; cmd++) { if (!str_prefix (command, aedit_table[cmd].name)) { if ((*aedit_table[cmd].olc_fun) (ch, argument)) { SET_BIT (pArea->area_flags, AREA_CHANGED); return; } else return; } } /* Default to Standard Interpreter. */ interpret (ch, arg); return; }
// Convert a ValueList flag into a long integer value long list_flag_value( ValueList *list, struct flag_type *flag_table ) { char flagString[MAX_STRING_LENGTH]; flagString[0] = '\0'; if ( list->size == 0 || ( list->size == 1 && !str_cmp( "none", list->elems[0].asStr() ) ) ) return 0; // Convert the list into a string for ( int i = 0; i < list->size; i++ ) { strcat( flagString, list->elems[i].asStr() ); if ( i < list->size-1 ) strcat( flagString, " " ); } // Send the string to flag_value return flag_value( flag_table, flagString ); }
/*************************************************************************** * change_exit * * change the values of an exit ***************************************************************************/ static bool change_exit(struct char_data *ch, const char *argument, int door) { struct room_index_data *room; char command[MAX_INPUT_LENGTH]; char arg[MAX_INPUT_LENGTH]; int value; EDIT_ROOM(ch, room); /* set the exit flags - needs full argument */ if ((value = flag_value(exit_flags, argument)) != NO_FLAG) { struct room_index_data *pToRoom; int rev; if (!room->exit[door]) { send_to_char("Exit does not exist.\n\r", ch); return false; } /* this room */ TOGGLE_BIT(room->exit[door]->rs_flags, value); room->exit[door]->exit_info = room->exit[door]->rs_flags; /* connected room */ pToRoom = room->exit[door]->u1.to_room; rev = rev_dir[door]; if (pToRoom->exit[rev] != NULL) { pToRoom->exit[rev]->rs_flags = room->exit[door]->rs_flags; pToRoom->exit[rev]->exit_info = room->exit[door]->exit_info; } send_to_char("Exit flag toggled.\n\r", ch); return true; } /* parse the arguments */ argument = one_argument(argument, command); one_argument(argument, arg); if (command[0] == '\0' && argument[0] == '\0') { move_char(ch, door, true); return false; } if (command[0] == '?') { show_help(ch->desc, "OLC_EXIT", NULL); return false; } if (!str_cmp(command, "delete")) { struct room_index_data *pToRoom; int rev; if (!room->exit[door]) { send_to_char("REdit: Cannot delete a null exit.\n\r", ch); return false; } /* remove ToRoom exit */ rev = rev_dir[door]; pToRoom = room->exit[door]->u1.to_room; if (pToRoom->exit[rev]) { free_exit(pToRoom->exit[rev]); pToRoom->exit[rev] = NULL; } /* remove this exit */ free_exit(room->exit[door]); room->exit[door] = NULL; send_to_char("Exit unlinked.\n\r", ch); return true; } if (!str_cmp(command, "link")) { struct exit_data *pExit; struct room_index_data *toRoom; if (arg[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: [direction] link [vnum]\n\r", ch); return false; } value = parse_int(arg); if (!(toRoom = get_room_index(value))) { send_to_char("REdit: Cannot link to non-existant room.\n\r", ch); return false; } if (!IS_BUILDER(ch, toRoom->area)) { send_to_char("REdit: Cannot link to that area.\n\r", ch); return false; } if (toRoom->exit[rev_dir[door]]) { send_to_char("REdit: Remote side's exit already exists.\n\r", ch); return false; } if (!room->exit[door]) room->exit[door] = new_exit(); room->exit[door]->u1.to_room = toRoom; room->exit[door]->orig_door = door; door = rev_dir[door]; pExit = new_exit(); pExit->u1.to_room = room; pExit->orig_door = door; toRoom->exit[door] = pExit; send_to_char("Two-way link established.\n\r", ch); return true; } if (!str_cmp(command, "dig")) { char buf[MAX_STRING_LENGTH]; if (arg[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: [direction] dig <vnum>\n\r", ch); return false; } redit_create(ch, arg); sprintf(buf, "link %s", arg); change_exit(ch, buf, door); return true; } if (!str_cmp(command, "room")) { struct room_index_data *toRoom; if (arg[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: [direction] room [vnum]\n\r", ch); return false; } value = parse_int(arg); if (!(toRoom = get_room_index(value))) { send_to_char("REdit: Cannot link to non-existant room.\n\r", ch); return false; } if (!room->exit[door]) room->exit[door] = new_exit(); room->exit[door]->u1.to_room = toRoom; room->exit[door]->orig_door = door; send_to_char("One-way link established.\n\r", ch); return true; } if (!str_cmp(command, "key")) { struct objectprototype *key; if (arg[0] == '\0' || !is_number(arg)) { send_to_char("Syntax: [direction] key [vnum]\n\r", ch); return false; } if (!room->exit[door]) { send_to_char("Exit does not exist.\n\r", ch); return false; } value = parse_int(arg); if (!(key = objectprototype_getbyvnum(value))) { send_to_char("REdit: Key doesn't exist.\n\r", ch); return false; } if (key->item_type != ITEM_KEY) { send_to_char("REdit: Object is not a key.\n\r", ch); return false; } room->exit[door]->key = value; send_to_char("Exit key set.\n\r", ch); return true; } if (!str_cmp(command, "name")) { if (arg[0] == '\0') { send_to_char("Syntax: [direction] name [string]\n\r", ch); send_to_char(" [direction] name none\n\r", ch); return false; } if (!room->exit[door]) { send_to_char("Exit does not exist.\n\r", ch); return false; } free_string(room->exit[door]->keyword); if (str_cmp(arg, "none")) room->exit[door]->keyword = str_dup(arg); else room->exit[door]->keyword = str_dup(""); send_to_char("Exit name set.\n\r", ch); return true; } if (!str_prefix(command, "description")) { if (arg[0] == '\0') { if (!room->exit[door]) { send_to_char("Exit does not exist.\n\r", ch); return false; } string_append(ch, &room->exit[door]->description); return true; } send_to_char("Syntax: [direction] desc\n\r", ch); return false; } return false; }
// General data parsing method bool parse_affect( DATAData *pafD, AFFECT_DATA *paf ) { // Affect = ( 'enchant armor', -1, 110, 0, ('permanent'), // ( 'char', 'damroll', 0, 50 ), // ( 'char', 'hitroll', 0, 50 ) ); ValueList *list = pafD->value->eval().asList(); // Minimum 5 elements but revelant affects have at least 6 elements if ( list->size < 5 ) { bug("Wrong number of elements in affect [<name>]<where><location><op><modifier><duraction><level><casting level>"); return FALSE; } // ability, duration, level, casting, (flags), // ( where, loc, op, modifier ), // .. const char *s = list->elems[0].asStr(); int sn; if ( !str_cmp( s, "none" ) ) // not an ability affect sn = -1; else { sn = ability_lookup( s ); if ( sn < 0 ) { bug("Invalid ability name %s", s ); return FALSE; } } int dur = list->elems[1].asInt(); int level = list->elems[2].asInt(); int casting = list->elems[3].asInt(); long flags = list_flag_value_complete(list->elems[4].asList(),affect_data_flags); if ( flags == NO_FLAG ) { flags = ( sn == -1 ) ? AFFECT_INHERENT : AFFECT_ABILITY; bug("Invalid affect flag, assuming %s", flag_string( affect_data_flags, flags ) ); } createaff( *paf, dur, level, sn, casting, flags ); //if ( list->size == 5 ) //bug("Irrevelant affect: %d %d %s %d %ld", dur, level, s, casting, flags ); for ( int i = 5; i < list->size; i++ ) { // now, extract affect_list ValueList *alist = list->elems[i].asList(); // where, loc, op, modifier s = alist->elems[0].asStr(); int where = flag_value( afto_type, s ); if ( where == NO_FLAG ) { bug("Invalid where name %s", s ); return FALSE; } int loc = ATTR_NA; int mod = 0; switch (where) { case AFTO_CHAR: s = alist->elems[1].asStr(); loc = flag_value( attr_flags, s ); if ( loc == NO_FLAG ) { bug("Invalid location name %s", s ); return FALSE; } if (attr_table[loc].bits == NULL) mod = alist->elems[3].asInt(); else mod = list_flag_value_complete( alist->elems[3].asList(), attr_table[loc].bits ); break; case AFTO_ROOM: s = alist->elems[1].asStr(); loc = flag_value( room_attr_flags, s ); if ( loc == NO_FLAG ) { bug("Invalid location name %s", s ); return FALSE; } if (room_attr_table[loc].bits == NULL) mod = alist->elems[3].asInt(); else mod = list_flag_value_complete( alist->elems[3].asList(), room_attr_table[loc].bits ); break; case AFTO_OBJVAL: loc = alist->elems[1].asInt(); mod = alist->elems[3].asInt(); break; case AFTO_WEAPON: // loc not revelant mod = list_flag_value_complete( alist->elems[3].asList(), weapon_type2 ); break; case AFTO_OBJECT: // loc not revelant mod = list_flag_value_complete( alist->elems[3].asList(), extra_flags ); break; default: bug("Invalid where: %s", s ); break; } int op = alist->elems[2].asInt(); //int mod = alist->elems[3].asInt(); addaff2(*paf,where,loc,op,mod); } list->explicit_free(); return TRUE; }
void log_explain(uint32_t index) { bson b; char argidx[4]; bson_init_size(&b, mem_suggested_size(1024)); bson_append_int(&b, "I", index); bson_append_string(&b, "name", sig_apiname(index)); bson_append_string(&b, "type", "info"); bson_append_string(&b, "category", sig_category(index)); bson_append_start_array(&b, "args"); bson_append_string(&b, "0", "is_success"); bson_append_string(&b, "1", "retval"); const char *fmt = sig_paramtypes(index); for (uint32_t argnum = 2; *fmt != 0; argnum++, fmt++) { ultostr(argnum, argidx, 10); // Ignore buffers, they are sent over separately. if(*fmt == '!') { argnum--; fmt++; continue; } const char *argname = sig_param_name(index, argnum-2); // On certain formats, we need to tell cuckoo about them for // nicer display / matching. if(*fmt == 'p' || *fmt == 'P') { bson_append_start_array(&b, argidx); bson_append_string(&b, "0", argname); bson_append_string(&b, "1", "p"); bson_append_finish_array(&b); } else { bson_append_string(&b, argidx, argname); } } bson_append_finish_array(&b); bson_append_start_object(&b, "flags_value"); for (uint32_t idx = 0; sig_flag_name(index, idx) != NULL; idx++) { const flag_repr_t *f = flag_value(sig_flag_value(index, idx)); bson_append_start_array(&b, sig_flag_name(index, idx)); for (uint32_t idx2 = 0; f->repr != NULL; idx2++, f++) { ultostr(idx, argidx, 10); bson_append_start_array(&b, argidx); bson_append_int(&b, "0", f->value); bson_append_string(&b, "1", f->repr); bson_append_finish_array(&b); } bson_append_finish_array(&b); } bson_append_finish_object(&b); bson_append_start_object(&b, "flags_bitmask"); for (uint32_t idx = 0; sig_flag_name(index, idx) != NULL; idx++) { const flag_repr_t *f = flag_bitmask(sig_flag_value(index, idx)); bson_append_start_array(&b, sig_flag_name(index, idx)); for (uint32_t idx2 = 0; f->repr != NULL; idx2++, f++) { ultostr(idx, argidx, 10); bson_append_start_array(&b, argidx); bson_append_int(&b, "0", f->value); bson_append_string(&b, "1", f->repr); bson_append_finish_array(&b); } bson_append_finish_array(&b); } bson_append_finish_object(&b); bson_finish(&b); log_raw(bson_data(&b), bson_size(&b)); bson_destroy(&b); }
/* Allows supermob to do damage without killing it -Flux */ void do_mpdamage( CHAR_DATA *ch, char *argument ) { char arg[ MAX_INPUT_LENGTH ]; char arg2[ MAX_INPUT_LENGTH ]; char arg3[ MAX_INPUT_LENGTH ]; CHAR_DATA *victim; int dam = 0; int damtype = 0; int dammes = TYPE_HIT; if ( !IS_NPC( ch ) ) { typo_message( ch ); return; } if ( IS_SET( ch->act , ACT_PET ) || IS_AFFECTED( ch, AFF_CHARM ) ) return; argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); argument = one_argument( argument, arg3 ); if ( arg[0] == '\0' || arg2[0] == '\0' || arg3[0] == '\0' ) { sprintf( log_buf, "MpDamage - no argument: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { sprintf( log_buf, "MpDamage - Victim not in room: vnum %d name %s short %s .", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( victim == ch ) { sprintf( log_buf, "MpDamage - Bad victim to attack: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) { sprintf( log_buf, "MpDamage - Charmed mob attacking master: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( !is_number( arg2 ) ) { sprintf( log_buf, "MpDamage - Arg2 not a # vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } dam = atoi( arg2 ); damtype = ( flag_value( damage_flags, arg3 ) ); if ( damtype <= DAM_NONE || damtype > DAM_INTERNAL ) { sprintf( log_buf, "MpDamage - Invalid damage type vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( damtype == DAM_SLASH ) dammes = DAMNOUN_SLASH; else if ( damtype == DAM_PIERCE ) dammes = DAMNOUN_PIERCE; else if ( damtype == DAM_SCRATCH ) dammes = DAMNOUN_TEAR; else if ( damtype == DAM_BASH ) dammes = DAMNOUN_STRIKE; else if ( damtype == DAM_INTERNAL ) dammes = gsn_wrack; else dammes = damtype + 913; damage( victim, victim, dam, dammes, damtype, TRUE ); return; }
/* allows supermob to add affects like poisoned, diseased, etc.. -Flux */ void do_mpaffect( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; AFFECT_DATA af; char arg[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; long affect; bool affect2 = FALSE; if ( !IS_NPC( ch ) ) { typo_message( ch ); return; } if ( IS_SET( ch->act , ACT_PET ) || IS_AFFECTED( ch, AFF_CHARM ) ) return; argument = one_argument( argument, arg ); argument = one_argument( argument, arg2 ); if ( arg[0] == '\0' || arg2[0] == '\0' ) { sprintf( log_buf, "MpAffect - no argument: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { sprintf( log_buf, "Mpaffect - Victim not in room: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( victim == ch ) { sprintf( log_buf, "Mpaffect - Bad victim to attack: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master == victim ) { sprintf( log_buf, "Mpaffect - Charmed mob attacking master: vnum %d name %s short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } affect = flag_value( mpaffect_flags, arg2 ); if ( affect == -99 || affect == -1 ) { sprintf( log_buf, "Mpaffect - invalid affect type: vnum %d, name %s, short %s.", ch->pIndexData->vnum, ch->name, ch->short_descr ); bug( log_buf, -1 ); return; } if ( !str_cmp( arg2, "poison" ) || !str_cmp( arg2, "insanity" ) ) { if ( IS_AFFECTED( ch, affect ) ) return; affect2 = FALSE; } else { if ( IS_AFFECTED2( ch, affect ) ) return; affect2 = TRUE; } if ( affect == AFF_POISON && affect2 == FALSE ) af.type = gsn_poison; else if ( affect == AFF_DISEASED && affect2 == TRUE ) af.type = gsn_plague; else if ( affect == AFF_PLASMA && affect2 == TRUE ) af.type = gsn_plasma; else if ( affect == AFF_HALLUCINATING && affect2 == TRUE ) af.type = gsn_hallucinate; else if ( affect == AFF_INSANE && affect2 == FALSE ) af.type = gsn_insane; af.level = victim->level; af.duration = dice( 1, 25 ); af.location = APPLY_NONE; af.modifier = 0; af.bitvector = affect; if ( !affect2 ) affect_to_char( victim, &af ); else affect_to_char2( victim, &af ); return; }