Wrote a fix for the Python path detection issue, uses multiple registry sources now
[craw.git] / script / enchant.py
blobf9d9dcc51f4f16221765f741cd149ac1d949f80d
1 import utility, craw, configuration, packets, time, nil.thread, threading, privileges
3 class enchant_handler_class:
4 enchant_skill = 0x0034
6 def __init__(self):
7 self.running = False
8 self.lock = threading.Lock()
10 def perform_mana_check(self, cast_count):
11 self.mana_per_cast = self.enchant_level + 24
12 mana_usage = cast_count * self.mana_per_cast
13 current_mana, maximum_mana = self.mana
14 output = mana_usage <= current_mana
15 if self.mana_per_cast > current_mana:
16 packets.send_chat(configuration.mana_error % self.mana)
17 return False
18 elif mana_usage > current_mana:
19 packets.send_chat(configuration.enchant_mana_lack_warning % self.mana)
20 return True
21 else:
22 return True
24 def perform_party_check(self):
25 is_in_party = utility.same_party(self.player, self.my_player)
26 if not is_in_party:
27 packets.send_chat(configuration.party_error)
28 return is_in_party
30 def distance_check(self):
31 my_coordinates = (self.my_player.x, self.my_player.y)
32 player_coordinates = (self.player.x, self.player.y)
34 distance = utility.distance(my_coordinates, player_coordinates)
36 is_in_range = self.player.x != 0 and distance <= configuration.maximal_enchant_distance
37 if not is_in_range:
38 packets.send_chat(configuration.enchant_range_error)
39 return is_in_range
41 def perform_pre_cast_check(self):
42 if not self.perform_party_check():
43 return False
44 return self.distance_check()
46 def process_command(self, name, message):
47 self.player = utility.get_player_data_by_name(name)
48 self.my_player = utility.get_my_player()
50 if self.player.id == self.my_player.id:
51 return
53 if self.player == None or self.my_player == None:
54 return
56 enchant_level = craw.get_skill_level(enchant_handler_class.enchant_skill)
57 if enchant_level == None:
58 print 'Unable to retrieve the enchant skill level'
59 return
61 if enchant_level == 0:
62 print 'Unable to enchant - this character does not even have this skill!'
63 return
65 self.enchant_level = enchant_level
67 self.mana = craw.get_mana()
68 if self.mana == None:
69 print 'Unable to retrieve mana'
70 return
72 if message == configuration.enchant_command:
73 self.launch_function(self.enchant_player)
75 elif message == configuration.enchant_minions_command:
76 self.launch_function(self.enchant_minions)
78 elif message == configuration.enchant_all_command:
79 self.launch_function(self.enchant_all)
81 elif message == configuration.enchant_players_command:
82 self.launch_function(self.enchant_players)
84 def launch_function(self, function):
85 self.lock.acquire()
86 if self.running:
87 print 'Received an enchant request that was blocked because the thread is still running.'
88 else:
89 self.running = True
90 nil.thread.create_thread(lambda: self.function_wrapper(function))
91 self.lock.release()
93 def thread_termination(self):
94 self.lock.acquire()
95 self.running = False
96 self.lock.release()
98 def function_wrapper(self, function):
99 function()
100 self.thread_termination()
102 def enchant_player(self):
103 if not self.perform_pre_cast_check() or not self.perform_mana_check(1):
104 return False
105 self.enchant(self.player.id, 0)
106 packets.send_chat(configuration.enchant_confirmation % self.mana)
107 return True
109 def get_minions(self):
110 minions = craw.get_minions(self.player.id)
111 if minions == None:
112 print 'Unable to retrieve the minions of player %s' % self.player.name
113 return None
115 minions = filter(lambda minion: not minion.enchanted, minions)
116 return map(lambda minion: (1, minion.id), minions)
118 def process_targets(self, targets):
119 if not self.perform_mana_check(len(targets)):
120 return None
122 targets_enchanted = 0
123 for type, id in targets:
124 if not self.enchant(id, type):
125 break
126 targets_enchanted += 1
128 return targets_enchanted
130 def enchant_minions(self):
131 if not self.perform_pre_cast_check():
132 return False
134 minions = self.get_minions()
135 minions_enchanted = self.process_targets(minions)
136 if minions_enchanted == None:
137 return False
139 current_mana, maximum_mana = self.mana
140 packets.send_chat(configuration.enchant_minions_confirmation % (minions_enchanted, current_mana, maximum_mana))
141 return True
143 def enchant_all(self):
144 if not self.perform_pre_cast_check():
145 return False
147 targets = self.get_minions()
148 if targets == None:
149 print 'Unable to retrieve minions!'
150 targets = []
151 targets = [(0, self.player.id)] + targets
152 targets_enchanted = self.process_targets(targets)
153 if targets_enchanted == None:
154 return False
156 minions_enchanted = targets_enchanted - 1
158 current_mana, maximum_mana = self.mana
159 packets.send_chat(configuration.enchant_all_confirmation % (minions_enchanted, current_mana, maximum_mana))
160 return True
162 def enchant_players(self):
163 players = utility.get_party_players()
164 for player in players:
165 self.player = player
166 if not self.enchant_all():
167 pass
168 return True
170 def process_bytes(self, bytes):
171 self.lock.acquire()
172 running = self.running
173 self.lock.release()
175 if running:
176 return
178 my_name = utility.get_my_name()
179 if my_name not in configuration.enchanters:
180 return
182 self.mana = craw.get_mana()
183 if self.mana == None:
184 print 'Unable to retrieve the mana values'
185 return
187 message = packets.parse_message(bytes)
188 if message != None:
189 name, message = message
190 if privileges.has_remote_privileges(name):
191 self.process_command(name, message)
193 def enchant(self, target, type):
194 packets.set_right_skill(enchant_handler_class.enchant_skill)
195 packets.cast_right_skill_at_target(type, target)
196 current_mana, maximum_mana = self.mana
197 current_mana -= self.mana_per_cast
198 self.mana = (current_mana, maximum_mana)
199 time.sleep(configuration.enchant_delay)
200 return current_mana >= self.mana_per_cast