def make_mob(vnum: int, mob_class: Type[CircleMob] = CircleMob) -> Living: """Create an instance of an item for the given vnum""" c_mob = mobs[vnum] name = c_mob.aliases[0] aliases = set(c_mob.aliases[1:]) # type: Set[str] title = c_mob.shortdesc if title.startswith("the ") or title.startswith("The "): title = title[4:] if title.startswith("a ") or title.startswith("A "): title = title[2:] # for now, we take the stats from the 'human' race because the circle data lacks race and stats # @todo map circle mobs on races? mob_class = circle_mob_class.get(vnum, mob_class) mob = mob_class(name, c_mob.gender, race="human", title=title, descr=c_mob.detaileddesc, short_descr=c_mob.longdesc) mob.circle_vnum = vnum # keep the vnum if hasattr(c_mob, "extradesc"): for ed in c_mob.extradesc: mob.add_extradesc(ed["keywords"], ed["text"]) mob.aliases = aliases mob.aggressive = "aggressive" in c_mob.actions mob.money = float(c_mob.gold) mob.stats.alignment = c_mob.alignment mob.stats.xp = c_mob.xp number, sides, hp = map( int, re.match(r"(\d+)d(\d+)\+(\d+)$", c_mob.maxhp_dice).groups()) if number > 0 and sides > 0: hp += roll_dice(number, sides)[0] mob.stats.hp = hp mob.stats.maxhp_dice = c_mob.maxhp_dice mob.stats.level = max(1, c_mob.level) # 1..50 # convert AC -10..10 to more modern 0..20 (naked person(0)...plate armor(10)...battletank(20)) # special elites can go higher (limit 100), weaklings with utterly no defenses can go lower (limit -100) mob.stats.ac = max(-100, min(100, 10 - c_mob.ac)) mob.stats.attack_dice = c_mob.barehanddmg_dice assert isinstance(c_mob.actions, set) mob.actions = c_mob.actions if "special" in c_mob.actions: # this mob has the 'special' flag which means it has special programmed behavior that must periodically be triggered # movement of the mob is one thing that this takes care of (if the mob is not sentinel) mobs_with_special.add(mob) # @todo load position? (standing/sleeping/sitting...) # @todo convert thac0 to appropriate attack stat (armor penetration? to-hit bonus?) # @todo actions, affection,... converted_mobs.add(vnum) return mob
def test_roll_dice(self): total, values = util.roll_dice() self.assertTrue(1 <= total <= 6) self.assertEqual(1, len(values)) self.assertEqual(total, values[0]) total, values = util.roll_dice(20, 10) # 20d10 self.assertEqual(20, len(values)) with self.assertRaises(AssertionError): util.roll_dice(0, 10) with self.assertRaises(AssertionError): util.roll_dice(400, 10)
def make_mob(vnum, mob_class=CircleMob): """Create an instance of an item for the given vnum""" c_mob = mobs[vnum] aliases = list(c_mob.aliases) name = aliases[0] aliases = set(aliases[1:]) title = c_mob.shortdesc if title.startswith("the ") or title.startswith("The "): title = title[4:] if title.startswith("a ") or title.startswith("A "): title = title[2:] # we take the stats from the 'human' race because the circle data lacks race and stats mob = mob_class(name, c_mob.gender, "human", title, description=c_mob.detaileddesc, short_description=c_mob.longdesc) mob.vnum = vnum # keep the vnum if hasattr(c_mob, "extradesc"): for ed in c_mob.extradesc: mob.add_extradesc(ed["keywords"], ed["text"]) mob.aliases = aliases mob.aggressive = "aggressive" in c_mob.actions mob.money = float(c_mob.gold) mob.stats.alignment = c_mob.alignment mob.stats.xp = c_mob.xp number, sides, hp = map( int, re.match(r"(\d+)d(\d+)\+(\d+)$", c_mob.maxhp_dice).groups()) if number > 0 and sides > 0: hp += roll_dice(number, sides)[0] mob.stats.hp = hp mob.stats.maxhp_dice = c_mob.maxhp_dice mob.stats.level = max(1, c_mob.level) # 1..50 # convert AC -10..10 to more modern 0..20 (naked person(0)...plate armor(10)...battletank(20)) # special elites can go higher (limit 100), weaklings with utterly no defenses can go lower (limit -100) mob.stats.ac = max(-100, min(100, 10 - c_mob.ac)) mob.stats.attack_dice = c_mob.barehanddmg_dice if "sentinel" not in c_mob.actions: mud_context.driver.defer(random.randint(2, 30), mob.do_wander) # @todo load position? (standing/sleeping/sitting...) # @todo convert thac0 to appropriate attack stat (armor penetration? to-hit bonus?) # @todo actions, affection,... converted_mobs.add(vnum) return mob
def make_mob(vnum, mob_class=CircleMob): """Create an instance of an item for the given vnum""" c_mob = mobs[vnum] aliases = list(c_mob.aliases) name = aliases[0] aliases = set(aliases[1:]) title = c_mob.shortdesc if title.startswith("the ") or title.startswith("The "): title = title[4:] if title.startswith("a ") or title.startswith("A "): title = title[2:] # we take the stats from the 'human' race because the circle data lacks race and stats mob = mob_class(name, c_mob.gender, "human", title, description=c_mob.detaileddesc, short_description=c_mob.longdesc) mob.vnum = vnum # keep the vnum if hasattr(c_mob, "extradesc"): for ed in c_mob.extradesc: mob.add_extradesc(ed["keywords"], ed["text"]) mob.aliases = aliases mob.aggressive = "aggressive" in c_mob.actions mob.money = float(c_mob.gold) mob.stats.alignment = c_mob.alignment mob.stats.xp = c_mob.xp number, sides, hp = map(int, re.match(r"(\d+)d(\d+)\+(\d+)$", c_mob.maxhp_dice).groups()) if number > 0 and sides > 0: hp += roll_dice(number, sides)[0] mob.stats.hp = hp mob.stats.maxhp_dice = c_mob.maxhp_dice mob.stats.level = max(1, c_mob.level) # 1..50 # convert AC -10..10 to more modern 0..20 (naked person(0)...plate armor(10)...battletank(20)) # special elites can go higher (limit 100), weaklings with utterly no defenses can go lower (limit -100) mob.stats.ac = max(-100, min(100, 10 - c_mob.ac)) mob.stats.attack_dice = c_mob.barehanddmg_dice if "sentinel" not in c_mob.actions: mud_context.driver.defer(random.randint(2, 30), mob.do_wander) #@todo load position? (standing/sleeping/sitting...) #@todo convert thac0 to appropriate attack stat (armor penetration? to-hit bonus?) #@todo actions, affection,... converted_mobs.add(vnum) return mob