/*! \file randplace.c The randplace command is used to randomly place objects or tokens around the world in specific areas, on the ground or on mobs, and/or within a specified level range. The immortal must be carrying the objects. Syntax : RANDPLACE <n*obj> mob|ground world|area <num>|level <lvl_num> World places objects anywhere. Area places objects in the area that occurs at position num in the area list. Level places objects in areas with that level range. Example: randplace 25*tokens ground area 7 will place 25 tokens on the ground randomly in midgaard. \author Jon A. Lambert \version 1.96 \date 06/27/2002 \remarks This code copyright (C) 2000-2002 by Jon A. Lambert<BR> <antilochos@ix.netcom.com> - All rights reserved.<BR> No part of this code may be used without my written consent.<BR> This code released to the PUBLIC DOMAIN on 4/2/2006 */ #include <stdio.h> #include <stdlib.h> #include "merc.h" void do_randplace (CHAR_DATA * ch, char *argument) { extern AREA_DATA *area_first; char arg1[MAX_INPUT_LENGTH]; char arg2[MAX_INPUT_LENGTH]; char arg3[MAX_INPUT_LENGTH]; char arg4[MAX_INPUT_LENGTH]; char buf[MAX_STRING_LENGTH]; CHAR_DATA *pmob; ROOM_INDEX_DATA *proom = NULL; AREA_DATA *parea; AREA_DATA *usearea = NULL; OBJ_DATA *obj; int number, vnumindex, count; int in_world = 0; int in_area = 0; int at_level = 0; int level_or_vnum = 0; int stop_on; int i; if (argument == NULL || argument[0] == '\0') { send_to_char ("Syntax : RANDPLACE <n*obj> mob|ground world|area <num>|level <lvl_num>\r\n", ch); send_to_char (" World places objects anywhere.\r\n", ch); send_to_char (" Area places objects in the area that occurs at position num in the area list.\r\n", ch); send_to_char (" Level places objects in areas with that level range.\r\n", ch); send_to_char ("Example: randplace 25*tokens ground area 7\r\n", ch); send_to_char (" will place 25 tokens on the ground randomly in midgaard.\r\n", ch); return; } argument = one_argument (argument, arg1); argument = one_argument (argument, arg2); argument = one_argument (argument, arg3); argument = one_argument (argument, arg4); number = mult_argument (arg1, arg1); if (number < 1 || number > 50) { send_to_char ("You can only randomly place between 1 and 50 objects at a time.\r\n", ch); return; } if ((obj = get_obj_carry (ch, arg1, ch)) == NULL) { send_to_char ("You are not carrying that item.\r\n", ch); return; } if (str_cmp (arg2, "mob") && str_cmp (arg2, "ground")) { send_to_char ("Do you want to place the objects on MOBs or on the GROUND?\r\n", ch); return; } if (str_cmp (arg3, "world") && str_cmp (arg3, "area") && str_cmp (arg3, "level")) { send_to_char ("How do you want to place the objects, anywhere in the WORLD, in a specific AREA, or by LEVEL.\r\n", ch); return; } if ((arg4 == NULL || arg4[0] == '\0') && str_cmp (arg3, "world")) { send_to_char ("Last argument must be a vnum if AREA or level number if LEVEL.\r\n", ch); return; } if (is_number (arg4)) { level_or_vnum = atoi (arg4); if (!str_cmp (arg3, "area")) { for (parea = area_first, i = 0; parea != NULL; parea = parea->next, i++) { if (level_or_vnum == i) { usearea = parea; break; } } } } /* Get counts on possible valid placements */ if (!str_cmp (arg2, "mob")) { for (pmob = char_list; pmob != NULL; pmob = pmob->next) { if (!IS_NPC (pmob)) continue; if (IS_SET (pmob->act, ACT_NOPURGE) || pmob->pIndexData == NULL || pmob->pIndexData->pShop != NULL || IS_SET (pmob->imm_flags, IMM_SUMMON) || IS_SET (pmob->act, ACT_PET) || IS_SET (pmob->affected_by, AFF_CHARM) || IS_SET (pmob->act, ACT_IS_HEALER)) continue; in_world++; if (pmob->level >= level_or_vnum && pmob->level <= level_or_vnum + 10) at_level++; if (pmob->in_room && usearea && usearea == pmob->in_room->area) in_area++; } } else { for (parea = area_first; parea != NULL; parea = parea->next) { for (vnumindex = parea->min_vnum; vnumindex <= parea->max_vnum; vnumindex++) { if ((proom = get_room_index (vnumindex)) != NULL) { if (IS_SET (proom->room_flags, ROOM_IMP_ONLY) || IS_SET (proom->room_flags, ROOM_PRIVATE) || IS_SET (proom->room_flags, ROOM_GODS_ONLY) || proom->clan != 0 || IS_SET (proom->room_flags, ROOM_NOWHERE)) continue; in_world++; if (usearea && usearea == parea) in_area++; if (level_or_vnum >= parea->low_range && level_or_vnum <= parea->high_range) at_level++; } } } } count = 0; while (count < number) { if (!CAN_WEAR (obj, ITEM_TAKE)) { act ("$p is not flagged as TAKEable and will not be placed.\r\n", ch, obj, 0, TO_CHAR); break; } if (!str_cmp (arg3, "world")) stop_on = number_range (1, in_world); else if (!str_cmp (arg3, "area")) stop_on = number_range (1, in_area); else stop_on = number_range (1, at_level); i = 0; if (!str_cmp (arg2, "mob")) { if (!str_cmp (arg3, "world")) { for (pmob = char_list; pmob != NULL; pmob = pmob->next) { if (!IS_NPC (pmob)) continue; if (IS_SET (pmob->act, ACT_NOPURGE) || pmob->pIndexData == NULL || pmob->pIndexData->pShop != NULL || IS_SET (pmob->imm_flags, IMM_SUMMON) || IS_SET (pmob->act, ACT_PET) || IS_SET (pmob->affected_by, AFF_CHARM) || IS_SET (pmob->act, ACT_IS_HEALER)) continue; i++; if (stop_on == i) break; } } else if (!str_cmp (arg3, "level")) { for (pmob = char_list; pmob != NULL; pmob = pmob->next) { if (!IS_NPC (pmob)) continue; if (IS_SET (pmob->act, ACT_NOPURGE) || pmob->pIndexData == NULL || pmob->pIndexData->pShop != NULL || IS_SET (pmob->imm_flags, IMM_SUMMON) || IS_SET (pmob->act, ACT_PET) || IS_SET (pmob->affected_by, AFF_CHARM) || IS_SET (pmob->act, ACT_IS_HEALER)) continue; if (pmob->level >= level_or_vnum && pmob->level <= level_or_vnum + 10) i++; if (stop_on == i) break; } } else { for (pmob = char_list; pmob != NULL; pmob = pmob->next) { if (!IS_NPC (pmob)) continue; if (IS_SET (pmob->act, ACT_NOPURGE) || pmob->pIndexData == NULL || pmob->pIndexData->pShop != NULL || IS_SET (pmob->imm_flags, IMM_SUMMON) || IS_SET (pmob->act, ACT_PET) || IS_SET (pmob->affected_by, AFF_CHARM) || IS_SET (pmob->act, ACT_IS_HEALER)) continue; if (pmob->in_room && usearea && usearea == pmob->in_room->area) i++; if (stop_on == i) break; } } if (!pmob) return; obj_from_char (obj); obj_to_char (obj, pmob); sprintf (buf, "%s [%d] placed on mob %s [%d].\r\n", obj->short_descr, obj->pIndexData->vnum, pmob->short_descr, pmob->pIndexData->vnum); send_to_char (buf, ch); } else { bool leave = FALSE; if (!str_cmp (arg3, "world")) { for (parea = area_first; parea != NULL; parea = parea->next) { for (vnumindex = parea->min_vnum; vnumindex <= parea->max_vnum; vnumindex++) { if ((proom = get_room_index (vnumindex)) != NULL) { if (IS_SET (proom->room_flags, ROOM_IMP_ONLY) || IS_SET (proom->room_flags, ROOM_PRIVATE) || IS_SET (proom->room_flags, ROOM_GODS_ONLY) || proom->clan != 0 || IS_SET (proom->room_flags, ROOM_NOWHERE)) continue; i++; if (stop_on == i) { leave = TRUE; break; } } } if (leave) break; } } else if (!str_cmp (arg3, "level")) { for (parea = area_first; parea != NULL; parea = parea->next) { for (vnumindex = parea->min_vnum; vnumindex <= parea->max_vnum; vnumindex++) { if ((proom = get_room_index (vnumindex)) != NULL) { if (IS_SET (proom->room_flags, ROOM_IMP_ONLY) || IS_SET (proom->room_flags, ROOM_PRIVATE) || IS_SET (proom->room_flags, ROOM_GODS_ONLY) || proom->clan != 0 || IS_SET (proom->room_flags, ROOM_NOWHERE)) continue; if (level_or_vnum >= parea->low_range && level_or_vnum <= parea->high_range) i++; if (stop_on == i) { leave = TRUE; break; } } } if (leave) break; } } else { for (parea = area_first; parea != NULL; parea = parea->next) { for (vnumindex = parea->min_vnum; vnumindex <= parea->max_vnum; vnumindex++) { if ((proom = get_room_index (vnumindex)) != NULL) { if (IS_SET (proom->room_flags, ROOM_IMP_ONLY) || IS_SET (proom->room_flags, ROOM_PRIVATE) || IS_SET (proom->room_flags, ROOM_GODS_ONLY) || proom->clan != 0 || IS_SET (proom->room_flags, ROOM_NOWHERE)) continue; if (usearea && usearea == parea) i++; if (stop_on == i) { leave = TRUE; break; } } } if (leave) break; } } if (!proom) return; obj_from_char (obj); obj_to_room (obj, proom); sprintf (buf, "%s [%d] placed in room %s [%d].\r\n", obj->short_descr, obj->pIndexData->vnum, proom->name, proom->vnum); send_to_char (buf, ch); } count++; obj = get_obj_carry (ch, arg1, ch); if (obj == NULL) { break; } } return; }