Ejemplo n.º 1
0
def random_weather(season='fall'):
    """
    Given a season, picks a weighted random weather type from the list
    of valid weathers.
    :param season: 'summer', 'autumn', 'winter', or 'spring'
    :return: A WeatherType object with emits valid in the given season.
    """
    emits = emits_for_season(season)

    # Build a list of all weathers and the combined weight
    # of their valid emits
    weathers = {}
    total_weight = 0
    for emit in emits:
        if emit.weather.automated:
            weatherweight = weathers[
                emit.weather.id] if emit.weather.id in weathers else 0
            weatherweight += emit.weight
            weathers[emit.weather.id] = weatherweight * emit.weather.multiplier
            total_weight += emit.weight

    # Create our picker list
    picker = WeightedPicker()
    for k, v in weathers.iteritems():
        picker.add_option(k, v)

    result = picker.pick()

    weather = WeatherType.objects.get(pk=result)
    return weather
Ejemplo n.º 2
0
    def at_repeat(self):
        try:
            haven = Shardhaven.objects.get(pk=self.obj.db.haven_id)
        except (Shardhaven.DoesNotExist, Shardhaven.MultipleObjectsReturned):
            self.stop()
            return

        if self.obj.db.last_monster:
            try:
                monster = Monster.objects.get(id=self.obj.db.last_monster)
            except (Monster.DoesNotExist, Monster.MultipleObjectsReturned):
                self.stop()
                return
        else:
            monsters = Monster.objects.filter(
                habitats__in=[haven.haven_type],
                difficulty__lte=haven.difficulty_rating)

            monster_type = self.obj.ndb.last_monster_type

            if monster_type:
                if monster_type == "mook":
                    monsters = monsters.filter(npc_type=Monster.MOOKS)
                elif monster_type == "boss":
                    monsters = monsters.filter(npc_type=Monster.BOSS)

            if monsters.count() == 0:
                self.stop()
                return

            picker = WeightedPicker()
            for monster in monsters.all():
                picker.add_option(monster, monster.weight_spawn)

            monster = picker.pick()

        mob_instance = monster.create_instance(self.obj)
        self.obj.msg_contents("{} attacks {}!".format(
            mob_instance.name, self.obj.ndb.monster_attack))
        mob_instance.attack(self.obj.ndb.monster_attack, kill=True)
        mob_instance.combat.set_switch_chance(40)

        if haven.auto_combat:
            cscript = self.obj.ndb.combat_manager
            for testobj in self.obj.contents:
                if (testobj.has_account or
                    (hasattr(testobj, "is_character") and testobj.is_character)
                    ) and not testobj.check_permstring("builders"):
                    if not cscript.check_character_is_combatant(testobj):
                        testobj.msg(cscript.add_combatant(testobj, testobj))
                    if not testobj.is_typeclass(
                            "world.exploration.npcs.BossMonsterNpc"
                    ) and not testobj.is_typeclass(
                            "world.exploration.npcs.MookMonsterNpc"):
                        if mob_instance.combat.state:
                            mob_instance.combat.state.add_foe(testobj)

        self.stop()
Ejemplo n.º 3
0
def pick_emit(weathertype, season=None, time=None, intensity=None):
    """
    Given weather conditions, pick a random emit.  If a GM-set weather
    override is present, will always return that value.
    :param weathertype: A WeatherType object, integer ID, or None.  If None,
                        defaults to the first weather type.
    :param season: 'summer', 'autumn', 'winter', 'spring', or None.  If None,
                    defaults to the current IC season.
    :param time: 'morning', 'afternoon', 'evening', 'night', or None.  If None,
                 defaults to the current IC time of day.
    :param intensity: The intensity of the weather, from 1 to 10.
    :return:
    """
    # Do we have a GM-set override?
    custom_weather = ServerConfig.objects.conf('weather_custom', default=None)
    if custom_weather:
        return custom_weather

    if weathertype is None:
        weathertype = ServerConfig.objects.conf('weather_type_current',
                                                default=1)

    if isinstance(weathertype, int):
        weathertype = WeatherType.objects.get(pk=weathertype)

    if not isinstance(weathertype, WeatherType):
        raise ValueError

    if intensity is None:
        intensity = ServerConfig.objects.conf('weather_intensity_current',
                                              default=5)

    emits = weather_emits(weathertype,
                          season=season,
                          time=time,
                          intensity=intensity)

    if emits.count() == 0:
        logger.log_err(
            "Weather: Unable to find any matching emits for {} intensity {} on a {} {}."
            .format(weathertype.name, intensity, season, time))
        return None

    if emits.count() == 1:
        return emits[0].text

    picker = WeightedPicker()

    for emit in emits:
        picker.add_option(emit, emit.weight)

    result = picker.pick()

    return result.text
Ejemplo n.º 4
0
    def set_alignment_and_affinity(cls, haven, obj):
        from world.magic.models import Alignment, Affinity

        align_picker = WeightedPicker()
        for alignment in haven.alignment_chances.all():
            align_picker.add(alignment.alignment, alignment.weight)

        affinity_picker = WeightedPicker()
        for affinity in haven.affinity_chances.all():
            affinity_picker.add(affinity.affinity, affinity.weight)

        alignment = align_picker.pick()
        affinity = affinity_picker.pick()

        if not alignment:
            alignment = Alignment.PRIMAL

        if not affinity:
            affinity = Affinity.objects.order_by("?").first()

        obj.db.alignment = alignment.id
        obj.db.affinity = affinity.id
Ejemplo n.º 5
0
    def create_trinket(cls, haven):
        name = GeneratedLootFragment.generate_trinket_name()
        trinket = create.create_object(
            typeclass="world.exploration.loot.Trinket", key=name)
        trinket.db.desc = "\nAn ancient trinket, one that feels slightly warm to the touch.\n"

        quality_picker = WeightedPicker()
        quality_picker.add_option(4, 25)
        quality_picker.add_option(5, 45)
        quality_picker.add_option(6, 30)
        quality_picker.add_option(7, 10)
        quality_picker.add_option(8, 3)
        quality_picker.add_option(9, 1)

        trinket.db.quality_level = quality_picker.pick()
        trinket.db.found_shardhaven = haven.name

        cls.set_alignment_and_affinity(haven, trinket)

        return trinket
Ejemplo n.º 6
0
    def at_object_receive(self, obj, source_location):
        if not obj.is_typeclass('typeclasses.characters.Character'):
            return

        haven = self.shardhaven
        if not haven:
            return

        entrance_square = haven.entrance
        if entrance_square is not None and entrance_square.room == self:
            return

        if not obj.has_player or not (hasattr(obj, 'is_character')
                                      and obj.is_character):
            return

        if obj.is_typeclass("world.exploration.npcs.BossMonsterNpc")\
                or obj.is_typeclass("world.explorations.npcs.MookMonsterNpc"):
            return

        haven_square = self.shardhaven_square
        recent = False
        if haven_square is not None:
            recent = haven_square.visited_recently
            haven_square.visit(obj)

        if obj.check_permstring("builders"):
            return

        characters = []
        for testobj in self.contents:
            if testobj != obj and (testobj.has_player or (hasattr(testobj, 'is_character') and testobj.is_character)) \
                    and not testobj.check_permstring("builders"):
                characters.append(testobj)

        player_characters = []
        monsters = []
        for testobj in characters:
            if not testobj.is_typeclass("world.exploration.npcs.BossMonsterNpc") \
                    and not testobj.is_typeclass("world.exploration.npcs.MookMonsterNpc"):
                player_characters.append(testobj)
            else:
                monsters.append(testobj)

        if obj not in player_characters:
            player_characters.append(obj)

        if haven_square.monster and not haven_square.monster_defeated and len(
                monsters) == 0:
            self.db.last_monster = haven_square.monster.id
            self.ndb.monster_attack = obj.name
            self.scripts.add(SpawnMobScript)
        else:
            picker = WeightedPicker()
            # Let's not roll high for EVERY single player
            # Otherwise we run the risk of a monster showing up every single room.
            if recent:
                weight_none = haven.weight_no_monster_backtrack
            else:
                weight_none = haven.weight_no_monster

            if len(monsters) > 0:
                weight_none *= 4
                if haven.auto_combat:
                    cscript = self.ndb.combat_manager
                    if cscript and not cscript.check_character_is_combatant(
                            obj):
                        obj.msg("There is a fight in the room!")
                        obj.msg(cscript.add_combatant(obj, obj))
                        for mon in monsters:
                            if mon.combat.state:
                                mon.combat.state.add_foe(obj)

            if len(player_characters) > 1:
                # Chance of spawn in goes down after the first player.
                weight_none = weight_none * 2

            if len(monsters) > 1:
                # Chance of spawn in goes down after the first monster.
                weight_none = weight_none * 2

            if obj.ndb.shardhaven_sneak_value:
                weight_none += (obj.ndb.shardhaven_sneak_value * 10)
                if obj.ndb.shardhaven_sneak_value > 0:
                    self.msg_contents(
                        "%s sneaks quietly into the room, hoping not to disturb any monsters."
                        % obj.name)
                elif obj.ndb.shardhaven_sneak_value < 0:
                    self.msg_contents(
                        "%s attempts to sneak into the room, but ends up making more "
                        "noise than if they'd just walked!" % obj.name)
                obj.ndb.shardhaven_sneak_value = None

            if weight_none < 0:
                weight_none = 0

            if weight_none > 0:
                picker.add_option(None, weight_none)

            picker.add_option("mook", haven.weight_mook_monster)
            picker.add_option("boss", haven.weight_boss_monster)

            monster = picker.pick()

            if monster:
                self.ndb.last_monster_type = monster
                self.ndb.monster_attack = obj.name
                self.scripts.add(SpawnMobScript)

        if len(characters) > 0:
            return

        picker = WeightedPicker()
        if recent:
            picker.add_option(None, haven.weight_no_treasure_backtrack)
        else:
            picker.add_option(None, haven.weight_no_treasure)

        picker.add_option("trinket", haven.weight_trinket)
        picker.add_option("weapon", haven.weight_weapon)

        treasure = picker.pick()

        if treasure:
            if treasure == "trinket":
                trinket = LootGenerator.create_trinket(haven)
                trinket.location = self
            elif treasure == "weapon":
                weapon_types = (LootGenerator.WPN_BOW, LootGenerator.WPN_SMALL,
                                LootGenerator.WPN_MEDIUM,
                                LootGenerator.WPN_HUGE)
                weapon = LootGenerator.create_weapon(
                    haven, random.choice(weapon_types))
                weapon.location = self

        if self.ndb.combat_manager:
            obj.msg("Your party is already in combat! Joining the fight.")
            obj.msg(self.ndb.combat_manager.add_combatant(obj, obj))
            for mob in monsters:
                if mob.combat and mob.combat.state:
                    mob.combat.state.add_foe(obj)
Ejemplo n.º 7
0
            if monster_type:
                if monster_type == "mook":
                    monsters = monsters.filter(npc_type=Monster.MOOKS)
                elif monster_type == "boss":
                    monsters = monsters.filter(npc_type=Monster.BOSS)

            if monsters.count() == 0:
                self.stop()
                return

            picker = WeightedPicker()
            for monster in monsters.all():
                picker.add_option(monster, monster.weight_spawn)

            monster = picker.pick()

        mob_instance = monster.create_instance(self.obj)
        self.obj.msg_contents("{} attacks {}!".format(
            mob_instance.name, self.obj.ndb.monster_attack))
        mob_instance.attack(self.obj.ndb.monster_attack, kill=True)
        mob_instance.combat.set_switch_chance(40)

        if haven.auto_combat:
            cscript = self.obj.ndb.combat_manager
            for testobj in self.obj.contents:
                if (testobj.has_player or (hasattr(testobj, 'is_character') and testobj.is_character)) \
                        and not testobj.check_permstring("builders"):
                    if not cscript.check_character_is_combatant(testobj):
                        testobj.msg(cscript.add_combatant(testobj, testobj))
                    if not testobj.is_typeclass('world.exploration.npcs.BossMonsterNpc') \
Ejemplo n.º 8
0
    def create_weapon(cls, haven, wpn_type=None):

        weapon_types = (
            LootGenerator.WPN_SMALL,
            LootGenerator.WPN_MEDIUM,
            LootGenerator.WPN_HUGE,
            LootGenerator.WPN_BOW,
        )

        if not wpn_type:
            wpn_type = random.choice(weapon_types)

        picker = WeightedPicker()

        difficulty = haven.difficulty_rating
        if difficulty < 3:
            picker.add_option("steel", 30)
            picker.add_option("rubicund", 50)
            picker.add_option("diamondplate", 1)
        elif difficulty < 5:
            picker.add_option("steel", 10)
            picker.add_option("rubicund", 40)
            picker.add_option("diamondplate", 5)
        elif difficulty < 8:
            picker.add_option("rubicund", 30)
            picker.add_option("diamondplate", 20)
            picker.add_option("alaricite", 5)
        else:
            picker.add_option("rubicund", 10)
            picker.add_option("diamondplate", 30)
            picker.add_option("alaricite", 5)

        material = picker.pick()

        should_name = material in ["diamondplate", "alaricite"]

        generator_wpn = GeneratedLootFragment.MEDIUM_WEAPON_TYPE
        if wpn_type == LootGenerator.WPN_SMALL:
            generator_wpn = GeneratedLootFragment.SMALL_WEAPON_TYPE
        elif wpn_type == LootGenerator.WPN_HUGE:
            generator_wpn = GeneratedLootFragment.HUGE_WEAPON_TYPE
        elif wpn_type == LootGenerator.WPN_BOW:
            generator_wpn = GeneratedLootFragment.BOW_WEAPON_TYPE

        name = GeneratedLootFragment.generate_weapon_name(
            material, include_name=should_name, wpn_type=generator_wpn)
        weapon = create.create_object(
            typeclass="world.exploration.loot.AncientWeapon", key=name)

        desc = "\n{particle} {adjective} ancient {material} weapon, with {decor} on the {element}.\n"
        if wpn_type == LootGenerator.WPN_BOW:
            desc = "\n{particle} {adjective} ancient {material} bow, decorated with {decor}.\n"

        adjective = GeneratedLootFragment.pick_random_fragment(
            GeneratedLootFragment.ADJECTIVE)
        decor = GeneratedLootFragment.pick_random_fragment(
            GeneratedLootFragment.WEAPON_DECORATION)
        element = GeneratedLootFragment.pick_random_fragment(
            GeneratedLootFragment.WEAPON_ELEMENT)
        particle = a_or_an(adjective).capitalize()

        desc = desc.replace("{particle}", particle)
        desc = desc.replace("{material}", material)
        desc = desc.replace("{adjective}", adjective)
        desc = desc.replace("{decor}", decor)
        desc = desc.replace("{element}", element)

        weapon.db.desc = desc

        quality_picker = WeightedPicker()
        quality_picker.add_option(4, 25)
        quality_picker.add_option(5, 45)
        quality_picker.add_option(6, 30)
        quality_picker.add_option(7, 10)
        quality_picker.add_option(8, 3)
        quality_picker.add_option(9, 1)

        weapon.item_data.quality_level = quality_picker.pick()
        weapon.db.found_shardhaven = haven.name
        weapon.item_data.recipe = LootGenerator.get_weapon_recipe(
            material, wpn_type=wpn_type)

        cls.set_alignment_and_affinity(haven, weapon)

        return weapon