コード例 #1
0
 def _create_memories(self, pc):
     world=rog.world()
     pos=world.component_for_entity(pc, cmp.Position)
     if world.has_component(pc, cmp.SenseSight):
         rang=world.component_for_entity(pc, cmp.SenseSight).sight
     else:
         self._discover_place(pos.x,pos.y,self.inanat(x,y))
     for x in     range( max(0, pos.x-rang), min(self.w, pos.x+rang+1) ):
         for y in range( max(0, pos.y-rang), min(self.h, pos.y+rang+1) ):
             
             if rog.can_see(pc,x,y):
                 self._discover_place(x,y,self.inanat(x,y))
コード例 #2
0
 def add_sound(self, x,y, text1,text2, volume):
     for obj in self._listeners_sounds:
         if rog.can_see(obj, x,y):
             continue
         data=rog.can_hear(obj, x,y, volume)
         if data:
             dx,dy,volHeard=data
             if volHeard <= 1:
                 dx=dy=0
         #   each entity gets its own Event object,
         #   specific to its own perception.
             text=text1 if obj.stats.get("hearing") >= SUPER_HEARING else text2
             lis=self.get_sounds(obj)
             lis.append(Event_Sound(dx,dy, text, volHeard))
             self._sounds.update({obj : lis})
コード例 #3
0
ファイル: managers.py プロジェクト: eyeCube/Softly-Roguelike
 def add_sight(self, x, y, text):
     for obj in self._listeners_sights:
         if rog.can_see(obj, x, y):
             lis = self.get_sights(obj)
             lis.append(Event_Sight(x, y, text))
             self._sights.update({obj: lis})
コード例 #4
0
ファイル: tilemap.py プロジェクト: eyeCube/Softly-Roguelike
    def _draw_what_player_sees(self, pc, sight):
        world=rog.world()
        pos=world.component_for_entity(pc, cmp.Position)
        
        for     x in range( max(0, pos.x-sight), min(self.w, pos.x+sight+1) ):
            for y in range( max(0, pos.y-sight), min(self.h, pos.y+sight+1) ):
##                print("tile at {} {} has light level {}".format(x ,y, self.get_light_value(x,y)))
                
                if not rog.can_see(pc, x, y, sight):
                    continue
                
                # get return data from rog.can_see
                ret=rog.fetchglobalreturn()
                if ret: # unpack
                    dist, plight = ret
                
                ents=self.thingsat(x, y)
                
                if ents:
                    charDiscover = None
                    entDrawn = False
                    
                    for ent in reversed(ents):
                        # calculate visibility
                        if ent==pc:
                            visibility=10 #VISIBILITY_MAX
                        else:
                            camo = rog.getms(ent, 'camo')
                            visibility=rog.visibility(
                                pc,sight,plight,camo,dist)
##                            print('visibility: ',visibility)
##                            print('stats: s{}, l{}, c{}, d{}'.format(sight, plight, camo, dist))
                        
                        if visibility<=0: continue
                        # render data based on visibility
                        rend=world.component_for_entity(ent, cmp.Draw)
                        char = rend.char if visibility > 1 else '?'
                        
                        if not entDrawn: # draw top entity
                            entDrawn = True
                            # get render data
                            fgcol=rend.fgcol
                            # render
                            libtcod.console_put_char(
                                self.con_map_state, x,y, char )
                            
##                            if type(fgcol)==type("s"): # TEST
##                                print("~~~ problem entity: {} named '{}'".format(
##                                    ent, rog.getname(ent)))

                            libtcod.console_set_char_foreground(
                                self.con_map_state, x,y, fgcol)
                            self._apply_rendered_bgcol(x,y, ent)
                            if world.has_component(ent, cmp.Creature):
                                continue # don't discover creatures
                        
                        if charDiscover is None:
                            charDiscover = char # we'll discover this entity
                            break # only discover one entity
                    # end for

                    self._discover_place(x,y, charDiscover)
                else:
                    libtcod.console_put_char_ex(self.con_map_state, x,y,
                        self.get_char(x, y),
                        self.get_color(x, y), self.get_bgcolor(x, y))
                    self._discover_place(x,y, None)
コード例 #5
0
def stateless(bot):
    '''
        Dumb temporary NPC controller function
        implementing a simple 8-directional desire system
    '''

    world = rog.world()
    desires = Desires(wander=7)
    sight = rog.getms(bot, "sight")
    pos = world.component_for_entity(bot, cmp.Position)
    botCreature = world.component_for_entity(bot, cmp.Creature)

    ##    botType=world.component_for_entity(bot, cmp.Draw).char #should not depend on draw component

    # Where should this go????
    ##    rog.run_fov_manager(bot) # moved to can_see

    # TODO: write this function
    def isFoe(myFaction, theirFaction):
        return True

    # TODO: re-implement listening
    # listen to events
    '''lis=rog.listen(bot)
    if lis:
        for ev in lis:
            if rog.can_see(bot,ev.x,ev.y):
                continue
            # hearing
            if not ev.volume: continue
            if rog.can_hear(bot, ev.x,ev.y, ev.volume):
                interest=5
                _add_desire_direction(
                    desires, bot.x,bot.y, ev.x,ev.y, interest)
        rog.clear_listen_events(bot)'''

    # iterate through each tile in sight and see what is there...
    # is there a better way to do this?
    # This code is a little slow.
    for x in range(pos.x - sight, pos.x + sight + 1):
        for y in range(pos.y - sight, pos.y + sight + 1):
            if (not rog.is_in_grid(x, y)  # out of bounds
                    or (x == pos.x and y == pos.y)):  # ignore self
                continue
            if not rog.can_see(bot, x, y, sight): continue  # can't see it

            here = rog.thingat(x, y)

            if here:
                isCreature = world.has_component(here, cmp.Creature)
                # decide what it is and what to do about it
                if isCreature:
                    creature = world.component_for_entity(here, cmp.Creature)
                    if rog.on(here, DEAD):
                        continue  # no interest in dead things

                    interest = 0

                    #desire to fight
                    if creature.faction == FACT_ROGUE:
                        interest = 1000
                    #grouping behavior
                    elif creature.faction == botCreature.faction:
                        interest = 5

                    if (interest > 0):
                        _add_desire_direction(desires, pos.x, pos.y, x, y,
                                              interest)
                    elif (interest < 0):
                        _add_fear_direction(desires, pos.x, pos.y, x, y,
                                            interest)
                #if thing is inanimate
                else:
                    #food desire if hungry
                    #treasure desire
                    pass

    # pick the direction it wants to move in the most
    highest = -999
    for i in range(3):
        for j in range(3):
            new = desires.get(j - 1, i - 1)
            if new > highest:
                highest = new
                coords = (
                    j - 1,
                    i - 1,
                )
    dx, dy = coords
    xto = pos.x + dx
    yto = pos.y + dy

    # out of bounds
    if not rog.is_in_grid(xto, yto):
        return

    # fight if there is a foe present
    mon = rog.monat(xto, yto)
    if (mon and mon is not bot):
        monFaction = world.component_for_entity(mon, cmp.Creature).faction
        if isFoe(botCreature.faction, monFaction):
            action.fight(bot, mon)
            return
    # or move
    elif not rog.solidat(xto, yto):
        if action.move(bot, dx, dy):
            return

    # if no action was done, just wait
    action.wait(bot)
コード例 #6
0
def _get_reaction(
    ent:int, persuasion_type:int, personality:int, disposition:int,
    leverage=0, mx=1, value=0, style=0
    ) -> int:
    ''' get reaction from an entity based on conversational parameters
        leverage: who has the power advantage? Pos: PC. TODO: implement!
        mx: multiplier for intensity
        value: value of transaction, if it's a barter or bribe
        Returns >0 values for positive reactions, <0 for negative
            the greater the value, the higher the intensity
    '''
    world=rog.world()
    pc=rog.pc()
    DMAX = MAX_DISPOSITION
    reaction = -20
    dice_size = 20
    
        # ---- initialize ---- #
    
    # get stats for player
    speech = rog.getskill(pc, SKL_PERSUASION)
    speech_bonus_modf = 0.5 + speech/MAX_SKILL
    speech_penalty_modf = 2.25 - 2*speech/MAX_SKILL
    pc_idn = rog.getms(pc, 'idn')
    pc_bea = rog.getms(pc, 'bea')
    pc_cou = rog.getms(pc, 'cou')
    pc_str = rog.getms(pc, 'str')//MULT_STATS
    pc_int = rog.getms(pc, 'int')//MULT_STATS
    pc_pos = world.component_for_entity(pc, cmp.Position)
    
    # get stats for conversational partner
    ent_sight = rog.getms(ent,'sight')
    ent_cansee = rog.can_see(ent, pc_pos.x,pc_pos.y, ent_sight)
    
    disposition = get_effective_disposition(ent, disposition)

        # ---- basic reaction ---- #
    
    # (perceived) value of the transaction
    value_modf = max(1, (value//MULT_VALUE)*0.1)
    reaction += leverage

    # reaction based on existing disposition
    if disposition == 0:
        reaction -= 24
    elif disposition < 0.1*DMAX:
        reaction -= 18
    elif disposition < 0.2*DMAX:
        reaction -= 12
    elif disposition < 0.3*DMAX:
        reaction -= 6
    elif disposition < 0.4*DMAX:
        pass
    elif disposition < 0.5*DMAX:
        reaction += 3
    elif disposition < 0.6*DMAX:
        reaction += 6
    elif disposition < 0.7*DMAX:
        reaction += 9
    elif disposition < 0.8*DMAX:
        reaction += 12
    elif disposition < 0.9*DMAX:
        reaction += 15
    elif disposition < DMAX:
        reaction += 18
    else:
        reaction += 21
    
        # ---- status reaction ---- #
    
    if world.has_component(ent, cmp.StatusAnnoyed):
        compo = world.component_for_entity(ent, cmp.StatusAnnoyed)
        if compo.entity == pc:
            reaction -= 40
    
        # ---- special cases ---- #
    
    # people of high moral standing who never accept a bribe
    if world.has_component(ent, cmp.NeverAcceptsBribes):
        value_modf = 0
        
    # rich people don't care about low-value deals
    if (world.has_component(ent, cmp.Rich) and value < 100*MULT_VALUE):
        value_modf = 0
        if value < 10*MULT_VALUE:
            reaction -= 40
        else:
            reaction -= 20
    
        # ---- intensity, default reactions ---- #

    # intensity of the conversation based on transaction value    
    intensity = 1
    speech_mod = 0.4
    # intensity, base reaction, random variation (size of dice), and
    #   speech modifier (how much speech level affects reaction);
    #   based on type of conversation / persuasion
    if persuasion_type==TALK_TORTURE:
        speech_mod = 1.25*speech_mod
        dice_size = 100
        reaction -= 0.15*DMAX
        intensity = 10 * intensity
    elif persuasion_type==TALK_INTERROGATE:
        speech_mod = 1.5*speech_mod
        dice_size = 60
        reaction -= 0.085*DMAX
        intensity = 5 * intensity
    elif persuasion_type==TALK_INTIMIDATION:
        reaction -= 0.01*DMAX
        intensity = 4 * intensity
    elif persuasion_type==TALK_BEG:
        speech_mod = 1.33334*speech_mod
        reaction -= 0.05*DMAX
        intensity = 3 * intensity
    elif persuasion_type==TALK_BARTER:
        dice_size = 40
        intensity = 2 * intensity
        reaction -= 0.01*DMAX
        reaction += value_modf * value//MULT_VALUE
    elif persuasion_type==TALK_BRIBERY:
        dice_size = 40
        intensity = 2 * intensity
        reaction -= 0.02*DMAX
        reaction += value_modf * value//MULT_VALUE
    elif persuasion_type==TALK_CHARM: # relies on speech skill
        speech_mod = 1.5*speech_mod
        reaction -= 20
    elif persuasion_type==TALK_BOAST: # relies on perceived strength/fame
        speech_mod = 1.25*speech_mod
        reaction -= 40
        reaction += rog.get_power_level(rog.pc())
    elif persuasion_type==TALK_DEBATE:
        speech_mod = 1.5*speech_mod
        intensity = 2 * intensity
    elif persuasion_type==TALK_FLIRTATION:
        speech_mod = 1.5*speech_mod
        dice_size = 80
        reaction -= 50
        intensity = 2 * intensity
    elif persuasion_type==TALK_ASKFAVOR:
        reaction -= 0.025*DMAX
        intensity = 2 * intensity
    elif persuasion_type==TALK_FLATTERY:
        speech_mod = 1.5*speech_mod
        reaction -= 15
        dice_size = 40
        intensity = 1.5 * intensity
            # special combo-persuasion: Taunt -> Flattery
        if (world.has_component(ent, cmp.Taunted)
            and not world.has_component(ent, cmp.ComboTauntFlattery)
            ):
            if dice.roll(20) <= 5 + speech//5:
                reaction += 40
                intensity += 0.1
                rog.world().add_component(ent, cmp.ComboTauntFlattery())
                diabetes(ent) # gives more diabetes than usual flattery
    elif persuasion_type==TALK_TAUNT:
        speech_mod = 1.2*speech_mod
        reaction -= 0.01*DMAX
        intensity = 1.5 * intensity
    elif persuasion_type==TALK_SMALLTALK:
        speech_mod = 0.75*speech_mod
        reaction += 5
        intensity = 0.5 * intensity
    elif persuasion_type==TALK_GREETING:
        reaction += 1
        intensity = 0.25 * intensity
    
        # ---- attraction ---- #
            
    attraction = 0
    pc_isfemale = rog.get_gender(pc)=="female"
    pc_ismale = rog.get_gender(pc)=="male"
    
    # Sexual Attraction to Women
    if (ent_cansee and pc_isfemale
        and world.has_component(ent, cmp.AttractedToWomen)
        ):
        intensity += 1
        attraction += get_attraction_feminine(pc_bea)
    # Sexual Attraction to Men
    elif (ent_cansee and pc_ismale
        and world.has_component(ent, cmp.AttractedToMen)
        ):
        intensity += 1
        attraction += get_attraction_masculine(
            pc_bea, pc_idn, pc_cou, pc_str, pc_int
            )
    # end if
    
    # apply attraction reaction
    attraction = rog.around(attraction)
        # flirtation-specific
    if persuasion_type==TALK_FLIRTATION:
        #
            # special cases #
        # sorry hun, I'm taken.
        if world.has_component(ent, cmp.Taken):
            reaction -= 20
        # I don't do sex.
        if world.has_component(ent, cmp.Ascetic):
            reaction -= 40
            #
        #
        # attraction matter more for flirtation than other
        #   types of conversation.
        reaction += attraction
    else:
        # other
        reaction += attraction*0.5
    # end if
        
        # ---- compatibility ---- #
    
    # personality compatibility
    pc_personality = rog.get_personality(pc)
    compat = get_compatibility(personality, pc_personality)
    if compat==1:
        reaction -= 20
    elif compat==2:
        reaction -= 10
    elif compat==3:
        pass
    elif compat==4:
        reaction += 10
    elif compat==5:
        reaction += 20
##    print("personalities: ent: {}, player: {}".format(
##        personality, pc_personality))
##    print("personalities: ent: {}, player: {}".format(
##        PERSONALITIES[personality][0], PERSONALITIES[pc_personality][0]))
##    print("personality compatibility: ", compat)
    
    # likes and dislikes
    likes=_get_likes(personality)
    dislikes=_get_dislikes(personality)
    if persuasion_type == likes[0]:
        reaction += ( 0.01*DMAX * speech_bonus_modf * mx ) * intensity
    elif persuasion_type == dislikes[0]:
        reaction -= ( 0.02*DMAX * speech_penalty_modf * mx ) * intensity
    
    # special cases #
    # intensity and energy level
    if ((personality==PERSON_NONCONFRONTATIONAL
         or personality==PERSON_LOWENERGY)
        and intensity >= 3
        ):
        reaction -= 0.01*DMAX
    elif ((personality==ARGUMENTATIVE
           or personality==PERSON_BUBBLY)
         and intensity >= 3
        ):
        reaction += 0.01*DMAX
    # never accepts bribes
    if (persuasion_type==TALK_BRIBERY
        and world.has_component(ent, cmp.NeverAcceptsBribes)
        ):
        reaction = -0.05*DMAX * mx # set reaction
    # diabetes from too much flattery
    if (persuasion_type==TALK_FLATTERY
        and world.has_component(ent, cmp.StatusDiabetes)
        ):
        reaction = -0.075*DMAX * speech_penalty_modf * mx
    # auxiliary likes/dislikes
    if (persuasion_type==TALK_BEG and personality==PERSON_PROUD):
        reaction -= 0.05*DMAX * mx
    elif (persuasion_type==TALK_INTERROGATE and personality==PERSON_RELAXED):
        reaction -= 0.02*DMAX * mx
    elif (persuasion_type==TALK_CHARM and personality==PERSON_LOWENERGY):
        reaction -= 0.01*DMAX * mx
    elif (persuasion_type==TALK_CHARM and personality==PERSON_BUBBLY):
        reaction += 0.01*DMAX * mx
    elif (persuasion_type==TALK_BOAST and personality==PERSON_PROACTIVE):
        reaction -= 0.01*DMAX * mx
    elif (persuasion_type==TALK_BOAST and personality==PERSON_MOTIVATED):
        reaction += 0.01*DMAX * mx
    
    # creeped out
    if (world.has_component(ent, cmp.StatusCreepedOut)
        and pc==world.component_for_entity(ent, cmp.StatusCreepedOut).entity):
        reaction -= 40 if persuasion_type==TALK_FLIRTATION else 20
    
    # waste my time with 0 value offer -> minus some disp.
    if (persuasion_type==TALK_BRIBERY or persuasion_type==TALK_BARTER):
        if value == 0:
            reaction = min(-10, value)
    
    # add speech modifier
    reaction += speech * speech_mod
    # add element of random chance -- size of dice determined above
    reaction += dice.roll(dice_size)
    
    # trying to charm while already charmed -> loss of disposition
    if persuasion_type==TALK_CHARM:
        if world.has_component(ent, cmp.StatusCharmed):
            reaction = min(reaction - 100, -20)
    elif persuasion_type==TALK_BOAST:
        if world.has_component(ent, cmp.StatusCharmed):
            reaction = min(reaction - 100, -20)
    
    # people who have a hard time learning to like/trust others
    if (disposition >= 0.5*DMAX # lose reaction once disp crosses a threshold
        and world.has_component(ent, cmp.Untrusting)):
        reaction -= 20
    if (world.has_component(ent, cmp.Antisocial)):
        reaction -= 10
    
    return math.ceil(abs(reaction)) * rog.sign(reaction)
コード例 #7
0
def stateless(bot):

    # desire to move in a particular coordinate
    desires = Desires(wander=7)

    # listen to events
    '''lis=rog.listen(bot)
    if lis:
        for ev in lis:
            if rog.can_see(bot,ev.x,ev.y):
                continue
            # hearing
            if not ev.volume: continue
            if rog.can_hear(bot, ev.x,ev.y, ev.volume):
                interest=5
                _add_desire_direction(
                    desires, bot.x,bot.y, ev.x,ev.y, interest)
        rog.clear_listen_events(bot)'''

    # iterate through each tile in sight and see what is there...
    # is there a better way to do this?
    # This code is a little slow.
    sight = bot.stats.sight

    for x in range(bot.x - sight, bot.x + sight + 1):
        for y in range(bot.y - sight, bot.y + sight + 1):
            if (not rog.is_in_grid(x, y)  #out of bounds
                    or (x == bot.x and y == bot.y)):  #ignore self
                continue
            if not rog.can_see(bot, x, y): continue  #bot can't see it

            here = rog.thingat(x, y)

            if here:

                # decide what it is and what to do about it
                if rog.is_creature(here):
                    if rog.on(here, DEAD):
                        continue  #no interest in dead things

                    interest = 0

                    #desire to fight
                    if here.faction == FACT_ROGUE:
                        interest = 1000
                    #desire to run away
                    #elif here.type == '@':
                    #   interest=-1000
                    #grouping behavior
                    elif here.type == bot.type:
                        interest = 5
                    if (interest > 0):
                        _add_desire_direction(desires, bot.x, bot.y, x, y,
                                              interest)
                    elif (interest < 0):
                        _add_fear_direction(desires, bot.x, bot.y, x, y,
                                            interest)
                #if thing is inanimate
                else:
                    #food desire if hungry
                    #treasure desire
                    pass

    # pick the direction it wants to move in the most
    highest = -999
    for i in range(3):
        for j in range(3):
            new = desires.get(j - 1, i - 1)
            if new > highest:
                highest = new
                coords = (
                    j - 1,
                    i - 1,
                )
    dx, dy = coords
    xto = bot.x + dx
    yto = bot.y + dy

    # out of bounds
    if not rog.is_in_grid(xto, yto):
        return

    # fight if there is a monster present
    mon = rog.monat(xto, yto)
    if (mon and mon is not bot):
        if not mon.type == bot.type:  ##TEMPORARY
            action.fight(bot, mon)
            return
    # or move
    elif not rog.solidat(xto, yto):
        if action.move(bot, dx, dy):
            return

    # if no action was done, just wait
    action.wait(bot)