Skip to content

Commit

Permalink
clean up auto-buy. Notable issues:
Browse files Browse the repository at this point in the history
goodtrait items, if not selected, weren't filtered as the comments stated
in `30% chance for her to buy any good restore item.' a choice on an
empty newpool could ctd.
if pool is empty (e.g. if a char has no money) the shuffle(pool) can ctd.
(ctd notions based on code, not observation)

Signed-off-by: picobyte <pico0obyte@gmail.com>
  • Loading branch information
picobyte committed Dec 6, 2016
1 parent 8874a5e commit a213f59
Showing 1 changed file with 51 additions and 65 deletions.
116 changes: 51 additions & 65 deletions game/library/characters/classes - characters.rpy
Expand Up @@ -1676,26 +1676,22 @@ init -9 python:
returns = list()
if isinstance(item, basestring):
item = items[item]
# we handle request to auto-buy any specific item!
# we handle request to auto-buy a particular item!
# it won't filter out forbidden for slaves items, since it might be useful to do so
if item and item in auto_buy_items:
if self.gold >= item.price:
while self.take_money(item.price) and amount:
amount = amount - 1
self.inventroty.append(item)
returns.append(item.id)
if equip:
self.equip(item)
return returns
else:
return returns

# and now if it's just a request to buy an item randomly
# we make sure that she'll NEVER buy an items that is in badtraits, and also filter out too expensive ones
while self.take_money(item.price) and len(returns) < amount:
self.inventory.append(item)
returns.append(item.id)
if equip:
self.equip(item)
return returns

# otherwise if it's just a request to buy an item randomly
# make sure that she'll NEVER buy an items that is in badtraits, and also filter out too expensive ones
pool = set(item for item in auto_buy_items if not(item.badtraits.intersection(self.traits)) and (item.price <= self.gold))

if self.status == "slave": # for slaves we exclude all weapons, spells and armor immediately
pool = list(item for item in auto_buy_items if not(item.badtraits.intersection(self.traits)) and (item.price <= self.gold) and not(item.slot in ("weapon", "smallweapon")) and not(item.type in ("armor", "scroll")))
else:
pool = list(item for item in auto_buy_items if not(item.badtraits.intersection(self.traits)) and (item.price <= self.gold))
pool = pool.difference(item for item in pool if item.slot in ("weapon", "smallweapon") or item.type in ("armor", "scroll"))

# we form inventory set anyway
hasitems = set([i for i in self.inventory]) if self.inventory else set()
Expand All @@ -1704,77 +1700,69 @@ init -9 python:
hasitems.add(self.eqslots[key])

# Now lets see if a girl can buy one item that she really likes based on traits
if dice(80):
newpool = list(item for item in pool if item.goodtraits.intersection(self.traits))
if newpool:
selected_item = choice(newpool)
if selected_item not in hasitems:
if self.take_money(selected_item.price, "Items"):
self.inventory.append(selected_item)
returns.append(selected_item.id)
amount -= 1
# Break the for loop if amount == 0
if not amount:
newpool = set(item for item in pool if item.goodtraits.intersection(self.traits))
if dice(80) and newpool:
selected_item = random.choice(tuple(newpool))
if selected_item not in hasitems:
if self.take_money(selected_item.price, "Items"):
self.inventory.append(selected_item)
returns.append(selected_item.id)
if len(returns) >= amount:
return returns
else:
newpool = set()
else:
newpool = set()

# Ok, so if we made it here, we cannot buy any of the trait items...
# Or the dice has failed, we remove all trait items either way:
pool = list(i for i in pool if ((i not in newpool) and (i.type != "permanent"))) # also we remove all all permanent type items. the only way to autobuy them is to have a suitable goodtrait
pool = set(i for i in pool.difference(newpool) if i.type != "permanent") # also we remove all all permanent type items. the only way to autobuy them is to have a suitable goodtrait

if not(any([i for i in hasitems if i.slot == "body"])): # if she has zero body slot items, she will try to buy one dress
newpool = list(item for item in pool if ((item.type != "armor") and (item.slot == "body")))
if not any(i for i in hasitems if i.slot == "body"): # if she has zero body slot items, she will try to buy one dress
newpool = set(item for item in pool if ((item.type != "armor") and (item.slot == "body")))
if newpool:
selected_item = choice(newpool)
selected_item = random.choice(tuple(newpool))
if dice(100 - selected_item.badness) and self.take_money(selected_item.price, "Items"):
self.inventory.append(selected_item)
returns.append(selected_item.id)
amount -= 1
if not amount:
return returns
if len(returns) >= amount:
return returns

if dice(30):
# 30% chance for her to buy any good restore item.
newpool = list(item for item in pool if item.type == "restore")
selected_item = choice(newpool)
newpool = set(item for item in pool if item.type == "restore")
if newpool:
selected_item = random.choice(tuple(newpool))
if dice(100 - selected_item.badness) and self.take_money(selected_item.price, "Items"):
self.inventory.append(selected_item)
returns.append(selected_item.id)
amount = amount - 1
if not amount:
return returns
if len(returns) >= amount:
return returns

# then a high chance to buy a snack, I assume that all chars can eat and enjoy normal food even if it's actually useless for them in terms of anatomy, since it's true for sex
if ("Always Hungry" in self.traits and dice(80)) or dice(200 - self.vitality):
newpool = list(item for item in pool if item.type == "food")
newpool = set(item for item in pool if item.type == "food")
if newpool:
selected_item = choice(newpool)
selected_item = random.choice(tuple(newpool))
if dice(100 - selected_item.badness) and self.take_money(selected_item.price, "Items"):
self.inventory.append(selected_item)
returns.append(selected_item.id)
if len(returns) >= amount:
return returns
# and it doesn't count as +1 to requested amount of purchases, since it's not a big deal

if self.status != "slave": # we already excluded all battle items for slaves, so...
if not("Warrior" in self.occupations):
pool = list(i for i in pool if ((i.slot != "weapon") and (i.type != "armor"))) # non-warriors will never attempt to buy a big weapon or an armor
elif ("SIW" in self.occupations) or ("Server" in self.occupations) or ("Specialist" in self.occupations): # if the character has Warrior occupation, yet has other occupations too
if dice(40):
pool = list(i for i in pool if i.type != "dress") # then sometimes she ignores non armors
else:
if dice(75):
pool = list(i for i in pool if i.type != "dress") # and pure warriors ignore non armors quite often
if ("Caster" in self.occupations) and dice(25): # mages have a small chance to try to buy a scroll. why small? because we don't want them to quickly get all sellable spells in the game without MC's help
pass
else:
pool = list(i for i in pool if i.type != "scroll")
shuffle(pool)
if not("Warrior" in self.occupations):
pool = set(i for i in pool if ((i.slot != "weapon") and (i.type != "armor"))) # non-warriors will never attempt to buy a big weapon or an armor
elif ("SIW" in self.occupations) or ("Server" in self.occupations) or ("Specialist" in self.occupations): # if the character has Warrior occupation, yet has other occupations too
if dice(40):
pool = set(i for i in pool if i.type != "dress") # then sometimes she ignores non armors
else:
if dice(75):
pool = set(i for i in pool if i.type != "dress") # and pure warriors ignore non armors quite often
if ("Caster" in self.occupations) and dice(25): # mages have a small chance to try to buy a scroll. why small? because we don't want them to quickly get all sellable spells in the game without MC's help
pass
else:
pool = set(i for i in pool if i.type != "scroll")

# Items that remain is what a girl got to choose from.

for i in pool:
while pool and len(returns) < amount:
i = random.choice(tuple(pool))
# This will make sure that girl will never buy more than 5 of any item!
if i.id in self.inventory:
mod = self.inventory[i.id] * 20
Expand All @@ -1784,9 +1772,7 @@ init -9 python:
if dice(100 - i.badness - mod) and self.take_money(i.price, "Items"):
self.inventory.append(i)
returns.append(i.id)
amount = amount - 1
if not amount:
break
pool.remove(i)

return returns

Expand Down

0 comments on commit a213f59

Please sign in to comment.