void find_buddy( char_data* ch, obj_data* obj, int level, int species_list, int obj_list ) { char_data* buddy; player_data* pc; species_data* species; int i; if( obj == NULL ) { bug( "Find_Buddy: Null Object as reagent!?" ); return; } if( ( pc = player( ch ) ) == NULL ) return; for( i = 0; i < 10; i++ ) if( obj->pIndexData->vnum == list_value[ obj_list ][ 10*(ch->shdata->alignment%3)+i ] ) break; if( i == 10 ) { send( ch, "Nothing happens.\n\r" ); return; } send( *ch->array, "%s disintegrates in a burst of blue flame.\n\r", obj ); obj->Extract( 1 ); if( number_range( 0,100 ) < 50-7*level+10*i ) { send( ch, "You feel the summoning fail.\n\r" ); return; } i = list_value[ species_list ][ 10*(ch->shdata->alignment%3)+i ]; if( ( species = get_species( i ) ) == NULL ) { bug( "Find_buddy: unknown species." ); return; } buddy = create_mobile( species ); set_bit( &buddy->status, STAT_PET ); remove_bit( &buddy->status, STAT_AGGR_ALL ); remove_bit( &buddy->status, STAT_AGGR_GOOD ); remove_bit( &buddy->status, STAT_AGGR_EVIL ); buddy->To( ch->array ); send( ch, "%s comes to your summons, stepping from the shadows.\n\r", buddy ); add_follower( buddy, ch ); return; }
void Thought_Bubble::set_cubby(Cubby *new_cubby, boolean also_add_follower) { // rewritten on 080205 to maintain follower links if (cubby != NULL && cubby->pointer_to_leader() == this) { remove_follower(cubby); }; cubby = new_cubby; if (new_cubby != NULL && also_add_follower && new_cubby->pointer_to_leader() != this) { add_follower(new_cubby); }; };
void chkmaster(struct char_data *ch) { struct char_data *masterplayer, *next_ch; if ((!ch->master) && (GET_MOB_SAVED_MASTER(ch) != -1)) for (masterplayer = character_list; masterplayer; masterplayer = next_ch) { next_ch = masterplayer->next; if ( masterplayer && !IS_NPC(masterplayer) && (GET_MOB_SAVED_MASTER(ch)==GET_IDNUM(masterplayer)) ) add_follower(ch, masterplayer); } }
boolean Thought_Bubble::handle_xml_tag(Tag tag, xml_node *node) { // new on 151002 switch (tag) { case BOX_TAG: // new on 021202 cubby = (Cubby *) xml_load_sprite(node,tag,cubby,CUBBY); if (cubby->pointer_to_leader_offsets() == NULL) { // restored on 050903 receive_cubby(cubby,TRUE); // experiment 280803 for dealing with thought bubbles that are about to be entered to start training } else { add_follower(cubby,TRUE,INSERT_AT_END,TRUE); }; // receive_cubby((Cubby *) xml_load_sprite(node,tag,cubby,CUBBY)); return(TRUE); case NO_MORE_TAGS: // new on 151002 set_active(TRUE); // stop pretending since can never be turned off - // and do the following (new on 121102) default: if (sprite_tag(tag)) { // new on 130703 add_follower(xml_load_sprite(node,tag),TRUE,INSERT_AT_END,TRUE); return(TRUE); } else { return(Sprite::handle_xml_tag(tag,node)); }; }; };
void do_follow( CHAR_DATA * ch, char * argument ) { CHAR_DATA * victim; char arg[ MAX_INPUT_LENGTH ]; one_argument( argument, arg ); if ( arg[ 0 ] == '\0' ) { send_to_char( AT_DGREEN, "Follow whom?\n\r", ch ); return; } if ( !( victim = get_char_room( ch, arg ) ) ) { send_to_char( AT_DGREEN, "They aren't here.\n\r", ch ); return; } if ( IS_AFFECTED( ch, AFF_CHARM ) && ch->master ) { act( AT_DGREEN, "But you'd rather follow $N!", ch, NULL, ch->master, TO_CHAR ); return; } if ( victim == ch ) { if ( !ch->master ) { send_to_char( AT_DGREEN, "Silly...you already follow yourself.\n\r", ch ); return; } stop_follower( ch ); return; } if ( ( ch->level - victim->level < -8 || ch->level - victim->level > 8 ) && !IS_HERO( ch ) ) { send_to_char( AT_DGREEN, "You feel unworthy to follow.\n\r", ch ); return; } if ( ch->master ) { stop_follower( ch ); } add_follower( ch, victim ); return; }
void Thought_Bubble::receive_cubby(Cubby *a_cubby, boolean center_cubby) { // item_being_sucked_up = a_cubby; cubby = a_cubby; // if (cubby->is_busy()) { // cubby->run_when_non_busy(this,receive_cubby_again_callback); // return; // }; // item_being_sucked_up cubby->inside_thought_bubble(); // item_being_sucked_up scale_to_fit(); // see if this fixes geometry sloppiness if (center_cubby) center_and_resize_cubby(); cubby->remove_from_floor(FALSE); add_follower(cubby); // cubby // item_being_sucked_up // ->animate_size_and_location(new_width,new_height,new_llx,new_lly, // duration, // this,sucking_up_callback); };
void do_follow( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *victim; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Follow whom?\n\r", ch ); return; } if ( ( victim = get_char_room( ch, arg ) ) == NULL ) { send_to_char( "They aren't here.\n\r", ch ); return; } if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL ) { act( "You don't wish to leave your beloved master!", ch, ch->master, NULL, NULL, NULL, TO_CHAR, SENSE_SIXTH ); return; } if ( victim == ch ) { if ( ch->master == NULL ) { send_to_char( "You already follow yourself.\n\r", ch ); return; } stop_follower( ch ); return; } if ( ch->master != NULL ) stop_follower( ch ); add_follower( ch, victim ); return; }
bool spell_tame( char_data* ch, char_data* victim, void*, int level, int ) { if( null_caster( ch, SPELL_TAME ) ) return TRUE; if( is_set( &victim->status, STAT_PET ) ) { send( ch, "%s is already tame.\r\n", victim ); return TRUE; } if( victim->species == NULL || !is_set( &victim->species->act_flags, ACT_CAN_TAME ) || makes_save( victim, ch, RES_MIND, SPELL_TAME, level ) || victim->leader != NULL || victim->shdata->level > ch->shdata->level ) { send( ch, "%s ignores you.\r\n", victim ); send( *ch->array, "%s ignores %s.\r\n", victim, ch ); return TRUE; } if( victim->shdata->level > ch->shdata->level-pet_levels( ch ) ) { send( ch, "You fail as you are unable to control more animals.\r\n" ); return TRUE; } if( is_set( &victim->species->act_flags, ACT_MOUNT ) && has_mount( ch ) ) return TRUE; if( ch->leader == victim ) stop_follower( ch ); set_bit( &victim->status, STAT_PET ); set_bit( &victim->status, STAT_TAMED ); remove_bit( &victim->status, STAT_AGGR_ALL ); remove_bit( &victim->status, STAT_AGGR_GOOD ); remove_bit( &victim->status, STAT_AGGR_EVIL ); add_follower( victim, ch ); return TRUE; }
static void event_zombie_master(struct char_data *ch, char *arg) { struct room_data *rp = NULL; struct char_data *master = NULL; struct char_data *mob = NULL; int i = 0; int j = 0; if (DEBUG > 1) log_info("called %s with %s, %s", __PRETTY_FUNCTION__, SAFE_NAME(ch), VNULL(arg)); if ((rp = real_roomp(ch->in_room))) { master = read_mobile(666, VIRTUAL); /* xenthia, lady of the dead */ j = dice(1, 4) + 3; if (IS_SET(ch->specials.act, PLR_STEALTH)) allprintf ("\r\nYou feel a darkening of the land.\r\nYou hear a low moaning wind arise nearby...\r\n\r\n"); else allprintf ("\r\n%s begins a low incantation, and a bolt of ebon lightning strikes %s upraised hands!\r\nYou hear a low moaning wind arise nearby...\r\n\r\n", GET_NAME(ch), HSHR(ch)); for (i = 0; i < j; i++) { mob = read_mobile(100, VIRTUAL); /* zombie */ char_to_room(mob, ch->in_room); SET_BIT(mob->specials.affected_by, AFF_CHARM); GET_EXP(mob) = number(300, 500); add_follower(mob, master); mob->points.max_hit = dice(4, 10) + 10; mob->points.hit = mob->points.max_hit; AddHatred(master->followers->follower, OP_VNUM, ZM_NEMESIS); SET_BIT(master->followers->follower->specials.act, ACT_GUARDIAN); SET_BIT(master->followers->follower->specials.act, ACT_USE_ITEM); SET_BIT(master->followers->follower->specials.affected_by, AFF_FLYING); } char_to_room(master, ch->in_room); } }
void mag_summons(int level, struct char_data *ch, struct obj_data *obj, int spellnum, int savetype) { struct char_data *mob = NULL; struct obj_data *tobj, *next_obj; int pfail = 0, msg = 0, fmsg = 0, num = 1, handle_corpse = FALSE, i; mob_vnum mob_num; if (ch == NULL) return; switch (spellnum) { case SPELL_CLONE: msg = 10; fmsg = rand_number(2, 6); /* Random fail message. */ mob_num = MOB_CLONE; pfail = 50; /* 50% failure, should be based on something later. */ break; case SPELL_ANIMATE_DEAD: if (obj == NULL || !IS_CORPSE(obj)) { act(mag_summon_fail_msgs[7], FALSE, ch, 0, 0, TO_CHAR); return; } handle_corpse = TRUE; msg = 11; fmsg = rand_number(2, 6); /* Random fail message. */ mob_num = MOB_ZOMBIE; pfail = 10; /* 10% failure, should vary in the future. */ break; default: return; } if (AFF_FLAGGED(ch, AFF_CHARM)) { send_to_char(ch, "You are too giddy to have any followers!\r\n"); return; } if (rand_number(0, 101) < pfail) { send_to_char(ch, "%s", mag_summon_fail_msgs[fmsg]); return; } for (i = 0; i < num; i++) { if (!(mob = read_mobile(mob_num, VIRTUAL))) { send_to_char(ch, "You don't quite remember how to make that creature.\r\n"); return; } char_to_room(mob, IN_ROOM(ch)); IS_CARRYING_W(mob) = 0; IS_CARRYING_N(mob) = 0; SET_BIT(AFF_FLAGS(mob), AFF_CHARM); if (spellnum == SPELL_CLONE) { /* Don't mess up the prototype; use new string copies. */ mob->player.name = strdup(GET_NAME(ch)); mob->player.short_descr = strdup(GET_NAME(ch)); } act(mag_summon_msgs[msg], FALSE, ch, 0, mob, TO_ROOM); add_follower(mob, ch); } if (handle_corpse) { for (tobj = obj->contains; tobj; tobj = next_obj) { next_obj = tobj->next_content; obj_from_obj(tobj); obj_to_char(tobj, mob); } extract_obj(obj); } }
void do_buy( char_data *ch, char *argument ) { char buf [ MAX_INPUT_LENGTH ]; char_data* keeper; char_data* pet; obj_data* obj; room_data* room; thing_array* array; if( ( keeper = find_keeper( ch ) ) == NULL ) return; /* PET SHOP */ if( is_set( &ch->in_room->room_flags, RFLAG_PET_SHOP ) ) { if( ch->species != NULL ) { send( ch, "Monsters can't buy pets." ); return; } if( ( room = get_room_index( ch->in_room->vnum+1 ) ) == NULL ) { send( ch, "The pet shop is still under construction.\r\n" ); return; } thing_array list; for( int i = 0; i < room->contents; i++ ) if( ( pet = character( room->contents[i] ) ) != NULL && buyable_pet( pet ) ) list += pet; if( ( pet = one_character( ch, argument, "buy", &list ) ) == NULL ) return; if( pet->shdata->level > ch->shdata->level ) { send( ch, "%s is too high a level for you.\r\n", pet ); return; } if( pet->species->price == 0 ) { send( ch, "That pet is not for sale until a god sets a price for it.\r\n" ); return; } if( is_set( &pet->species->act_flags, ACT_MOUNT ) ) { if( has_mount( ch ) ) return; } else { if( number_of_pets( ch ) >= 2 ) { send( ch, "You already have two pets.\r\n" ); return; } } sprintf( buf, "You hand %s", keeper->descr->name ); if( !remove_coins( ch, pet->species->price, buf ) ) { if( ch->shdata->level < LEVEL_APPRENTICE ) { send( ch, "You can't afford it.\r\n" ); return; } send( ch, "You don't have enough gold, but it doesn't seem to\ matter.\r\n" ); } pet->From( ); pet->To( ch->array ); set_bit( &pet->status, STAT_PET ); add_follower( pet, ch ); send( ch, "Enjoy your pet.\r\n" ); fsend( ch, "%s bought %s as a pet.\r\n", ch, pet ); if( pet->reset != NULL ) { pet->reset->count--; pet->reset = NULL; } return; } /* OBJECT SHOP */ thing_array list; for( int i = 0; i < keeper->contents; i++ ) { obj = (obj_data*) keeper->contents[i]; if( will_trade( keeper, obj ) ) list += obj; } if( ( array = several_things( ch, argument, "buy", &list ) ) == NULL ) return; thing_array subset [ 4 ]; thing_func* func [ 4 ] = { heavy, many, cantafford, buy }; sort_objects( ch, *array, keeper, 4, subset, func ); page_priv( ch, NULL, empty_string ); page_priv( ch, &subset[0], "can't lift" ); page_priv( ch, &subset[1], "can't handle" ); page_priv( ch, &subset[2], "can't afford" ); page_publ( ch, &subset[3], "buy", keeper, "from", "for" ); delete array; }
void find_familiar( char_data* ch, obj_data* obj, int level, int species_list, int obj_list ) { char_data* familiar; player_data* pc; species_data* species; int i; if( obj == NULL ) { bug( "Find_Familiar: Null Object as reagent!?" ); return; } if( ( pc = player( ch ) ) == NULL ) return; if( ch->shdata->level < LEVEL_APPRENTICE && is_set( ch->pcdata->pfile->flags, PLR_FAMILIAR ) ) { send( ch, "Nothing happens.\n\r" ); send( ch, "You can only summon one familiar per level.\n\r" ); return; } if( pc->familiar != NULL ) { send( ch, "Nothing happens.\n\r" ); send( ch, "You can only have one familiar at a time.\n\r" ); return; } for( i = 0; i < 10; i++ ) if( obj->pIndexData->vnum == list_value[ obj_list ][ 10*(ch->shdata->alignment%3)+i ] ) break; if( i == 10 ) { send( ch, "Nothing happens.\n\r" ); return; } send( *ch->array, "%s disintegrates in a burst of blue flame.\n\r", obj ); obj->Extract( 1 ); if( number_range( 0,100 ) < 50-7*level+10*i ) { send( ch, "You feel the summoning fail.\n\r" ); return; } i = list_value[ species_list ][ 10*(ch->shdata->alignment%3)+i ]; if( ( species = get_species( i ) ) == NULL ) { bug( "Find_familiar: unknown species." ); return; } familiar = create_mobile( species ); familiar->reset = NULL; pc->familiar = familiar; set_bit( &familiar->status, STAT_PET ); set_bit( &familiar->status, STAT_FAMILIAR ); set_bit( ch->pcdata->pfile->flags, PLR_FAMILIAR ); remove_bit( &familiar->status, STAT_AGGR_ALL ); remove_bit( &familiar->status, STAT_AGGR_GOOD ); remove_bit( &familiar->status, STAT_AGGR_EVIL ); familiar->To( ch->array ); send( ch, "%s comes to your summons, stepping from the shadows.\n\r", familiar ); add_follower( familiar, ch ); return; }
void do_resurrect(CHAR_DATA *ch, char *argument ) { char buf2[MAX_STRING_LENGTH]; char buf [MAX_INPUT_LENGTH]; char arg [MAX_STRING_LENGTH]; CHAR_DATA *victim; AFFECT_DATA af; OBJ_DATA *obj; one_argument(argument,arg); if (IS_NPC(ch)) return; if (!IS_CLASS(ch, CLASS_WIZARD)) { send_to_char("Huh?\n\r",ch); return; } if (arg[0] == '\0') { send_to_char("Resurrect what corpse?\n\r",ch); return; } if ( IS_CLASS(ch, CLASS_WIZARD) && ch->pcdata->powers[WL_SKILLS] < 1 ) { stc("You need level 1 in Wizard Skills\n\r",ch); return; } if (ch->pcdata->followers > 5) { send_to_char("Nothing happens.\n\r",ch); return; } if ((obj = get_obj_carry(ch,arg)) == NULL) { send_to_char("You dont have that corpse.",ch); return; } if (obj->item_type != ITEM_CORPSE_NPC) { send_to_char("You can only Resurrect original corpses.\n\r",ch); return; } ch->pcdata->followers++; victim=create_mobile( get_mob_index( obj->value[2] ) ); sprintf(buf,"Resurrection of %s",victim->short_descr); sprintf(buf2,"Resurrection of %s is here.\n\r",victim->short_descr); free_string(victim->short_descr); victim->short_descr = str_dup(buf); free_string(victim->name); SET_BIT(victim->act, ACT_NOEXP); if ( IS_SET(victim->act,ACT_QUEST) ) REMOVE_BIT(victim->act,ACT_QUEST); victim->name = str_dup(buf); free_string(victim->long_descr); victim->long_descr= str_dup(buf2); victim->spec_fun = NULL; sprintf(buf,"I invoke the rebirth of %s!",victim->name); do_say( ch, buf ); sprintf(buf, "%s clambers back up to its feet.\n\r",obj->short_descr); act(buf,ch,NULL,NULL,TO_ROOM); send_to_char(buf,ch); char_to_room( victim, ch->in_room ); WAIT_STATE(ch,10); extract_obj(obj); if(victim->level > ((ch->pcdata->upgrade_level + 1) * 500)) { send_to_char("You are unable to control the resurrected creature.\n\r", ch); return; } add_follower( victim, ch ); af.type = skill_lookup ("charm person"); af.duration = 666; af.location = APPLY_NONE; af.modifier = 0; af.bitvector = AFF_CHARM; affect_to_char( victim, &af ); sprintf(buf,"%s",victim->name); do_group(ch,buf); return; }
void do_buy_mount( CHAR_DATA *ch, char *argument ) { int cost,roll; char arg[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; char color[80], name[30], size[30]; CHAR_DATA *mount; ROOM_INDEX_DATA *pRoomIndexNext; ROOM_INDEX_DATA *in_room; name[0] = '\0'; size[0] = '\0'; color[0] = '\0'; if ( IS_NPC(ch) ) return; if (!IS_NPC(ch) && !ch->pcdata->learned[gsn_riding]) { send_to_char("How do you expect to buy a horse when you can't even ride?\n\r", ch); return; } argument = one_argument(argument,arg); pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( pRoomIndexNext == NULL ) { bug( "Do_buy: bad mount shop at vnum %d.", ch->in_room->vnum ); send_to_char( "I'm afraid the stalls where I keep my mounts don't exist.\n\r", ch ); return; } in_room = ch->in_room; ch->in_room = pRoomIndexNext; mount = get_char_room( ch, arg ); ch->in_room = in_room; if ( mount == NULL) { send_to_char( "Sorry, we don't sell any of those here.\n\r", ch ); return; } if ( !IS_SET(mount->act3, ACT3_MOUNT) ) { send_to_char( "Sorry, we don't sell any of those here.\n\r", ch ); return; } if ( MOUNTED(ch) || ch->mount != NULL) { send_to_char("You already have a mount.\n\r",ch); return; } cost = 100 * ch->level; if ( ch->gold < cost ) { send_to_char( "You can't afford it.\n\r", ch ); return; } roll = number_percent(); if (!IS_NPC(ch) && roll < ch->pcdata->learned[gsn_haggle]) { cost -= cost / 2 * roll / 100; sprintf(buf,"You haggle the price down to %d coins.\n\r",cost); send_to_char(buf,ch); check_improve(ch,gsn_haggle,TRUE,4); } ch->gold -= cost; mount = create_mobile( mount->pIndexData ); mount->comm = COMM_NOTELL|COMM_NOSHOUT|COMM_NOCHANNELS; mount->max_hit = mount->hit = (ch->level * 4) - (25 + number_range(1,50)); if( mount->max_hit < 25 ) mount->max_hit = mount->hit = 25; mount->max_mana = mount->mana = 50; mount->max_move = mount->move = 200 + ch->level * 10; mount->level = ch->level / 1.25; mount->sex = ch->sex; switch( number_range(1,11) ) { case 1: strcpy(color, "dappled grey" ); break; case 2: strcpy(color, "charcoal grey" ); break; case 3: strcpy(color, "midnight black" ); break; case 4: strcpy(color, "dark burgundy" ); break; case 5: strcpy(color, "cream yellow" ); break; case 6: strcpy(color, "pure white"); break; case 7: strcpy(color, "dark brown"); break; case 8: strcpy(color, "light brown"); break; case 9: strcpy(color, "white and brown spotted"); break; case 10: strcpy(color, "black and white spotted"); break; case 11: strcpy(color, "purple and green striped"); strcpy(size, "mutant "); mount->hit += 100; mount->max_hit += 100; break; } if( ch->level >= 41 ) { strcpy(name, "pegasus"); SET_BIT(mount->affected_by, AFF_FLYING); } else if( ch->level >= 30 ) { if (ch->sex == 1) strcpy(name, "gelding"); else { strcpy(name, "mare"); strcat(size, "majestic "); } } else if( ch->level >= 20 ) { if (ch->sex == 1) strcpy(name, "stallion"); else strcpy(name, "mare"); } else if( ch->level >= 15 ) { strcpy(name, "horse"); } else if( ch->level >= 10 ) { strcpy(name, "horse"); strcat(size, "small "); } else { strcpy(name, "pony"); } argument = one_argument( argument, arg ); if ( arg[0] != '\0' ) sprintf( buf, "%s %s", name, arg ); else sprintf( buf, "%s", name ); free_string( mount->name ); mount->name = str_dup( buf ); sprintf( buf, "a %s%s %s", size, color, name ); free_string( mount->short_descr ); mount->short_descr = str_dup( buf ); sprintf( buf, "A %s%s %s is standing here.\n\r", size, color, name ); free_string( mount->long_descr ); mount->long_descr = str_dup( buf ); sprintf( buf, "%sThe name %s is branded on its hind leg.\n\r", mount->description, ch->name ); free_string( mount->description ); mount->description = str_dup( buf ); char_to_room( mount, ch->in_room ); add_follower( mount, ch ); act( "$n bought $N as a mount.", ch, NULL, mount, TO_ROOM ); sprintf( buf, "Enjoy your %s.\n\r", name ); send_to_char( buf, ch); do_mount( ch, name ); return; }
/* the main engine of charm spell, and similar */ void effect_charm(struct char_data *ch, struct char_data *victim, int spellnum) { struct affected_type af; int elf_bonus = 0; if (!IS_NPC(victim) && (GET_RACE(victim) == RACE_ELF || //elven enchantment resistance GET_RACE(victim) == RACE_H_ELF)) // added check for IS_NPC because NPCRACE_HUMAN == RACE_ELF and NPCRACE_ABERRATION == RACE_H_ELF elf_bonus += 2; if (victim == ch) send_to_char(ch, "You like yourself even better!\r\n"); else if (MOB_FLAGGED(victim, MOB_NOCHARM)) { send_to_char(ch, "Your victim doesn't seem vulnerable to this " "enchantments!\r\n"); if (IS_NPC(victim)) hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE); } else if (IS_AFFECTED(victim, AFF_MIND_BLANK)) { send_to_char(ch, "Your victim is protected from this " "enchantment!\r\n"); if (IS_NPC(victim)) hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE); } else if (AFF_FLAGGED(ch, AFF_CHARM)) send_to_char(ch, "You can't have any followers of your own!\r\n"); else if (AFF_FLAGGED(victim, AFF_CHARM)) send_to_char(ch, "Your victim is already charmed.\r\n"); else if (spellnum == SPELL_CHARM && (CASTER_LEVEL(ch) < GET_LEVEL(victim) || GET_LEVEL(victim) >= 8)) send_to_char(ch, "Your victim is too powerful.\r\n"); else if ((spellnum == SPELL_DOMINATE_PERSON || spellnum == SPELL_MASS_DOMINATION) && CASTER_LEVEL(ch) < GET_LEVEL(victim)) send_to_char(ch, "Your victim is too powerful.\r\n"); /* player charming another player - no legal reason for this */ else if (!CONFIG_PK_ALLOWED && !IS_NPC(victim)) send_to_char(ch, "You fail - shouldn't be doing it anyway.\r\n"); else if (circle_follow(victim, ch)) send_to_char(ch, "Sorry, following in circles is not allowed.\r\n"); else if (mag_resistance(ch, victim, 0)) { send_to_char(ch, "You failed to penetrate the spell resistance!"); if (IS_NPC(victim)) hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE); } else if (mag_savingthrow(ch, victim, SAVING_WILL, elf_bonus)) { send_to_char(ch, "Your victim resists!\r\n"); if (IS_NPC(victim)) hit(victim, ch, TYPE_UNDEFINED, DAM_RESERVED_DBC, 0, FALSE); } else { /* slippery mind gives a second save */ if (!IS_NPC(victim) && GET_SKILL(victim, SKILL_SLIPPERY_MIND)) { increase_skill(victim, SKILL_SLIPPERY_MIND); send_to_char(victim, "\tW*Slippery Mind*\tn "); if (mag_savingthrow(ch, victim, SAVING_WILL, 0)) { return; } } if (victim->master) stop_follower(victim); add_follower(victim, ch); new_affect(&af); if (spellnum == SPELL_CHARM) af.spell = SPELL_CHARM; if (spellnum == SPELL_CHARM_ANIMAL) af.spell = SPELL_CHARM_ANIMAL; else if (spellnum == SPELL_DOMINATE_PERSON) af.spell = SPELL_DOMINATE_PERSON; else if (spellnum == SPELL_MASS_DOMINATION) af.spell = SPELL_MASS_DOMINATION; af.duration = 100; if (GET_CHA_BONUS(ch)) af.duration += GET_CHA_BONUS(ch) * 4; SET_BIT_AR(af.bitvector, AFF_CHARM); affect_to_char(victim, &af); act("Isn't $n just such a nice fellow?", FALSE, ch, 0, victim, TO_VICT); // if (IS_NPC(victim)) // REMOVE_BIT_AR(MOB_FLAGS(victim), MOB_SPEC); } // should never get here }
void do_buy( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int maxgold; bool debit; OBJ_DATA *obj; argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Buy what?\n\r", ch ); return; } if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *pet; ROOM_INDEX_DATA *pRoomIndexNext; ROOM_INDEX_DATA *in_room; if ( argument[0] == '\0' ) debit = FALSE; else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) ) { bool has_card = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_DEBIT_CARD ) has_card = TRUE; } if ( has_card == TRUE ) debit = TRUE; else { send_to_char( "You don't even have your card with you!\n\r", ch ); return; } } if ( IS_NPC(ch) ) return; pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( !pRoomIndexNext ) { bug( "Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum ); send_to_char( "Sorry, you can't buy that here.\n\r", ch ); return; } in_room = ch->in_room; ch->in_room = pRoomIndexNext; pet = get_char_room( ch, arg ); ch->in_room = in_room; if ( pet == NULL || !IS_NPC( pet ) || !IS_SET(pet->act, ACT_PET) ) { send_to_char( "Sorry, you can't buy that here.\n\r", ch ); return; } if (( ch->gold < 10 * pet->top_level * pet->top_level ) && debit == FALSE) { send_to_char( "You can't afford it.\n\r", ch ); return; } else if ( (ch->pcdata->bank < 10 * pet->top_level * pet->top_level) && debit == TRUE ) { send_to_char( "You dont have enough money in your bank account for it.\n\r", ch ); return; } maxgold = 10 * pet->top_level * pet->top_level; if ( debit == FALSE ) ch->gold -= maxgold; /* this was already here, btw */ else ch->pcdata->bank -= maxgold; boost_economy( ch->in_room->area, maxgold ); pet = create_mobile( pet->pIndexData ); SET_BIT(pet->act, ACT_PET); SET_BIT(pet->affected_by, AFF_CHARM); argument = one_argument( argument, arg ); if ( arg[0] != '\0' ) { sprintf( buf, "%s %s", pet->name, arg ); STRFREE( pet->name ); pet->name = STRALLOC( buf ); } sprintf( buf, "%sA neck tag says 'I belong to %s'.\n\r", pet->description, ch->name ); STRFREE( pet->description ); pet->description = STRALLOC( buf ); char_to_room( pet, ch->in_room ); add_follower( pet, ch ); send_to_char( "Enjoy your pet.\n\r", ch ); act( AT_ACTION, "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM ); return; } else { CHAR_DATA *keeper; int cost; int noi = 1; /* Number of items */ sh_int mnoi = 20; /* Max number of items to be bought at once */ if ( ( keeper = find_keeper( ch ) ) == NULL ) return; maxgold = keeper->top_level * 10; if ( is_number( arg ) ) { noi = atoi( arg ); argument = one_argument( argument, arg ); if ( noi > mnoi ) { act( AT_TELL, "$n tells you 'I don't sell that many items at" " once.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } } if ( argument[0] == '\0' ) debit = FALSE; else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) ) { bool has_card = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_DEBIT_CARD ) has_card = TRUE; } if ( has_card == TRUE ) debit = TRUE; else { send_to_char( "You don't even have your card with you!\n\r", ch ); return; } } obj = get_obj_carry( keeper, arg ); if ( !obj && arg[0] == '#' ) { int onum, oref; bool ofound = FALSE; onum =0; oref = atoi(arg+1); for ( obj = keeper->last_carrying; obj; obj = obj->prev_content ) { if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) onum++; if ( onum == oref ) { ofound = TRUE; break; } else if ( onum > oref ) break; } if (!ofound) obj = NULL; } if (keeper->home != NULL && obj->cost > 0) cost= obj->cost; cost = ( get_cost( ch, keeper, obj, TRUE ) * noi ); if( !IS_NPC(ch) && ch->pcdata->learned[gsn_bargain] > 0 && ch->pcdata->learned[gsn_bargain] > number_percent()) { ch_printf(ch,"You are able to bargain from %d credits to %d credits!\n\r", cost, (cost/3)+(cost/2)); cost = (cost/3) + (cost/2); if(number_percent() > 50) learn_from_success(ch, gsn_bargain); } if ( cost <= 0 || !can_see_obj( ch, obj ) ) { act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) ) { interpret( keeper, "laugh" ); act( AT_TELL, "$n tells you 'I don't have enough of those in stock" " to sell more than one at a time.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->gold < cost && debit == FALSE) { act( AT_TELL, "$n tells you 'You can't afford to buy $p.'", keeper, obj, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->pcdata->bank < cost && debit == TRUE) { send_to_char( "You are almost slide your card through, but you remember you don't have enough money!\n\r", ch ); return; } if ( IS_SET(obj->extra_flags, ITEM_PROTOTYPE) && get_trust( ch ) < LEVEL_IMMORTAL ) { act( AT_TELL, "$n tells you 'This is a only a prototype! I can't sell you that...'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { send_to_char( "You can't carry that many items.\n\r", ch ); return; } if ( ch->carry_weight + ( get_obj_weight( obj ) * noi ) + (noi > 1 ? 2 : 0) > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\n\r", ch ); return; } if ( noi == 1 ) { if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) separate_obj( obj ); act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR ); } else { sprintf( arg, "$n buys %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM ); sprintf( arg, "You buy %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$N puts them into a bag and hands it to you.", ch, NULL, keeper, TO_CHAR ); } if ( debit == FALSE ) ch->gold -= cost; /* this line was already here, btw */ else if ( debit == TRUE ) ch->pcdata->bank -= cost; keeper->gold += cost; if ( keeper->gold > maxgold ) { boost_economy( keeper->in_room->area, keeper->gold - maxgold/2 ); keeper->gold = maxgold/2; act( AT_ACTION, "$n puts some credits into a large safe.", keeper, NULL, NULL, TO_ROOM ); } if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) { OBJ_DATA *buy_obj, *bag; buy_obj = create_object( obj->pIndexData, obj->level ); /* * Due to grouped objects and carry limitations in SMAUG * The shopkeeper gives you a bag with multiple-buy, * and also, only one object needs be created with a count * set to the number bought. -Thoric */ if ( noi > 1 ) { bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ), 1 ); /* perfect size bag ;) */ bag->value[0] = bag->weight + (buy_obj->weight * noi); buy_obj->count = noi; obj->pIndexData->count += (noi - 1); numobjsloaded += (noi - 1); obj_to_obj( buy_obj, bag ); obj_to_char( bag, ch ); } else obj_to_char( buy_obj, ch ); } else { obj_from_char( obj ); obj_to_char( obj, ch ); } return; } }
int pet_shops(struct char_data *ch, int cmd, char *arg) { char buf[MAX_STRING_LENGTH], pet_name[256]; int pet_room; struct char_data *pet; pet_room = ch->in_room+1; if (cmd==59) { /* List */ send_to_char("Available pets are:\n\r", ch); for(pet = world[pet_room].people; pet; pet = pet->next_in_room) { sprintf(buf, "%8d - %s\n\r", 3*GET_EXP(pet), pet->player.short_descr); send_to_char(buf, ch); } return(TRUE); } else if (cmd==56) { /* Buy */ arg = one_argument(arg, buf); arg = one_argument(arg, pet_name); /* Pet_Name is for later use when I feel like it */ if (!(pet = get_char_room(buf, pet_room))) { send_to_char("There is no such pet!\n\r", ch); return(TRUE); } if (GET_GOLD(ch) < (GET_EXP(pet)*3)) { send_to_char("You don't have enough gold!\n\r", ch); return(TRUE); } GET_GOLD(ch) -= GET_EXP(pet)*3; pet = read_mobile(pet->nr, REAL); GET_EXP(pet) = 0; SET_BIT(pet->specials.affected_by, AFF_CHARM); if (*pet_name) { sprintf(buf,"%s %s", pet->player.name, pet_name); free(pet->player.name); pet->player.name = strdup(buf); sprintf(buf,"%sA small sign on a chain around the neck says 'My Name is %s'\n\r", pet->player.description, pet_name); free(pet->player.description); pet->player.description = strdup(buf); } char_to_room(pet, ch->in_room); add_follower(pet, ch); /* Be certain that pet's can't get/carry/use/weild/wear items */ IS_CARRYING_W(pet) = 1000; IS_CARRYING_N(pet) = 100; send_to_char("May you enjoy your pet.\n\r", ch); act("$n bought $N as a pet.",FALSE,ch,0,pet,TO_ROOM); return(TRUE); } /* All commands except list and buy */ return(FALSE); }