def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): probKill = Event.DieOrEscapeProb1v1( mainActor, victims[0], state["settings"], defenseStat=(victims[0].getCombatAbility(mainActor) * 0.25 + victims[0].stats['cleverness'] * 0.15)) tempList = [mainActor, state["items"]["Bow and Arrow"], victims[0]] # Deteriorate relationship of victim toward participant state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -2) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -3) lootDict = None destroyedList = None if random.random() < probKill: victims[0].kill() deadList = [victims[0].name] desc = mainActor.name + ' shot an arrow at ' + \ victims[0].name + " and killed " + \ Event.parseGenderObject(victims[0]) + "." lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) else: deadList = [] desc = mainActor.name + ' shot an arrow at ' + \ victims[0].name + ", but missed." # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, tempList, deadList, loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): eventPeople = [mainActor] + participants numItems = random.randint(1, 2) itemsFound = [ ItemInstance.takeOrMakeInstance(v) for v in random.sample(list(state['items'].values()), 2) ] descList = eventPeople + itemsFound fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.fight( eventPeople, state["allRelationships"], preexistingLoot=itemsFound) if fightDesc is None: return None desc = Event.englishList( eventPeople) + " stumbled across " + Event.englishList( itemsFound) + " at the same time. A fight broke out. " + fightDesc return EventOutput(desc, descList, [x.name for x in fightDead], allKillers, loot_table=lootDict, injuries=injuries, list_killers=True, destroyed_loot_table=destroyedList)
def func(self: Event, mainActor: Contestant, state, participants: Optional[List[Contestant]], victims: List[Contestant], sponsors: Optional[List[Contestant]]=None): probKill = Event.DieOrEscapeProb1v1(mainActor, victims[0], state["settings"], defenseStat=( victims[0].getCombatAbility(mainActor) * 0.75 + victims[0].stats['cleverness'] * 0.25)) spearBroken = random.randint(0, 1) tempList = [mainActor, state["items"]["Spear"], victims[0]] # Deteriorate relationship of victim toward participant state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -2) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -3) lootDict = None destroyedList = None if random.random() < probKill: victims[0].kill() deadList = [victims[0].name] desc = mainActor.name + ' threw a spear through ' + \ victims[0].name + "'s neck and killed " + \ Event.parseGenderObject(victims[0]) + "." lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) else: deadList = [] desc = mainActor.name + ' threw a spear at ' + \ victims[0].name + ", but missed." # 50/50 chance the victim gets the spear, if not broken. if not spearBroken and random.randint(0, 1): desc += " " + victims[0].name + " was able to steal the spear!" lootref = mainActor.removeAndGet(state["items"]["Spear"]) victims[0].addItem(lootref) lootDict = {victims[0].name: [lootref]} if spearBroken: desc += " The spear was broken in the process." mainActor.removeItem(state["items"]["Spear"]) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, tempList, deadList, loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): desc = CLIFF_DESCRIPTIONS[random.randint(0, len(CLIFF_DESCRIPTIONS) - 1)](mainActor, victims[0]) state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -4) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -6) victims[0].kill() if mainActor.stats["stability"] < 3: desc += ' ' + Event.parseGenderSubject(mainActor).capitalize() + ' smiled as ' + Event.parseGenderSubject( mainActor) + ' watched ' + Event.parseGenderObject(victims[0]) + ' die.' mainActor.permStatChange({'stability': -1}) tempList = [mainActor, victims[0]] lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, tempList, [victims[0].name], loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): probKill = Event.DieOrEscapeProb1v1( mainActor, victims[0], state["settings"], defenseStat=(victims[0].getCombatAbility(mainActor) * 0.15 + victims[0].stats['cleverness'] * 0.10)) tempList = [mainActor, state["items"]["Rifle"], victims[0]] # Deteriorate relationship of victim toward participant state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -2) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -3) # RNG ammo use, this is unique to the rifle. actualItem = mainActor.hasThing("Rifle")[0] currentAmmo = actualItem.data.get("currentammo", actualItem.rawData["ammo"]) ammoUsed = min( random.randint(actualItem.rawData["ammouse"][0], actualItem.rawData["ammouse"][1]), currentAmmo) currentAmmo -= ammoUsed lootDict = None destroyedList = None if random.random() < probKill: victims[0].kill() deadList = [victims[0].name] desc = mainActor.name + ' fired at ' + \ victims[0].name + " from long range and killed " + \ Event.parseGenderObject(victims[0]) + "." lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) else: deadList = [] desc = mainActor.name + ' fired at ' + \ victims[0].name + " from long range, but missed." if currentAmmo > 0: desc += "\nAmmo remaining: " + str(currentAmmo) + " (" + str( ammoUsed) + " used)" actualItem.data["currentammo"] = currentAmmo else: desc += "\nThe Rifle belonging to " + mainActor.name + " exhausted its ammo." mainActor.removeItem("Rifle") # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, tempList, deadList, loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): desc = mainActor.name + ', ' + \ participants[0].name + ', and ' + participants[1].name + ' fought.' descList = [mainActor, participants[0], participants[1]] fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.fight( descList, state['allRelationships']) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc + fightDesc, descList, [x.name for x in fightDead], allKillers, loot_table=lootDict, injuries=injuries, list_killers=True, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): theDead = [x for x in state["contestants"].values() if not x.alive] # if no one dead, then no body to find, so need new event if not theDead: return None # encounter random body… this might be a problem if bodies ever get incinerated or something? body = random.choice(theDead) mainActor.permStatChange({'stability': -1}) # initialize some stuff lootDict = None destroyedList = None descBeginning = mainActor.name + ' found ' + body.name + "'s body" descNoLoot = descBeginning + ', but searching it turned up nothing useful' descEnd = '.' # generate appropriate message if body.inventory: lootDict, destroyedList = self.lootForOne(mainActor, body, chanceDestroyedOverride=0) if lootDict: # if there's any loot, a separate message will be generated for it, so we don't need to describe it here desc = descBeginning else: desc = descNoLoot else: desc = descNoLoot desc += descEnd # Second entry is the contestants named in desc, in order. Third is anyone who died… but no one died. return EventOutput(desc, [mainActor, body], [], loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): attackers = [mainActor] + participants desc = Event.englishList( attackers ) + " worked together to ambush and attack " + victims[0].name + "." descList = attackers + victims fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.factionFight( attackers, victims, state["allRelationships"]) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc + fightDesc, descList, sorted([x.name for x in fightDead]), allKillers, loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): # they shouldn't be practicing combat if injured if state["callbackStore"].setdefault('InjuredDict', defaultdict(bool)): return None desc = mainActor.name + ' practiced combat' practiceAbility = mainActor.stats['combat ability'] injuries = None if random.random() > 1 / (1 + 1.3**practiceAbility): desc += ' but hurt ' + \ Event.parseGenderReflexive(mainActor) + ' doing so.' mainActor.addStatus(state["statuses"]["Injury"]) injuries = [str(mainActor)] else: desc += ' and was successfully able to improve ' + \ Event.parseGenderPossessive(mainActor) + ' skills' mainActor.permStatChange({'combat ability': 1}) return EventOutput(desc, [mainActor], [], injuries=injuries)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): probSurvival = (1 - Event.DieOrEscapeProb1v1( mainActor, victims[0], state["settings"], defenseStat=(victims[0].getCombatAbility(mainActor) * 0.75 + victims[0].stats['cleverness'] * 0.25)) ) * 0.5 # This event is rigged against defender tempList = [mainActor, state["items"]["MolotovCocktail"], victims[0]] state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -4) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -6) if random.random() < probSurvival: desc = mainActor.name + ' threw a molotov cocktail at ' + \ victims[0].name + " but " + \ Event.parseGenderSubject(victims[0]) + " escaped!" return (desc, tempList, []) else: victims[0].kill() desc = mainActor.name + ' threw a molotov cocktail at ' + \ victims[0].name + " and burned " + \ Event.parseGenderObject(victims[0]) + " alive." mainActor.permStatChange({'stability': -2}) if mainActor.stats["stability"] < 3: desc += " " + mainActor.name + " laughed at " + \ Event.parseGenderPossessive(victims[0]) + " agony." mainActor.removeItem(state["items"]["MolotovCocktail"]) lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) if victims[0].removeStatus(state["statuses"]["Hypothermia"]): desc += " " + victims[0].name + " is no longer hypothermic." # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, tempList, [victims[0].name], loot_table=lootDict, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): # Deteriorate relationship of victim toward participant state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, -2) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, -3) probKill = Event.DieOrEscapeProb1v1( mainActor, victims[0], state["settings"], defenseStat=(victims[0].getCombatAbility(mainActor) * 0.5 + victims[0].stats['cleverness'] )) # this event is mildly rigged against attacker descList = [mainActor, victims[0]] if random.random() < probKill: victims[0].kill() if mainActor.stats['ruthlessness'] > 6: desc = mainActor.name + ' lay in wait for ' + \ victims[0].name + ', surprising and gutting ' + \ Event.parseGenderObject(victims[0]) + '.' else: desc = mainActor.name + ' lay in wait for ' + \ victims[0].name + ', surprising and killing ' + \ Event.parseGenderObject(victims[0]) + '.' lootDict, destroyedList = self.lootForOne(mainActor, victims[0]) return EventOutput(desc, descList, [victims[0].name], loot_table=lootDict, destroyed_loot_table=destroyedList) else: desc = mainActor.name + ' lay in wait for ' + \ victims[0].name + ', but ' + \ Event.parseGenderSubject(victims[0]) + ' managed to see it coming.' # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return (desc, descList, [])
def func(self: Event, mainActor, state=None, participants=None, victims=None, sponsors=None): desc = str(mainActor) + " offered to cook for " + \ str(victims[0]) + ", who gladly accepted." descList = [mainActor, victims[0]] # Roll for failure to actually poison notFailure = (victims[0].stats["cleverness"] + victims[0].stats["survivalism"]) / 15 if random.random() > notFailure: desc += " However, " + \ str(mainActor) + " tried to secretly poison the dish, but failed, using the wrong mushrooms. The dish was delicious." state["allRelationships"].IncreaseFriendLevel(victims[0], mainActor, random.randint(1, 3)) state["allRelationships"].IncreaseLoveLevel(victims[0], mainActor, random.randint(0, 2)) return (desc, descList, []) desc += " However, " + str(mainActor) + \ " tried to secretly poison the dish! " # Roll for participant realizing what's going on detection = (victims[0].stats["cleverness"] + victims[0].stats["survivalism"]) / 30 injuries = None destroyedList = None if random.random() < detection: # Participant realizes what's going on desc += str(victims[0]) + " caught " + \ Event.parseGenderObject(mainActor) + " in the act and attacked!" (fightDesc, fightDeadList, allKillers, lootDict, injuries, destroyedList) = self.fight(descList, state["allRelationships"]) if fightDeadList is None: # Event fight failed. return None # Special: if only one loser, 33% chance the loser escapes injured instead, losing loot. If they are already injured they just die (skip this segment). if len(fightDeadList) == 1 and random.random( ) < 0.33 and not fightDeadList[0].hasThing("Injury"): # revive the loser fightDeadList[0].alive = True fightDeadList[0].addStatus(state["statuses"]["Injury"]) if fightDeadList[0] == mainActor: desc += ' In the end, ' + mainActor.name + ' was injured and forced to flee.' else: desc += ' In the end, however, ' + \ victims[0].name + ' was injured and forced to flee.' return EventOutput(desc, descList, [], loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList) if not fightDeadList: desc += ' The fight was a draw, and the two sides departed, friends no more.' return (desc, descList, []) desc += fightDesc return (desc, descList, [x.name for x in fightDeadList], allKillers) else: desc += str(victims[0]) + \ " ate the meal, blissfully unaware, before falling over dead." victims[0].kill() lootDict, destroyedList = self.lootForOne(mainActor, victims[0], chanceDestroyedOverride=0) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, descList, [str(victims[0])], loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): desc = "Tired of waiting, the sponsors force two of the remaining contestants to fight. " # Build dict of weights for various possibilities optionDict = collections.OrderedDict() optionDict['fight'] = 1 if state['allRelationships'].friendships[str(mainActor)][str( participants[0])] > 3 and state['allRelationships'].friendships[ str(participants[0])][str(mainActor)] > 3: optionDict['attemptEscape'] = 2 if state['allRelationships'].loveships[str(mainActor)][str( participants[0])] > 3: optionDict['actorSuicide'] = 1 optionDict['actorBegToKill'] = 1 if state['allRelationships'].loveships[str( participants[0])][str(mainActor)] > 3: optionDict['participantSuicide'] = 1 optionDict['participantBegToKill'] = 1 chosen = weightedDictRandom(optionDict, 1)[0] if chosen == 'fight': # Keep running until only neither 0 nor all contestants are dead. fightDead = [] # dummy list. while (len(fightDead) != 1): fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.fight( [mainActor, participants[0]], state['allRelationships'], deferActualKilling=True, forceRelationshipFight=True) # We had to deny Event.fight actually killing anyone because of fact that it might be reset. fightDead[0].kill() desc += "They did so." + fightDesc return EventOutput(desc, [mainActor, participants[0]], [str(x) for x in fightDead], allKillers, loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList) if chosen == 'attemptEscape': escape = bool(random.randint(0, 1)) if escape: mainActor.escape() participants[0].escape() desc += 'Instead of fighting, the two contestants attempt to escape, and do so successfully!' # This is a hack, declaring both of them "Dead" but ending the game immediately with overriding text that suggests they survived. return (desc, [mainActor, participants[0]], [str(mainActor), str(participants[0])], {}, [mainActor, participants[0]], True) dead = mainActor if random.randint(0, 1) else participants[0] desc += 'Instead of fighting, the two contestants attempt to escape, but ' + \ dead.name + ' is caught and killed by the sponsors!' dead.kill() return (desc, [mainActor, participants[0]], [dead.name]) if chosen == 'actorSuicide': desc += "Rather than be forced to fight " + Event.parseGenderPossessive( mainActor) + " loved one, " + str( mainActor) + " committed suicide!" mainActor.kill() return (desc, [mainActor, participants[0]], [mainActor.name]) if chosen == 'participantSuicide': desc += "Rather than be forced to fight " + Event.parseGenderPossessive( participants[0]) + " loved one, " + str( participants[0]) + " committed suicide!" participants[0].kill() return (desc, [mainActor, participants[0]], [participants[0].name]) if chosen == 'actorBegToKill': desc += str(mainActor) + " begged " + \ str(participants[0]) + " to kill " + \ Event.parseGenderObject(mainActor) if state['allRelationships'].loveships[str( participants[0])][str(mainActor)] < 4 or random.random() > 0.5: desc += ', forcing ' + \ str(participants[0]) + ' to go through with it.' mainActor.kill() deadList = [mainActor.name] else: desc += ', but ' + Event.parseGenderSubject( participants[0] ) + ' refused, killing ' + Event.parseGenderReflexive( participants[0]) + ' instead!' participants[0].kill() deadList = [participants[0].name] return (desc, [mainActor, participants[0]], deadList) if chosen == 'participantBegToKill': desc += str(participants[0]) + " begged " + str(mainActor) + \ " to kill " + Event.parseGenderObject(participants[0]) if state['allRelationships'].loveships[str(mainActor)][str( participants[0])] < 4 or random.random() > 0.5: desc += ', forcing ' + str(mainActor) + ' to go through with it.' deadList = [participants[0].name] participants[0].kill() else: desc += ', but ' + Event.parseGenderSubject( mainActor) + ' refused, killing ' + Event.parseGenderReflexive( mainActor) + ' instead!' mainActor.kill() deadList = [mainActor.name] return (desc, [mainActor, participants[0]], deadList) raise AssertionError("This should not happen! " + chosen)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): success = True # It's okay to overwrite since we only care if it happened this turn self.eventStore.setdefault( 'turnRecord', defaultdict(lambda: -1))[mainActor.name] = state["turnNumber"][0] # If mainActor has a lover, divert this into light romance. possible_love = mainActor.hasThing("Love") if possible_love and not str(possible_love[0].target) in state["sponsors"]: lover = possible_love[0].target desc = str(mainActor) + ' and ' + str( lover) + ' successfully started a fire together.' mainActor.removeStatus("Hypothermia") lover.removeStatus("Hypothermia") self.eventStore[str(lover)] = True self.eventStore[str(mainActor)] = True #Need to prevent lover from showing up in events again. self.eventStore["turnRecord"][lover.name] = state["turnNumber"][0] descList = [mainActor, lover] if not mainActor.hasThing("Clean Water") or not lover.hasThing( "Clean Water"): if random.random() > 0.5: desc += ' Using it, they were able to boil some Clean Water.' mainActor.addItem(state["items"]["Clean Water"], isNew=True) lover.addItem(state["items"]["Clean Water"], isNew=True) descList.append(state["items"]["Clean Water"]) return (desc, descList, []) if str(mainActor ) not in self.eventStore or not self.eventStore[str(mainActor)]: # base is 50%. unless the character has already done it before in which case success is assured # Yes this can overload past 1 chanceSuccess = mainActor.stats["cleverness"] * \ 0.02 + mainActor.stats["survivalism"] * 0.05 + 0.5 if random.random() > chanceSuccess: desc = str(mainActor) + ' tried to start a fire, but failed.' descList = [mainActor, state["statuses"]["Hypothermia"]] mainActor.addStatus(state["statuses"]["Hypothermia"].makeInstance( data={"day": state["turnNumber"][0]})) return (desc, descList, []) desc = str(mainActor) + ' successfully started a fire.' mainActor.removeStatus("Hypothermia") self.eventStore[str(mainActor)] = True # If character has ever killed anyone, initial 1/3 chance this becomes a haunting event. (affected by stability) # logistic hauntprob = 1 / ( 1 + exp(3 - len(state["callbackStore"]["killCounter"][str(mainActor)]) + (mainActor.stats["stability"] - 5) * self.settings['statInfluence'] * 0.4)) if state["callbackStore"]["killCounter"][str( mainActor)] and random.random() < hauntprob: haunter = state["contestants"][str( random.choice( state["callbackStore"]["killCounter"][str(mainActor)]))] desc = str(mainActor) + " f{} haunted by the ghost of " + str( haunter) + " and unable to sleep or make a fire." descList = [ mainActor, state["statuses"]["Ghost"], haunter, state["statuses"]["Hypothermia"] ] mainActor.addStatus(state["statuses"]["Hypothermia"].makeInstance( data={"day": state["turnNumber"][0]})) mainActor.permStatChange({"stability": random.randint(-2, 0)}) return EventOutput(desc, descList, [], no_contact=[haunter]) # Unless character already has clean water, 50% chance (potentially of the remaining 2/3) this becomes a clean water event if not mainActor.hasThing("Clean Water"): if random.random() > 0.5: desc += f' Using it, {Event.parseGenderSubject(mainActor)} {self.getWasConjugation(mainActor)} able to boil some Clean Water.' mainActor.addItem(state["items"]["Clean Water"], isNew=True) descList = [mainActor, state["items"]["Clean Water"]] return (desc, descList, []) # 50% chance here that nothing happens, unless it just ain't possible for something to happen (other participant must not have already done this event this turn or already have a fire) possibleFireSharers = [ x for x in state["contestants"].values() if x.alive and not self.eventStore["turnRecord"][x.name] == state["turnNumber"][0] and not x.hasThing("Love") ] if not possibleFireSharers or random.random() > 0.5: desc += f' {Event.parseGenderSubject(mainActor).capitalize()} {self.getWasConjugation(mainActor)} able to spend the night in comfort.' descList = [mainActor] return (desc, descList, []) # If someone finds them. Roll random contestant. contestant = random.choice(possibleFireSharers) desc += ' ' + contestant.name + ' found the fire' descList = [mainActor, contestant] # Use friendship and the other person's aggression/ruthlessness to determine what happens # Do they invite them to fire? - certain above 1 friendship or love, more ambivalent from -2 to 0, no below. Ruthlessness factors in. if ((state["allRelationships"].friendships[str(mainActor)][str(contestant)] > 0 and state["allRelationships"].loveships[str(mainActor)][str(contestant)] > 0) or (state["allRelationships"].friendships[str(mainActor)][str(contestant)] > -3 and state["allRelationships"].loveships[str(mainActor)][str(contestant)] > -3 and random.random() < ((min( state["allRelationships"].friendships[str(mainActor)][str( contestant)], state["allRelationships"].loveships[str( mainActor)][str(contestant)]) + 3) / 3 - mainActor.stats["ruthlessness"] / 15))): desc += ', and they agreed to share the fire together.' self.eventStore["turnRecord"][contestant.name] = state["turnNumber"][0] contestant.removeStatus("Hypothermia") state["allRelationships"].IncreaseFriendLevel(mainActor, contestant, random.randint(0, 1)) state["allRelationships"].IncreaseLoveLevel(mainActor, contestant, random.randint(0, 1)) state["allRelationships"].IncreaseFriendLevel(contestant, mainActor, random.randint(1, 3)) state["allRelationships"].IncreaseLoveLevel(contestant, mainActor, random.randint(0, 2)) return (desc, descList, []) desc += ', but ' + mainActor.name + ' refused to let ' + \ Event.parseGenderObject(contestant) + ' share it.' # Does the other party decide to attack? Only if friendship and loveship<0 if ((state["allRelationships"].friendships[str(contestant)][str(mainActor)] > 0 and state["allRelationships"].loveships[str(contestant)][str(mainActor)] > 0) or random.random() > (contestant.stats["aggression"] * 2 + contestant.stats["ruthlessness"]) * abs(state["allRelationships"].friendships[str(contestant)][str( mainActor)] + 2 * state["allRelationships"].loveships[str( contestant)][str(mainActor)]) / 450): desc += ' After a moment, ' + contestant.name + ' left.' return (desc, descList, [], [], [mainActor]) desc += ' After a moment, ' + contestant.name + ' attacked.' (fightDesc, fightDeadList, allKillers, lootDict, injuries, destroyedList) = self.fight(descList, state["allRelationships"], deferActualKilling=True) # We need to handle special cases because we want some chance of someone being injured and running away instead. # If everyone dies if len(fightDeadList) == 2: fightDeadList[0].kill() fightDeadList[1].kill() # Special: if only one loser, 33% chance the loser escapes injured instead, losing loot. if len(fightDeadList) == 1: if random.random() > 0.33: # kill him anyway. fightDeadList[0].kill() else: # Injure the loser and divert the event outcome fightDeadList[0].addStatus(state["statuses"]["Injury"]) if fightDeadList[0] == mainActor: self.eventStore["turnRecord"][ contestant.name] = state["turnNumber"][0] desc += ' and ' + mainActor.name + ' was injured and forced to flee.' mainActor.addStatus( state["statuses"]["Hypothermia"].makeInstance( data={"day": state["turnNumber"][0]})) contestant.removeStatus("Hypothermia") else: desc += ' but ' + contestant.name + ' was injured and forced to flee.' contestant.addStatus( state["statuses"]["Hypothermia"].makeInstance( data={"day": state["turnNumber"][0]})) if fightDeadList[0] not in injuries: injuries.append(fightDeadList[0]) return EventOutput(desc, descList, [], loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList) # If nobody was hurt, they just give up and use the fire together. if not fightDeadList: self.eventStore["turnRecord"][contestant.name] = state["turnNumber"][0] contestant.removeStatus("Hypothermia") desc += '\nIn the end both sides got tired and gave up, agreeing to use the fire together for one night. Neither side slept well.' return EventOutput(desc, descList, [], injuries=injuries) # need to ban contestant from turning up again in fire events if they won the fight. if contestant.name not in fightDeadList: self.eventStore["turnRecord"][contestant.name] = state["turnNumber"][0] desc += fightDesc return EventOutput(desc, descList, [x.name for x in fightDeadList], allKillers, loot_table=lootDict, injuries=injuries, destroyed_loot_table=destroyedList)
def func(self, mainActor, state=None, participants=None, victims=None, sponsors=None): eventPeople = [mainActor] + participants relationships = state["allRelationships"] while True: whatHappens = random.randint(0, 2) # 0 is empty, 1 is loot, 2 is trap descList = eventPeople.copy() desc = Event.englishList( eventPeople) + ' found an abandoned building, ' fightDead = [] allKillers = None lootDict = None destroyedList = None injuries = None if whatHappens == 0: desc += 'but it turned out to have nothing of value.' if len(eventPeople) > 1: probViolence = 0.25 - \ relationships.groupCohesion(eventPeople) / 200 if random.random() < probViolence: fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.fight( eventPeople, relationships) if fightDesc is None: continue desc += ' Violence broke out due to frustration.' desc += fightDesc break elif whatHappens == 1: # get one or two random pieces of loot new_loot = random.sample(list(state['items'].values()), random.randint(1, 2)) desc += ' and found sweet loot!' # let the loot be described separately lootDict = {} destroyedList = [] # If there is no fight, there's no reason loot would be destroyed. overrideLootDestructionChance = 0 if len(eventPeople) > 1: probViolence = 0.5 - relationships.groupCohesion( eventPeople) / 100 if random.random() < probViolence: overrideLootDestructionChange = None fightDesc, fightDead, allKillers, lootDict, injuries, destroyedList = self.fight( eventPeople, relationships, False, False, preexistingLoot=new_loot) if fightDesc is None: continue desc += ' A fight broke out over the loot.' desc += fightDesc break # This has separate logic than what happens if there is no fight. partialLoot, partialDestroyed = self.lootForMany( eventPeople, new_loot, chanceDestroyedOverride=overrideLootDestructionChance) Event.MergeLootDicts(lootDict, partialLoot) Event.MergeDestroyedLists(destroyedList, partialDestroyed) break elif whatHappens == 2: desc += ' but the building was booby-trapped! ' for person in eventPeople: if person.stats['cleverness'] + person.stats[ 'combat ability'] + random.randint(0, 21) < 21: person.kill() fightDead.append(person) if not fightDead: if len(eventPeople) > 1: desc += 'Everyone escaped safely.' else: desc += Event.parseGenderSubject( eventPeople[0]).capitalize() + ' escaped safely.' # This must be done separately because it assigns no killers # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return (desc, descList, [x.name for x in fightDead], collections.OrderedDict()) # Second entry is the contestants or items named in desc, in desired display. Third is anyone who died. This is in strings. return EventOutput(desc, descList, [x.name for x in fightDead], allKillers, loot_table=lootDict, injuries=injuries, list_killers=True, destroyed_loot_table=destroyedList)