def greet(ent:int, style=0) -> int: # attempt to init conversation pc=rog.pc() world=rog.world() personality=world.component_for_entity(ent,cmp.Personality).personality dispcompo=world.component_for_entity(ent,cmp.Disposition) # new disposition after dialogue concludes new_disposition = dispcompo.disposition # effective disposition during this dialogue (not the new disposition) ed = dispcompo.disposition + _get_reaction( ent, TALK_GREETING, personality, dispcompo.disposition, style=style, mx=0.5 ) reaction = rog.sign(ed) # just nudge disposition fdisp = ed / MAX_DISPOSITION # roll for speech success speech_bonus = rog.getskill(pc, SKL_PERSUASION) roll=dice.roll(100) + speech_bonus if fdisp < 0.4: roll -= 8/fdisp else: roll += 100*fdisp # cases if roll <= 0: _response(ent, RESPONSE_REJECTION) else: _response(ent, RESPONSE_ACCEPT) return reaction
def _get_transaction_value( ent:int, personality:int, disposition:int, pc_offer:BarterOffer, npc_offer:BarterOffer, style=0 ) -> int: world = rog.world() pc = rog.pc() DMAX = MAX_DISPOSITION total = 0 # modifiers my_base = 2 # by default, I value my own things more highly pc_base = 0.5 # other people's stuff is much less valuable my_modf = PERSONALITIES[personality][3] pc_modf = PERSONALITIES[personality][4] # disposition disp_influence = 0.5 # how much does disp. affect perceived value? dr = (disposition - 0.5*DMAX)/DMAX my_disp_modf = 1 - dr*disp_influence pc_disp_modf = 1 + dr*disp_influence # speech skill level speech_influence = 1 # how much does speech affect perceived value? pc_speech = rog.getskill(pc, SKL_PERSUASION) my_speech = rog.getskill(ent, SKL_PERSUASION) sr = (my_speech - pc_speech)/MAX_SKILL my_speech_modf = 1 - sr*speech_influence pc_speech_modf = 1 + sr*speech_influence # PC offer total += pc_offer.money # money for item in pc_offer.items: # items value = world.component_for_entity(item, cmp.Form).value total += value*pc_base*pc_modf*pc_disp_modf*pc_speech_modf # NPC offer total += npc_offer.money # money for item in npc_offer.items: # items value = world.component_for_entity(item, cmp.Form).value total -= value*my_base*my_modf*my_disp_modf*my_speech_modf return int(total)
def talk_flirt(ent:int, personality:int, disposition:int, value=0, style=0) -> tuple: ttype = TALK_FLIRTATION reaction=_get_reaction(ent, ttype, personality, disposition, style=style) success = (reaction > 0) if not success: sb = rog.getskill(rog.pc(), SKL_PERSUASION)//5 if dice.roll(20) > (10 + sb + reaction//4): creepout(ent) _change_disposition(ent, reaction, PERSUASION[ttype][2]) annoy(ent, 5) return _talk(ent, success, ttype, personality, disposition, 600)
def diabetes(ent): # buildup for Diabetes Status world=rog.world() if world.has_component(ent, cmp.GetsDiabetes): compo = world.component_for_entity(ent, cmp.GetsDiabetes) dice_size = 140 - rog.getskill(rog.pc(),SKL_PERSUASION) dice_size = _apply_compatibility_modifier_pseudostatus( ent, dice_size, factor=1.5 ) dice_size *= res_diabetes(ent) compo.diabetes += dice.roll(rog.around(dice_size)) if compo.diabetes >= MAX_DIABETES: compo.diabetes = 0 rog.set_status(ent, cmp.StatusDiabetes) print(compo.diabetes)
def _select_skill(_skillID): pc=Chargen.pc _skillName = rog.get_skill_name(_skillID) _skillPts = get_skill_skillpts(_skillID) + rog.getskill(pc, _skillID)//SKILL_INCREQ if rog.getskill(pc, _skillID) >= MAX_SKILL: _maxedSkill(_skillName) return False if Chargen.skillPts < _skillPts: _insufficientPoints(Chargen.skillPts, _skillPts, "skill") return False # change skill level rog.setskill(pc, _skillID, min( 100, rog.getskill(pc, _skillID) + SKILL_LEVELS_PER_SELECTION) ) # save selected data Chargen.skillPts -= _skillPts if Chargen.skillPts <= 0: Chargen.open_skills = False Chargen._skillNames.append(_skillName) Chargen._skillIDs.append(_skillID) print("skill chosen: {} (pts: {})".format(_skillName, Chargen.skillPts)) return True
def talk_debate(ent:int, personality:int, disposition:int, value=0, style=0) -> tuple: ttype = TALK_DEBATE reaction=_get_reaction(ent, ttype, personality, disposition, style=style) success = (reaction > 0) _change_disposition(ent, reaction, PERSUASION[ttype][2]) if (success and rog.world().has_component(ent,cmp.GetsAngry)): # success of anger roll depends on speech skill tobeat = 10 + rog.getskill(rog.pc(),SKL_PERSUASION)//10 # the following personalities anger people more easily in debate: if (rog.get_personality(rog.pc())==PERSON_APATHETIC or rog.get_personality(rog.pc())==PERSON_PROUD or rog.get_personality(rog.pc())==PERSON_ARGUMENTATIVE ): tobeat -= 10 # roll if dice.roll(20) >= tobeat: anger(ent, reaction) # end if annoy(ent, 10) return _talk(ent, success, ttype, personality, disposition, 900)
def _chargen_skills(): pc=Chargen.pc if Chargen.open_skills: Chargen.menu.update( {"- skills (pts: {})".format(Chargen.skillPts) : "close-skills",}) Chargen.skilldict={} sortdict = {k:v for k,v in sorted( SKILLS.items(), key=lambda item: item[1][SKILL_I_NAME].lower())} for k, sk in sortdict.items(): # Python 3.6+ remembers dict ordering so skills are already ordered skilllv = rog.getskill(pc, k) x = skilllv // SKILL_INCREQ cost = "({})".format(sk[SKILL_I_COST] + x) if skilllv < 100 else "<MAX>" string = "... {} {}".format(cost, sk[SKILL_I_NAME]) Chargen.skilldict.update({string : k}) for k,v in Chargen.skilldict.items(): Chargen.menu.update({k:v}) else: Chargen.menu.update( {"+ skills (pts: {})".format(Chargen.skillPts) : "open-skills",})
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)