""" #************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ #************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * ***************************************************************************/ #*********** * Ported to Python by Davion of MudBytes.net * Using Miniboa https://code.google.com/p/miniboa/ * Now using Python 3 version https://code.google.com/p/miniboa-py3/ ************/ """ import os, sys, random from settings import AREA_DIR, AREA_LIST from merc import * from handler import * from special import spec_table from tables import sex_table, position_table import const def boot_db(): print ("Loading Areas...") init_time() load_areas() fix_exits() area_update() print ("\t...Loaded %d Helpfiles" % len(help_list)) print ("\t...Loaded %d Areas" % len(area_list)) print ("\t...Loaded %d Mobile Indexes" % len(mob_index_hash)) print ("\t...Loaded %d Object Indexes" % len(obj_index_hash)) print ("\t...Loaded %d Room Indexes" % len(room_index_hash)) print ("\t...Loaded %d Resets" % len(reset_list)) print ("\t...Loaded %d Shops" % len(shop_list)) print ("\t...Loaded %d Socials" % len(social_list)) def load_areas(): area_list = os.path.join(AREA_DIR, AREA_LIST) fp = open(area_list, 'r') area = fp.readline().strip() while area != "$": afp = open(os.path.join(AREA_DIR, area), 'r' ) load_area( afp.read() ) area = fp.readline().strip() afp.close() fp.close() def load_area(area): if not area.strip(): return area, w = read_word(area,False) pArea = None while ( area ): if w == "#AREA": pArea = AREA_DATA() area, pArea.file_name = read_string(area) area, pArea.name = read_string(area) area, pArea.credits = read_string(area) area, pArea.min_vnum = read_int(area) area, pArea.max_vnum = read_int(area) area_list.append(pArea) print ("\t...%s" % pArea) elif w == "#HELPS": area = load_helps(area) elif w == "#MOBILES": area = load_mobiles(area) elif w == "#OBJECTS": area = load_objects(area) elif w == "#RESETS": area = load_resets(area, pArea) elif w == "#ROOMS": area = load_rooms(area, pArea) elif w == "#SHOPS": area = load_shops(area) elif w == "#SOCIALS": area = load_socials(area) elif w == "#SPECIALS": area = load_specials(area) elif w == '#$': break else: print ("Bad section name: " + w) area, w = read_word(area,False) def load_helps(area): while True: help = HELP_DATA() area, help.level = read_int(area) area, help.keyword = read_string(area) if help.keyword == '$': del help break area, help.text = read_string(area) if help.keyword == "GREETING": greeting_list.append(help) help_list.append(help) return area def load_mobiles(area): area, w = read_word(area,False) w = w[1:] # strip the pound while w != '0': mob = MOB_INDEX_DATA() mob.vnum = int(w) mob_index_hash[mob.vnum] = mob area, mob.player_name = read_string(area) area, mob.short_descr = read_string(area) area, mob.long_descr = read_string(area) area, mob.description = read_string(area) area, mob.race = read_string(area) mob.race = const.race_table[mob.race] area, mob.act = read_flags(area) mob.act = mob.act | ACT_IS_NPC | mob.race.act area, mob.affected_by = read_flags(area) mob.affected_by = mob.affected_by | mob.race.aff area, mob.alignment = read_int(area) area, mob.group = read_int(area) area, mob.level = read_int(area) area, mob.hitroll = read_int(area) area, mob.hit[0] = read_int(area) area = read_forward(area) area, mob.hit[1] = read_int(area) area = read_forward(area) area, mob.hit[2] = read_int(area) area, mob.mana[0] = read_int(area) area = read_forward(area) area, mob.mana[1] = read_int(area) area = read_forward(area) area, mob.mana[2] = read_int(area) area, mob.damage[0] = read_int(area) area = read_forward(area) area, mob.damage[1] = read_int(area) area = read_forward(area) area, mob.damage[2] = read_int(area) area, mob.dam_type = read_word(area,False) mob.dam_type = name_lookup(const.attack_table, mob.dam_type) area, mob.ac[0] = read_int(area) area, mob.ac[1] = read_int(area) area, mob.ac[2] = read_int(area) area, mob.ac[3] = read_int(area) area, mob.off_flags = read_flags(area) mob.off_flags = mob.off_flags | mob.race.off area, mob.imm_flags = read_flags(area) mob.imm_flags = mob.imm_flags | mob.race.imm area, mob.res_flags = read_flags(area) mob.res_flags = mob.res_flags | mob.race.res area, mob.vuln_flags = read_flags(area) mob.vuln_flags = mob.vuln_flags | mob.race.vuln area, mob.start_pos = read_word(area,False) area, mob.default_pos = read_word(area,False) mob.start_pos = name_lookup(position_table, mob.start_pos, 'short_name') mob.default_pos = name_lookup(position_table, mob.default_pos, 'short_name') area, sex = read_word(area,False) mob.sex = value_lookup(sex_table, sex) area, mob.wealth = read_int(area) area, mob.form = read_flags(area) mob.form = mob.form | mob.race.form area, mob.parts = read_flags(area) mob.parts = mob.parts | mob.race.parts area, mob.size = read_word(area,False) area, mob.material = read_word(area,False) area, w = read_word(area,False) mob.size = size_table.index(mob.size) while w == 'F': area, word = read_word(area,False) area, vector = read_flags(area) area, w = read_word(area,False) w = w[1:] # strip the pound return area def load_objects(area): area, w = read_word(area,False) w = w[1:] # strip the pound while w != '0': obj = OBJ_INDEX_DATA() obj.vnum = int(w) obj_index_hash[obj.vnum] = obj area, obj.name = read_string(area) area, obj.short_descr = read_string(area) area, obj.description = read_string(area) area, obj.material = read_string(area) area, item_type = read_word(area,False) area, obj.extra_flags = read_flags(area) area, obj.wear_flags = read_flags(area) obj.item_type = item_type if obj.item_type == ITEM_WEAPON: area, obj.value[0] = read_word(area,False) area, obj.value[1] = read_int(area) area, obj.value[2] = read_int(area) area, obj.value[3] = read_word(area,False) obj.value[3] = name_lookup(const.attack_table, obj.value[3]) area, obj.value[4] = read_flags(area) elif obj.item_type == ITEM_CONTAINER: area, obj.value[0] = read_int(area) area, obj.value[1] = read_flags(area) area, obj.value[2] = read_int(area) area, obj.value[3] = read_int(area) area, obj.value[4] = read_int(area) elif obj.item_type == ITEM_DRINK_CON or obj.item_type == ITEM_FOUNTAIN: area, obj.value[0] = read_int(area) area, obj.value[1] = read_int(area) area, obj.value[2] = read_word(area,False) area, obj.value[3] = read_int(area) area, obj.value[4] = read_int(area) elif obj.item_type == ITEM_WAND or obj.item_type == ITEM_STAFF: area, obj.value[0] = read_int(area) area, obj.value[1] = read_int(area) area, obj.value[2] = read_int(area) area, obj.value[3] = read_word(area,False) area, obj.value[4] = read_int(area) elif obj.item_type == ITEM_POTION or obj.item_type == ITEM_POTION or obj.item_type == ITEM_PILL: area, obj.value[0] = read_int(area) area, obj.value[1] = read_word(area,False) area, obj.value[2] = read_word(area,False) area, obj.value[3] = read_word(area,False) area, obj.value[4] = read_word(area,False) else: area, obj.value[0] = read_flags(area) area, obj.value[1] = read_flags(area) area, obj.value[2] = read_flags(area) area, obj.value[3] = read_flags(area) area, obj.value[4] = read_flags(area) area, obj.level = read_int(area) area, obj.weight = read_int(area) area, obj.cost = read_int(area) area, obj.condition = read_word(area,False) if obj.condition == 'P': obj.condition = 100 elif obj.condition == 'G': obj.condition = 90 elif obj.condition == 'A': obj.condition = 75 elif obj.condition == 'W': obj.condition = 50 elif obj.condition == 'D': obj.condition = 25 elif obj.condition == 'B': obj.condition = 10 elif obj.condition == 'R': obj.condition = 0 else: obj.condition = 100 area, w = read_word(area,False) while w == 'F' or w == 'A' or w == 'E': if w == 'F': area, word = read_word(area,False) area, number = read_int(area) area, number = read_int(area) area, flags = read_flags(area) elif w == 'A': area, number = read_int(area) area, number = read_int(area) elif w == 'E': ed = EXTRA_DESCR_DATA() area, ed.keyword = read_string(area) area, ed.description = read_string(area) obj.extra_descr.append(ed) area, w = read_word(area,False) w = w[1:] # strip the pound return area def load_resets(area, pArea): while True: area, letter = read_letter(area) if letter == 'S': break if letter == '*': area, t = read_to_eol(area) continue reset = RESET_DATA() reset.command = letter area, number = read_int(area) #if_flag area, reset.arg1 = read_int(area) area, reset.arg2 = read_int(area) area, reset.arg3 = (area, 0) if letter == 'G' or letter == 'R' else read_int(area) area, reset.arg4 = read_int(area) if letter == 'P' or letter == 'M' else (area, 0) area, t = read_to_eol(area) pArea.reset_list.append(reset) reset_list.append(reset) return area def load_rooms(area, pArea): area, w = read_word(area,False) w = w[1:] # strip the pound while w != '0': room = ROOM_INDEX_DATA() room.vnum = int(w) if room.vnum in room_index_hash: print ("Dupicate room Vnum: %d" % room.vnum) sys.exit(1) room_index_hash[room.vnum] = room room.area = pArea area, room.name = read_string(area) area, room.description = read_string(area) area, number = read_int(area) #area number area, room.room_flags = read_flags(area) area, room.sector_type = read_int(area) while True: area, letter = read_letter(area) if letter == 'S': break elif letter == 'H': #Healing Room area, room.heal_rate = read_int(area) elif letter == 'M': #Mana Room area, room.mana_rate = read_int(area) elif letter == 'C': #Clan area, room.clan = read_string(area) elif letter == 'D': #exit exit = EXIT_DATA() area, door = read_int(area) area, exit.description = read_string(area) area, exit.keyword = read_string(area) area, locks = read_int(area) area, exit.key = read_int(area) area, exit.to_room = read_int(area) room.exit[door] = exit elif letter == 'E': ed = EXTRA_DESCR_DATA() area, ed.keyword = read_string(area) area, ed.description = read_string(area) room.extra_descr.append(ed) elif letter == 'O': area, room.owner = read_string(area) else: print ("RoomIndexData(%d) has flag other than SHMCDEO: %s" % ( room.vnum, letter )) sys.exit(1) area, w = read_word(area,False) w = w[1:] # strip the pound return area def load_shops(area): while True: area, keeper = read_int(area) if keeper == 0: break shop = SHOP_DATA() shop.keeper = keeper for r in range(MAX_TRADE): area, shop.buy_type[r] = read_int(area) area, shop.profit_buy = read_int(area) area, shop.profit_sell = read_int(area) area, shop.open_hour = read_int(area) area, shop.close_hour = read_int(area) area, t = read_to_eol(area) mob_index_hash[keeper].pShop = shop shop_list.append(shop) return area def load_socials(area): while True: area, word = read_word(area,False) if word == '#0': return social = SOCIAL_DATA() social.name = word area, throwaway = read_to_eol(area) area, line = read_to_eol(area) if line == '$': social.char_no_arg = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.char_no_arg = line area, line = read_to_eol(area) if line == '$': social.others_no_arg = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.others_no_arg = line area, line = read_to_eol(area) if line == '$': social.char_found = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.char_found = line area, line = read_to_eol(area) if line == '$': social.others_found = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.others_found = line area, line = read_to_eol(area) if line == '$': social.vict_found = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.vict_found = line area, line = read_to_eol(area) if line == '$': social.char_not_found = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.char_not_found = line area, line = read_to_eol(area) if line == '$': social.char_auto = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.char_auto = line area, line = read_to_eol(area) if line == '$': social.others_auto = None elif line == '#': if social not in social_list: social_list.append(social) continue else: social.others_auto = line if social not in social_list: social_list.append(social) return area def load_specials(area): while True: area, letter = read_letter(area) if letter == '*': area, t = read_to_eol(area) continue elif letter == 'S': return area elif letter == 'M': area, vnum = read_int(area) area, mob_index_hash[vnum].spec_fun = read_word(area,False) else: print ("Load_specials: letter noth *SM: " + letter) return area def fix_exits(): for k, r in room_index_hash.items(): for e in r.exit[:]: if e and type(e.to_room) == int: if e.to_room not in room_index_hash: print ("Fix_exits: Failed to find to_room for %d: %d" % (r.vnum, e.to_room)) e.to_room = None r.exit.remove(e) else: e.to_room = room_index_hash[e.to_room] # * Repopulate areas periodically. def area_update( ): for pArea in area_list: pArea.age += 1 if pArea.age < 3: continue # #* Check age and reset. #* Note: Mud School resets every 3 minutes (not 15). #*/ if(not pArea.empty and (pArea.nplayer == 0 or pArea.age >= 15)) or pArea.age >= 31: reset_area( pArea ) wiznet("%s has just been reset." % pArea.name,None,None,WIZ_RESETS,0,0) pArea.age = random.randint( 0, 3 ) pRoomIndex = room_index_hash[ROOM_VNUM_SCHOOL] if pRoomIndex and pArea == pRoomIndex.area: pArea.age = 15 - 2 elif pArea.nplayer == 0: pArea.empty = True # # * Reset one area. def reset_area( pArea ): mob = None last = True level = 0 for pReset in pArea.reset_list: if pReset.command == 'M': if pReset.arg1 not in mob_index_hash: print ("Reset_area: 'M': bad vnum %d." % pReset.arg1) continue pMobIndex = mob_index_hash[pReset.arg1] if pReset.arg3 not in room_index_hash: print ("Reset_area: 'R': bad vnum %d." % pReset.arg3) continue pRoomIndex = room_index_hash[pReset.arg3] if pMobIndex.count >= pReset.arg2: last = False break count = 0 for mob in pRoomIndex.people: if mob.pIndexData == pMobIndex: count += 1 if count >= pReset.arg4: last = False break if count >= pReset.arg4: continue mob = create_mobile( pMobIndex ) # #* Check for pet shop. # */ if pRoomIndex.vnum-1 in room_index_hash: pRoomIndexPrev = room_index_hash[pRoomIndex.vnum-1] if IS_SET(pRoomIndexPrev.room_flags, ROOM_PET_SHOP): mob.act = SET_BIT(mob.act, ACT_PET) # set area */ mob.zone = pRoomIndex.area mob.to_room(pRoomIndex) level = max(0, min(mob.level - 2, LEVEL_HERO - 1 ) ) last = True elif pReset.command == 'O': if pReset.arg1 not in obj_index_hash: print ("Reset_area: 'O': bad vnum %d." % pReset.arg1) continue pObjIndex = obj_index_hash[pReset.arg1] if pReset.arg3 not in room_index_hash: print ("Reset_area: 'R': bad vnum %d." % pReset.arg3) continue pRoomIndex = room_index_hash[pReset.arg3] if pArea.nplayer > 0 or count_obj_list( pObjIndex, pRoomIndex.contents ) > 0: last = False continue obj = create_object( pObjIndex, min(number_fuzzy(level), LEVEL_HERO - 1) ) obj.cost = 0 obj.to_room(pRoomIndex) last = True continue elif pReset.command == 'P': if pReset.arg1 not in obj_index_hash: print ("Reset_area: 'P': bad vnum %d." % pReset.arg1) continue pObjIndex = obj_index_hash[pReset.arg1] if pReset.arg3 not in obj_index_hash: print ("Reset_area: 'P': bad vnum %d." % pReset.arg3) continue pObjToIndex = obj_index_hash[pReset.arg3] if pReset.arg2 > 50: # old format */ limit = 6 elif pReset.arg2 == -1: # no limit */ limit = 999 else: limit = pReset.arg2 obj_to = get_obj_type(pObjToIndex) if pArea.nplayer > 0 \ or not obj_to \ or (obj_to.in_room == None and not last) \ or ( pObjIndex.count >= limit and random.randint(0,4) != 0) \ or count_obj_list(pObjIndex, obj_to.contains) > pReset.arg4: last = False break count = count_obj_list(pObjIndex, obj_to.contains) while count < pReset.arg4: obj = create_object( pObjIndex, number_fuzzy(obj_to.level) ) obj.to_obj(obj_to) count += 1 if pObjIndex.count >= limit: break # fix object lock state! */ obj_to.value[1] = obj_to.pIndexData.value[1] last = True elif pReset.command == 'G' or pReset.command == 'E': if pReset.arg1 not in obj_index_hash: print ("Reset_area: 'E' or 'G': bad vnum %d." % pReset.arg1) continue pObjIndex = obj_index_hash[pReset.arg1] if not last: continue if not mob: print ("Reset_area: 'E' or 'G': None mob for vnum %d." % pReset.arg1) last = False continue olevel = 0 if mob.pIndexData.pShop: if not pObjIndex.new_format: if pObjIndex.item_type == ITEM_PILL \ or pObjIndex.item_type == ITEM_POTION \ or pObjIndex.item_type == ITEM_SCROLL: olevel = 53 for i in pObjIndex.value: if i > 0: for j in skill_table[pObjIndex.value[i]].skill_level: olevel = min(olevel, j) olevel = max(0,(olevel * 3 // 4) - 2) elif pObjIndex.item_type == ITEM_WAND: olevel = random.randint( 10, 20 ) elif pObjIndex.item_type == ITEM_STAFF: olevel = random.randint( 15, 25 ) elif pObjIndex.item_type == ITEM_ARMOR: olevel = random.randint( 5, 15 ) elif pObjIndex.item_type == ITEM_WEAPON: olevel = random.randint( 5, 15 ) elif pObjIndex.item_type == ITEM_TREASURE: olevel = random.randint( 10, 20 ) obj = create_object( pObjIndex, olevel ) obj.extra_flags = SET_BIT(obj.extra_flags, ITEM_INVENTORY) else: if pReset.arg2 > 50: # old format */ limit = 6 elif pReset.arg2 == -1: # no limit */ limit = 999 else: limit = pReset.arg2 if pObjIndex.count < limit or random.randint(0,4) == 0: obj = create_object(pObjIndex,min(number_fuzzy(level), LEVEL_HERO - 1)) # error message if it is too high */ if obj.level > mob.level + 3 \ or (obj.item_type == ITEM_WEAPON \ and pReset.command == 'E' \ and obj.level < mob.level -5 and obj.level < 45): print ("Err: obj %s (%d) -- %d, mob %s (%d) -- %d\n" % ( obj.short_descr,obj.pIndexData.vnum,obj.level, mob.short_descr,mob.pIndexData.vnum,mob.level)) else: continue obj.to_char(mob) if pReset.command == 'E': mob.equip(obj, pReset.arg3) last = True continue elif pReset.command == 'D': if pReset.arg1 not in room_index_hash: print ("Reset_area: 'D': bad vnum %d." % pReset.arg1) continue pRoomIndex = room_index_hash[pReset.arg1] pexit = pRoomIndex.exit[pReset.arg2] if not pexit: continue if pReset.arg3 == 0: pexit.exit_info = REMOVE_BIT(pexit.exit_info, EX_CLOSED) pexit.exit_info = REMOVE_BIT(pexit.exit_info, EX_LOCKED) continue elif pReset.arg3 == 1: pexit.exit_info = SET_BIT(pexit.exit_info, EX_CLOSED ) pexit.exit_info = REMOVE_BIT(pexit.exit_info, EX_LOCKED ) continue elif pReset.arg3 == 2: pexit.exit_info = SET_BIT(pexit.exit_info, EX_CLOSED ) pexit.exit_info = SET_BIT(pexit.exit_info, EX_LOCKED ) continue last = True continue elif pReset.command == 'R': if pReset.arg1 not in room_index_hash: print ("Reset_area: 'R': bad vnum %d." % pReset.arg1) continue pRoomIndex = room_index_hash[pReset.arg1] for d0 in range(pReset.arg2 - 1): d1 = random.randint( d0, pReset.arg2-1 ) pexit = pRoomIndex.exit[d0] pRoomIndex.exit[d0] = pRoomIndex.exit[d1] pRoomIndex.exit[d1] = pexit break else: print ("Reset_area: bad command %c." % pReset.command) # # * Create an instance of a mobile. def create_mobile( pMobIndex ): if pMobIndex == None: print ("Create_mobile: None pMobIndex.") sys.exit( 1 ) mob = CHAR_DATA() mob.pIndexData = pMobIndex mob.name = pMobIndex.player_name mob.id = get_mob_id() mob.short_descr = pMobIndex.short_descr mob.long_descr = pMobIndex.long_descr mob.description = pMobIndex.description if pMobIndex.spec_fun: mob.spec_fun = spec_table[pMobIndex.spec_fun] mob.prompt = None if pMobIndex.wealth == 0: mob.silver = 0 mob.gold = 0 else: wealth = random.randint(pMobIndex.wealth // 2, 3 * pMobIndex.wealth // 2) mob.gold = random.randint(wealth // 200, wealth // 100) mob.silver = wealth - (mob.gold * 100) if pMobIndex.new_format: # load in new style */ # read from prototype */ mob.group = pMobIndex.group mob.act = pMobIndex.act mob.comm = COMM_NOCHANNELS|COMM_NOSHOUT|COMM_NOTELL mob.affected_by = pMobIndex.affected_by mob.alignment = pMobIndex.alignment mob.level = pMobIndex.level mob.hitroll = pMobIndex.hitroll mob.damroll = pMobIndex.damage[DICE_BONUS] mob.max_hit = dice(pMobIndex.hit[DICE_NUMBER], pMobIndex.hit[DICE_TYPE]) + pMobIndex.hit[DICE_BONUS] mob.hit = mob.max_hit mob.max_mana = dice(pMobIndex.mana[DICE_NUMBER], pMobIndex.mana[DICE_TYPE]) + pMobIndex.mana[DICE_BONUS] mob.mana = mob.max_mana mob.damage[DICE_NUMBER] = pMobIndex.damage[DICE_NUMBER] mob.damage[DICE_TYPE] = pMobIndex.damage[DICE_TYPE] mob.dam_type = pMobIndex.dam_type if mob.dam_type == 0: num = random.randint(1,3) if num == 1: mob.dam_type = 3 # slash */ elif num == 2: mob.dam_type = 7 # pound */ elif num == 3: mob.dam_type = 11 # pierce */ for i in range(4): mob.armor[i] = pMobIndex.ac[i] mob.off_flags = pMobIndex.off_flags mob.imm_flags = pMobIndex.imm_flags mob.res_flags = pMobIndex.res_flags mob.vuln_flags = pMobIndex.vuln_flags mob.start_pos = pMobIndex.start_pos mob.default_pos = pMobIndex.default_pos mob.sex = pMobIndex.sex if type(pMobIndex.sex) != int or mob.sex == 3: # random sex */ mob.sex = random.randint(1,2) mob.race = pMobIndex.race mob.form = pMobIndex.form mob.parts = pMobIndex.parts mob.size = int(pMobIndex.size) mob.material = pMobIndex.material # computed on the spot */ for i in range(MAX_STATS): mob.perm_stat[i] = min(25, 11 + mob.level // 4) if IS_SET(mob.act,ACT_WARRIOR): mob.perm_stat[STAT_STR] += 3 mob.perm_stat[STAT_INT] -= 1 mob.perm_stat[STAT_CON] += 2 if IS_SET(mob.act,ACT_THIEF): mob.perm_stat[STAT_DEX] += 3 mob.perm_stat[STAT_INT] += 1 mob.perm_stat[STAT_WIS] -= 1 if IS_SET(mob.act,ACT_CLERIC): mob.perm_stat[STAT_WIS] += 3 mob.perm_stat[STAT_DEX] -= 1 mob.perm_stat[STAT_STR] += 1 if IS_SET(mob.act,ACT_MAGE): mob.perm_stat[STAT_INT] += 3 mob.perm_stat[STAT_STR] -= 1 mob.perm_stat[STAT_DEX] += 1 if IS_SET(mob.off_flags,OFF_FAST): mob.perm_stat[STAT_DEX] += 2 mob.perm_stat[STAT_STR] += mob.size - SIZE_MEDIUM mob.perm_stat[STAT_CON] += (mob.size - SIZE_MEDIUM) // 2 af = AFFECT_DATA() # let's get some spell action */ if IS_AFFECTED(mob,AFF_SANCTUARY): af.where = TO_AFFECTS af.type = "sanctuary" af.level = mob.level af.duration = -1 af.location = APPLY_NONE af.modifier = 0 af.bitvector = AFF_SANCTUARY mob.affect_add(af) if IS_AFFECTED(mob,AFF_HASTE): af.where = TO_AFFECTS af.type = "haste" af.level = mob.level af.duration = -1 af.location = APPLY_DEX af.modifier = 1 + (mob.level >= 18) + (mob.level >= 25) + (mob.level >= 32) af.bitvector = AFF_HASTE mob.affect_add(af) if IS_AFFECTED(mob,AFF_PROTECT_EVIL): af.where = TO_AFFECTS af.type = "protection evil" af.level = mob.level af.duration = -1 af.location = APPLY_SAVES af.modifier = -1 af.bitvector = AFF_PROTECT_EVIL mob.affect_add(af) if IS_AFFECTED(mob,AFF_PROTECT_GOOD): af.where = TO_AFFECTS af.type = "protection good" af.level = mob.level af.duration = -1 af.location = APPLY_SAVES af.modifier = -1 af.bitvector = AFF_PROTECT_GOOD mob.affect_add(af) else: # read in old format and convert */ mob.act = pMobIndex.act mob.affected_by = pMobIndex.affected_by mob.alignment = pMobIndex.alignment mob.level = pMobIndex.level mob.hitroll = pMobIndex.hitroll mob.damroll = 0 mob.max_hit = mob.level * 8 + random.randint( mob.level * mob.level // 4, mob.level * mob.level) mob.max_hit *= .9 mob.hit = mob.max_hit mob.max_mana = 100 + dice(mob.level,10) mob.mana = mob.max_mana num = random.randint(1,3) if num == 1: mob.dam_type = 3 # slash */ elif num == 2: mob.dam_type = 7 # pound */ elif num == 3: mob.dam_type = 11 # pierce */ for i in range(3): mob.armor[i] = interpolate(mob.level,100,-100) mob.armor[3] = interpolate(mob.level,100,0) mob.race = pMobIndex.race mob.off_flags = pMobIndex.off_flags mob.imm_flags = pMobIndex.imm_flags mob.res_flags = pMobIndex.res_flags mob.vuln_flags = pMobIndex.vuln_flags mob.start_pos = pMobIndex.start_pos mob.default_pos = pMobIndex.default_pos mob.sex = pMobIndex.sex mob.form = pMobIndex.form mob.parts = pMobIndex.parts mob.size = SIZE_MEDIUM mob.material = "" for i in MAX_STATS: mob.perm_stat[i] = 11 + mob.level // 4 mob.position = mob.start_pos # link the mob to the world list */ char_list.append(mob) return mob # duplicate a mobile exactly -- except inventory */ def clone_mobile(parent, clone): if not parent or not clone or not IS_NPC(parent): return # start fixing values */ clone.name = parent.name clone.version = parent.version clone.short_descr = parent.short_descr clone.long_descr = parent.long_descr clone.description = parent.description clone.group = parent.group clone.sex = parent.sex clone.guild = parent.guild clone.race = parent.race clone.level = parent.level clone.trust = 0 clone.timer = parent.timer clone.wait = parent.wait clone.hit = parent.hit clone.max_hit = parent.max_hit clone.mana = parent.mana clone.max_mana = parent.max_mana clone.move = parent.move clone.max_move = parent.max_move clone.gold = parent.gold clone.silver = parent.silver clone.exp = parent.exp clone.act = parent.act clone.comm = parent.comm clone.imm_flags = parent.imm_flags clone.res_flags = parent.res_flags clone.vuln_flags = parent.vuln_flags clone.invis_level = parent.invis_level clone.affected_by = parent.affected_by clone.position = parent.position clone.practice = parent.practice clone.train = parent.train clone.saving_throw = parent.saving_throw clone.alignment = parent.alignment clone.hitroll = parent.hitroll clone.damroll = parent.damroll clone.wimpy = parent.wimpy clone.form = parent.form clone.parts = parent.parts clone.size = parent.size clone.material = parent.material clone.off_flags = parent.off_flags clone.dam_type = parent.dam_type clone.start_pos = parent.start_pos clone.default_pos = parent.default_pos clone.spec_fun = parent.spec_fun for i in range(4): clone.armor[i] = parent.armor[i] for i in range(MAX_STATS): clone.perm_stat[i] = parent.perm_stat[i] clone.mod_stat[i] = parent.mod_stat[i] for i in range(3): clone.damage[i] = parent.damage[i] # now add the affects */ for paf in parent.affected: clone.affect_add(paf) # * Create an instance of an object. def create_object( pObjIndex, level ): if not pObjIndex: print ("Create_object: None pObjIndex.") sys.exit( 1 ) obj = OBJ_DATA() obj.pIndexData = pObjIndex obj.in_room = None obj.enchanted = False if pObjIndex.new_format == True: obj.level = pObjIndex.level else: obj.level = max(0,level) obj.wear_loc = -1 obj.name = pObjIndex.name obj.short_descr = pObjIndex.short_descr obj.description = pObjIndex.description obj.material = pObjIndex.material obj.item_type = pObjIndex.item_type obj.extra_flags = pObjIndex.extra_flags obj.wear_flags = pObjIndex.wear_flags obj.value = pObjIndex.value[:] obj.weight = pObjIndex.weight if level == -1 or pObjIndex.new_format: obj.cost = pObjIndex.cost else: obj.cost = number_fuzzy( 10 ) * number_fuzzy( level ) * number_fuzzy( level ) # Mess with object properties. if obj.item_type == ITEM_LIGHT: if obj.value[2] == 999: obj.value[2] = -1 elif obj.item_type == ITEM_FURNITURE \ or obj.item_type == ITEM_TRASH \ or obj.item_type == ITEM_CONTAINER \ or obj.item_type == ITEM_DRINK_CON \ or obj.item_type == ITEM_KEY \ or obj.item_type == ITEM_FOOD \ or obj.item_type == ITEM_BOAT \ or obj.item_type == ITEM_CORPSE_NPC \ or obj.item_type == ITEM_CORPSE_PC \ or obj.item_type == ITEM_FOUNTAIN \ or obj.item_type == ITEM_MAP \ or obj.item_type == ITEM_CLOTHING \ or obj.item_type == ITEM_PORTAL: if not pObjIndex.new_format: obj.cost //= 5 elif obj.item_type == ITEM_TREASURE \ or obj.item_type == ITEM_WARP_STONE \ or obj.item_type == ITEM_ROOM_KEY \ or obj.item_type == ITEM_GEM \ or obj.item_type == ITEM_JEWELRY: pass elif obj.item_type == ITEM_JUKEBOX: obj.value = [-1 for i in range(5)] elif obj.item_type == ITEM_SCROLL: if level != -1 and not pObjIndex.new_format: obj.value[0] = number_fuzzy( obj.value[0]) elif obj.item_type == ITEM_WAND \ or obj.item_type == ITEM_STAFF: if level != -1 and not pObjIndex.new_format: obj.value[0] = number_fuzzy( obj.value[0]) obj.value[1] = number_fuzzy( obj.value[1]) obj.value[2] = obj.value[1] if not pObjIndex.new_format: obj.cost *= 2 elif obj.item_type == ITEM_WEAPON: if level != -1 and not pObjIndex.new_format: obj.value[1] = number_fuzzy( number_fuzzy( 1 * level // 4 + 2 ) ) obj.value[2] = number_fuzzy( number_fuzzy( 3 * level // 4 + 6 ) ) elif obj.item_type == ITEM_ARMOR: if level != -1 and not pObjIndex.new_format: obj.value[0] = number_fuzzy( level // 5 + 3 ) obj.value[1] = number_fuzzy( level // 5 + 3 ) obj.value[2] = number_fuzzy( level // 5 + 3 ) elif obj.item_type == ITEM_POTION \ or obj.item_type == ITEM_PILL: if level != -1 and not pObjIndex.new_format: obj.value[0] = number_fuzzy( number_fuzzy( obj.value[0] ) ) elif obj.item_type == ITEM_MONEY: if not pObjIndex.new_format: obj.value[0] = obj.cost else: print ("Bad item_type pObjIndex vnum: %s(%s)" % (pObjIndex.vnum, obj.item_type )) for paf in pObjIndex.affected: if paf.location == APPLY_SPELL_AFFECT: obj.affect_add(paf) obj.extra_descr = pObjIndex.extra_descr object_list.append(obj) return obj # duplicate an object exactly -- except contents */ def clone_object(parent, clone): if not parent or not clone: return # start fixing the object */ clone.name = parent.name clone.short_descr = parent.short_descr clone.description = parent.description clone.item_type = parent.item_type clone.extra_flags = parent.extra_flags clone.wear_flags = parent.wear_flags clone.weight = parent.weight clone.cost = parent.cost clone.level = parent.level clone.condition = parent.condition clone.material = parent.material clone.timer = parent.timer for i in parent.value: clone.value[i] = i # affects */ clone.enchanted = parent.enchanted for paf in parent.affected: clone.affect_add(paf) # extended desc */ for ed in parent.extra_descr: ed_new = EXTRA_DESCR_DATA() ed_new.keyword = ed.keyword ed_new.description = ed.description clone.extra_descr.append(ed) # # * Clear a new character. # */ def clear_char( ch ): ch.name = "" ch.short_descr = "" ch.long_descr = "" ch.description = "" ch.prompt = "" ch.logon = time.time() ch.lines = 22 for i in range(4): ch.armor[i] = 100 ch.position = POS_STANDING ch.hit = 20 ch.max_hit = 20 ch.mana = 100 ch.max_mana = 100 ch.move = 100 ch.max_move = 100 ch.on = None for i in MAX_STATS: ch.perm_stat[i] = 13 ch.mod_stat[i] = 0 return # * Create a 'money' obj. def create_money(gold, silver): if gold < 0 or silver < 0 or (gold == 0 and silver == 0): print ("BUG: Create_money: zero or negative money. %d " % min(gold,silver)) gold = max(1,gold) silver = max(1,silver) if gold == 0 and silver == 1: obj = create_object(obj_index_hash[OBJ_VNUM_SILVER_ONE], 0) elif gold == 1 and silver == 0: obj = create_object(obj_index_hash[OBJ_VNUM_GOLD_ONE], 0) elif silver == 0: obj = create_object(obj_index_hash[OBJ_VNUM_GOLD_SOME], 0) obj.short_descr += " %d" % gold obj.value[1] = gold obj.cost = gold obj.weight = gold // 5 elif gold == 0: obj = create_object(obj_index_hash[OBJ_VNUM_SILVER_SOME], 0) obj.short_descr += " %d" % silver obj.value[0] = silver obj.cost = silver obj.weight = silver // 20 else: obj = create_object(obj_index_hash[OBJ_VNUM_COINS], 0) obj.short_descr += " %d %d" % (gold, silver) obj.value[0] = silver obj.value[1] = gold obj.cost = 100 * gold + silver obj.weight = gold // 5 + silver // 20 return obj # * Get an extra description from a list. def get_extra_descr(name, edlist): if not edlist: return None for ed in edlist: if name.lower() in ed.keyword: return ed.description return None def init_time(): lhour = (time.time() - 650336715) // (PULSE_TICK // PULSE_PER_SECOND) lhour = int(lhour) time_info.hour = lhour % 24 lday = lhour // 24 time_info.day = int(lday % 35) lmonth = lday // 35 time_info.month = lmonth % 17 time_info.year = lmonth // 17 if time_info.hour < 5: weather_info.sunlight = SUN_DARK elif time_info.hour < 6: weather_info.sunlight = SUN_RISE elif time_info.hour < 19: weather_info.sunlight = SUN_LIGHT elif time_info.hour < 20: weather_info.sunlight = SUN_SET else: weather_info.sunlight = SUN_DARK weather_info.change = 0 weather_info.mmhg = 960 if time_info.month >= 7 and time_info.month <= 12: weather_info.mmhg += random.randint(1, 50) else: weather_info.mmhg += random.randint(1, 80) if weather_info.mmhg <= 980: weather_info.sky = SKY_LIGHTNING elif weather_info.mmhg <= 1000: weather_info.sky = SKY_RAINING elif weather_info.mmhg <= 1020: weather_info.sky = SKY_CLOUDY else: weather_info.sky = SKY_CLOUDLESS