Advertisement
Guest User

basic aff tracker framework

a guest
Jan 23rd, 2015
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.63 KB | None | 0 0
  1. import time
  2.  
  3. #i'm lazy
  4. def alert(line):
  5.     world.Note(line)
  6.  
  7. #constants
  8. TREE_BAL = 10
  9. HERB = 1
  10. SMOKE = 2
  11. SALVE = 3
  12.  
  13. #masks
  14. TREEABLE = 1<<0
  15. PURGEABLE = 1<<1
  16. FOCUSABLE = 1<<2
  17.  
  18. #manages limb damage etc
  19. class Limb:
  20.     def __init__(self, name):
  21.         self.name = name
  22.         self.damage = 0
  23.         self.is_parried = False
  24.  
  25.     def get_damage(self):
  26.         return self.damage
  27.  
  28.     def damaged(self, dam):
  29.         self.damage += dam
  30.  
  31.     def heal(self, dam):
  32.         self.damage -= dam
  33.         if self.damage < 0:
  34.             self.damage = 0
  35.  
  36.     def healed(self):
  37.         self.damage = 0
  38.  
  39.     def parried(self):
  40.         self.is_parried = True
  41.  
  42.     def has_parry(self):
  43.         return self.is_parried
  44.  
  45. #affliction structure
  46. class Affliction:
  47.     def __init__(self, name, type, cure, priority, cures=0):
  48.         self.name = name
  49.         self.cure = cure
  50.         self.type = type
  51.         self.default_priority = priority
  52.         self.priority = priority
  53.         self.on = False
  54.         self.cures = cures
  55.         self.gained_at = 0
  56.  
  57.     #is being a python keyword ruins everything
  58.     def aff_is(self, what):
  59.             return (self.cures & what)
  60.  
  61.     def has(self):
  62.         return (self.on == True)
  63.  
  64.     #this is for handling your own affs, not a targets
  65.     def gained(self):
  66.         if self.on == True:
  67.             return
  68.         self.on = True
  69.         alert("<Aff> " + self.name)
  70.         self.gained_at = time.time()
  71.  
  72.     #this is for handling your own affs, not a targets
  73.     def cured(self, silent=False):
  74.         if self.on == False:
  75.             return
  76.         self.on = False
  77.         if silent:
  78.             return
  79.         time_taken = time.time() - self.gained_at
  80.         alert("<Cured> %s (%.2fs)" % (self.name, time_taken))
  81.  
  82.     def get_priority(self):
  83.         return self.priority
  84.  
  85.     def set_priority(self, priority):
  86.         self.priority = priority
  87.  
  88.     def get_default_priority(self):
  89.         return self.default_priority
  90.  
  91.     def reset_priority(self):
  92.         self.priority = self.default_priority
  93.  
  94.     def get_type(self):
  95.         return self.type
  96.  
  97.     #for targets affs mostly
  98.     def set(self, state):
  99.         self.on = state
  100.  
  101. #defence structure
  102. class Defence:
  103.     def __init__(self, name, default_state=False):
  104.         self.name = name
  105.         self.on = default_state
  106.         self.waiting = 0
  107.         self.delay_start = 0
  108.  
  109.     def has(self):
  110.         return (self.on == 1)
  111.  
  112.     def delay(self, now):
  113.         self.delay_start = now
  114.  
  115.     def is_delayed(self):
  116.         return (self.delay_start > 0)
  117.  
  118.     def pending(self):
  119.         self.on = 0.5
  120.  
  121.     def is_pending(self):
  122.         return (self.on == 0.5)
  123.  
  124.     def gained(self):
  125.         if self.on == 1:
  126.             return
  127.         self.on = 1
  128.         self.delay_start = 0
  129.  
  130.     def lost(self):
  131.         if self.on < 1:
  132.             return
  133.         self.on = 0
  134.  
  135. #structure to hold data about a single individual
  136. class TrackData:
  137.     def __init__(self, who):
  138.         self.name = who.title()
  139.         self.affs = new_aff_dict()
  140.         self.defs = new_defence_dict()
  141.         self.health_percent = 100
  142.         self.mana_percent = 100
  143.         self.last_eat = 0
  144.         self.last_tree = 0
  145.         self.last_purge = 0
  146.         self.last_elixir = 0
  147.         self.last_apply = 0
  148.         self.salve_timer = 0
  149.         self.potential_affs = []
  150.         self.potential_cures = []
  151.         self.prof = None
  152.         self.limbs = {
  153.             "head" : Limb("head"),
  154.             "torso" : Limb("torso"),
  155.             "left_arm" : Limb("left arm"),
  156.             "right_arm" : Limb("right arm"),
  157.             "left_leg" : Limb("left leg"),
  158.             "right_leg" : Limb("right leg"),
  159.         }
  160.         self.shadowplant = None
  161.         self.nairat = None
  162.         self.loshre = None
  163.  
  164. #type is like HERB/SMOKE/etc, cure is like maidenhair/kelp/laurel
  165.     def sorted_affs_to_cure(self, type, cure):
  166.         affs = []
  167.         for aff in self.affs.values():
  168.             if aff.has():
  169.                 if (not type or aff.type == type) and (not cure or aff.cure == cure):
  170.                     affs.append(aff)
  171.         return sorted(affs, key=lambda aff: aff.priority)
  172.  
  173.     #this is where you'd check for shadowplant hits, nairat, etc
  174.     def verify_cures(self):
  175.         for cure in self.potential_cures:
  176.             self.set_aff(cure, False)
  177.         self.print_status()
  178.  
  179.     #helper function
  180.     def cure_blocker(self):
  181.         if self.nairat or self.shadowplant or self.loshre or self.prof == "assassin" or self.prof == "renegade":
  182.             return True
  183.  
  184.     #you'd call this on the prompt, do your shrug/rebounding/whatever verification here
  185.     def verify_affs(self):
  186.         for aff in self.potential_affs:
  187.             self.set_aff(aff, True)
  188.  
  189.     def aff_count(self):
  190.         return len([aff for aff in self.affs if self.affs[aff].has()])
  191.  
  192.     def applied(self, bal):
  193.         self.salve_timer = bal
  194.         self.last_apply = time.time()
  195.  
  196.     def cant_tree(self):
  197.         if self.affs["paresis"].has() or self.affs["paralysis"].has() or (time.time() - self.last_tree < TREE_BAL):
  198.             return True
  199.         return False
  200.  
  201.     def cant_purge(self):
  202.         if self.affs["hemotoxin"].has() or self.affs["disrupted"].has() or time.time() - self.last_purge < 15:
  203.             return True
  204.         return False
  205.  
  206.     def off_herb_bal_for(self, amt):
  207.         if self.last_eat == 0:
  208.             return 0
  209.         period = time.time() - self.last_eat
  210.         if period > 2.0:
  211.             return 0
  212.         period = 2 - period
  213.         if period >= amt:
  214.             return True
  215.         return False
  216.  
  217.     def off_salve_bal(self):
  218.         if self.salve_timer == 0:
  219.             return False
  220.         now = time.time()
  221.         if now - self.last_apply > self.salve_timer:
  222.             return False
  223.         return True
  224.  
  225.     def print_status(self):
  226.         target = world.GetVariable("target")
  227.         if target is None:
  228.             return
  229.         target = target.title()
  230.         if self.name != target:
  231.             return
  232.         afflictions = []
  233.         for aff in self.affs:
  234.             if self.affs[aff].has():
  235.                 afflictions.append(aff)
  236.         defences = []
  237.         for defence in self.defs:
  238.             if self.defs[defence].has():
  239.                 defences.append(defence)
  240.         alert(self.name + ":")
  241.         alert("<Affs>: " + ", ".join(afflictions))
  242.         alert("<Defs>: " + ", ".join(defences))
  243.  
  244.     #afflictions to seal a truelock
  245.     def affs_to_seal_lock(self, ignore_confuse, ignore_disrupt):
  246.         lock = []
  247.         if not self.affs["asthma"].has():
  248.             lock.append("asthma")
  249.         if not self.affs["impatience"].has():
  250.             lock.append("impatience")
  251.         if not self.affs["anorexia"].has():
  252.             lock.append("anorexia")
  253.         if not self.affs["slickness"].has():
  254.             lock.append("slickness")
  255.         if not self.affs["numbness"].has() and not self.affs["paralysis"].has():
  256.             lock.append("numbness")
  257.         if not ignore_confuse and not self.affs["confusion"].has():
  258.             lock.append("confusion")
  259.         if not ignore_disrupt and not self.affs["disrupted"].has():
  260.             lock.append("disrupted")
  261.         return lock
  262.  
  263.     #are they locked?
  264.     def truelocked(self, confused, disrupted):
  265.         locked = (self.affs["asthma"].has() and self.affs["slickness"].has() and self.affs["impatience"].has() and self.affs["anorexia"].has() and (self.affs["numbness"].has() or self.affs["paralysis"].has()))
  266.         if not locked:
  267.             return False
  268.         if locked and (not disrupted or self.affs["disrupted"].has()) and (not confused or self.affs["confusion"].has()):
  269.             return True
  270.         return False
  271.  
  272.     def has_aff(self, aff):
  273.         aff = normalise_aff(aff)
  274.         if not self.affs.has_key(aff):
  275.             alert("Unknown aff in has_aff: " + aff)
  276.             return
  277.         return self.affs[aff].has()
  278.  
  279.     def has_def(self, defence):
  280.         defence = normalise_aff(defence)
  281.         if not self.defs.has_key(defence):
  282.             alert("Unknown defence " + defence + " in has_def")
  283.             return
  284.         return self.defs[defence].has()
  285.  
  286.     def reset_affs(self):
  287.         self.affs = new_aff_dict()
  288.         alert("Reset afflictions for " + self.name)
  289.  
  290.     def set_aff(self, aff, state=True):
  291.         aff = normalise_aff(aff)
  292.         if not self.affs.has_key(aff):
  293.             alert(self.name + " received unknown aff " + aff + ". Needs adding to new_aff_dict()")
  294.             return
  295.         if aff == "sensitivity" and self.defs["deafness"].has():
  296.             self.set_def("deafness", False)
  297.             return
  298.         old_val = self.affs[aff].on
  299.         self.affs[aff].set(state)
  300.         if old_val == state:
  301.             return
  302.         self.print_status()
  303.  
  304.     def set_def(self, defence, state=True):
  305.         defence = normalise_aff(defence)
  306.         if not self.defs.has_key(defence):
  307.             alert(self.name + " tried to handle defence " + defence + ". Needs adding to new_defence_dict()")
  308.             return
  309.         if self.defs[defence] != state:
  310.             self.defs[defence] = state
  311.             self.print_status()
  312.  
  313.     def reset_defs(self):
  314.         self.defs = new_defence_dict()
  315.         alert("Reset defences for " + self.name + ".")
  316.  
  317.     def limb_damage(self, limb, damage):
  318.         if not self.limbs.has_key(limb):
  319.             alert("Tried to damage the " + limb + " of " + self.name + ", but he doesn't appear to have one!")
  320.             return
  321.         self.limbs[limb].damage(damage)
  322.  
  323.     def limb_cure(self, limb, amount):
  324.         if not self.limbs.has_key(limb):
  325.             alert("Tried to cure the %s of %s, but he doesn't have one. Poor guy." % (limb, self.name))
  326.             return
  327.         self.limbs[limb].heal(amt)
  328.  
  329.     def print_limbs(self, raw=False):
  330.         alert("Limbs of " + self.name + ":")
  331.         for limb in self.limbs:
  332.             alert("%s: %s" % (limb, self.limbs[limb].get_damage()))
  333.  
  334.     def reset(self):
  335.         self.affs = new_aff_dict()
  336.         self.defs = new_defence_dict()
  337.         self.health_percent = 100
  338.         self.mana_percent = 100
  339.         self.last_tree = 0
  340.         self.last_eat = 0
  341.         self.last_elixir = 0
  342.         self.last_apply = 0
  343.         self.last_purge = 0
  344.         alert("Reset tracking for " + self.name + ".")
  345.         for l in self.limbs:
  346.             self.limbs[l].healed()
  347.  
  348. def new_defence_dict():
  349.     return {
  350.     "fitness" : Defence("fitness", True),
  351.     "deafness" : Defence("deafness", True),
  352.     "fangbarrier" : Defence("fangbarrier", True),
  353.     "rebounding" : Defence("rebounding", True),
  354.     "shielded" : Defence("shielded"),
  355.     "speed" : Defence("speed", True),
  356.         "insulation" : Defence("caloric", True),
  357.     "insomnia" : Defence("insomnia", True),
  358.     }
  359.  
  360. # priority is how important the aff is.
  361. # lower priorities are cured first
  362. #i.e. in the example below, someone eats maidenhair, numbness will be cleared from the tracker before paralysis
  363. def new_aff_dict():
  364.     return {
  365.         "paralysis" : Affliction("paralysis", HERB, "maidenhair", 6, PURGEABLE),
  366.         "numbness" : Affliction("numbness", HERB, "maidenhair", 5, PURGEABLE),
  367.         "stupidity" : Affliction("stupidity", HERB, "orphine", 0, TREEABLE | FOCUSABLE | PURGEABLE),
  368.         "anorexia" : Affliction("anorexia", SALVE, "epidermal to body", 0, FOCUSABLE | PURGEABLE),
  369.         "penance" : Affliction("penance", SMOKE, "laurel", 0, TREEABLE),
  370.     }
  371.  
  372. #where all tracking data is stored
  373. tracker = {}
  374.  
  375. #keep affs in a consistent format
  376. def normalise_aff(aff):
  377.     return aff.replace(" ", "_")
  378.  
  379. #give a person an aff
  380. def person_aff(who, aff, state=True):
  381.     who = who.lower().strip()
  382.     new_tracker_entry(who)
  383.     tracker[who].set_aff(who, state)
  384.  
  385. def new_tracker_entry(who):
  386.     who = who.lower().strip()
  387.     if tracker.has_key(who):
  388.         return
  389.     tracker[who] = TrackData(who)
  390.     alert("<Tracker>: Created new entry for " + who.title())
  391.  
  392. # there's some redundant code here since we check they have the affs already in the sorting process
  393. # But I'm pretty sure I had it here for a reason.
  394. def person_ate(target, herb):
  395.     target = target.lower().strip()
  396.     new_tracker_entry(target)
  397.     tracker[target].last_eat = time.time()
  398.     order = tracker[target].sorted_affs_to_cure(HERB, herb)
  399.     for aff in order:
  400.         tracker[target].set_aff(aff.name, False)
  401.         return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement