156
|
1 #!/usr/bin/env python
|
|
2 # Copyright Not Yet, see how much I trust you
|
|
3 #
|
|
4 # openrpg-dev@lists.sourceforge.net
|
|
5 #
|
|
6 # This program is free software; you can redistribute it and/or modify
|
|
7 # it under the terms of the GNU General Public License as published by
|
|
8 # the Free Software Foundation; either version 2 of the License, or
|
|
9 # (at your option) any later version.
|
|
10 #
|
|
11 # This program is distributed in the hope that it will be useful,
|
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 # GNU General Public License for more details.
|
|
15 #
|
|
16 # You should have received a copy of the GNU General Public License
|
|
17 # along with this program; if not, write to the Free Software
|
|
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
19 # --
|
|
20 #
|
|
21 # File: hackmaster.py
|
|
22 # Author: Ric Soard
|
|
23 # Maintainer:
|
|
24 # Version:
|
|
25 # $Id: hackmaster.py,v 0.4 2003/08/12
|
|
26 #
|
|
27 # Description: special die roller for HackMaster(C)(TM) RPG
|
|
28 # has penetration damage - .damage(bonus,honor)
|
|
29 # has attack - .attack(bonus, honor)
|
|
30 # has severity .severity(honor)
|
|
31 # has help - .help()
|
|
32 #
|
|
33 #
|
|
34 import random
|
|
35 from die import *
|
|
36
|
|
37 __version__ = "$Id: hackmaster.py,v 1.8 2006/11/15 12:11:22 digitalxero Exp $"
|
|
38
|
|
39 #hackmaster Class basically passes into functional classes
|
|
40 class hackmaster(std):
|
|
41
|
|
42 def __init__(self,source=[]):
|
|
43 std.__init__(self,source)
|
|
44
|
|
45
|
|
46 def damage(self, mod, hon):
|
|
47 return HMdamage(self, mod, hon)
|
|
48
|
|
49
|
|
50 def attack(self, mod, hon):
|
|
51 return HMattack(self, mod, hon)
|
|
52
|
|
53
|
|
54 def help(self):
|
|
55 return HMhelp(self)
|
|
56
|
|
57
|
|
58 def severity(self, honor):
|
|
59 return HMSeverity(self, honor)
|
|
60
|
|
61
|
|
62 # HM Damage roller - rolles penetration as per the PHB - re-rolles on max die - 1, adds honor to the penetration rolls
|
|
63 # and this appears to be invisible to the user ( if a 4 on a d4 is rolled a 3 will appear and be followed by another
|
|
64 # die. if High honor then a 4 will appear followed by a another die.
|
|
65 class HMdamage(std):
|
|
66
|
|
67 def __init__(self,source=[], mod = 0, hon = 0):
|
|
68 std.__init__(self,source)
|
|
69 self.mod = mod
|
|
70 self.hon = hon
|
|
71 self.check_pen()
|
|
72 #here we roll the mod die
|
|
73 self.append(static_di(self.mod))
|
|
74 #here we roll the honor die
|
|
75 self.append(static_di(self.hon))
|
|
76
|
|
77
|
|
78 def damage(mod = 0, hon = 0):
|
|
79 self.mod = mod
|
|
80 self.hon = hon
|
|
81
|
|
82 # This function is called by default to display the die string to the chat window.
|
|
83 # Our die string attempts to explain the results
|
|
84
|
|
85 def __str__(self):
|
|
86 myStr = "Damage "
|
|
87 myStr += "[Damage Roll, Modifiers, Honor]: " + " [" + str(self.data[0])
|
|
88 for a in self.data[1:]:
|
|
89 myStr += ","
|
|
90 myStr += str(a)
|
|
91 myStr += "] = (" + str(self.sum()) + ")"
|
|
92
|
|
93 return myStr
|
|
94
|
|
95 # This function checks to see if we need to reroll for penetration
|
|
96
|
|
97 def check_pen(self):
|
|
98 for i in range(len(self.data)):
|
|
99 if self.data[i].lastroll() >= self.data[i].sides:
|
|
100 self.pen_roll(i)
|
|
101
|
|
102 #this function rolls the penetration die, and checks to see if it needs to be re-rolled again.
|
|
103
|
|
104 def pen_roll(self,num):
|
|
105 result = int(random.uniform(1,self.data[num].sides+1))
|
|
106 self.data[num].value += (result - 1 + self.hon)
|
|
107 self.data[num].history.append(result - 1 + self.hon)
|
|
108 if result >= self.data[num].sides:
|
|
109 self.pen_roll(num)
|
|
110
|
|
111 # this function rolls for the HM Attack. the function checks for a 20 and displays critical, and a 1
|
|
112 # and displays fumble
|
|
113 class HMattack(std):
|
|
114
|
|
115 def __init__(self, source=[], mod = 0, base_severity = 0, hon = 0, size = 0):
|
|
116 std.__init__(self,source)
|
|
117 self.size = size
|
|
118 self.mod = mod
|
|
119 self.base_severity = base_severity
|
|
120 self.hon = hon
|
|
121 self.fumble = 0
|
|
122 self.crit = 0
|
|
123 self.check_crit()
|
|
124 #this is a static die that adds the modifier
|
|
125 self.append(static_di(self.mod))
|
|
126 #this is a static die that adds honor, we want high rolls so it's +1
|
|
127 self.append(static_di(self.hon))
|
|
128
|
|
129
|
|
130
|
|
131 def check_crit(self):
|
|
132 if self.data[0] == self.data[0].sides:
|
|
133 self.crit = 1
|
|
134 if self.data[0] == 1:
|
|
135 self.fumble = 1
|
|
136
|
|
137
|
|
138 #this function is the out put to the chat window, it basicaly just displays the roll unless
|
|
139 #it's a natural 20, or a natural 1
|
|
140
|
|
141 def __str__(self):
|
|
142 if self.crit > 0:
|
|
143 myStr = "Critical Hit!!: "
|
|
144 elif self.fumble > 0:
|
|
145 myStr = "FUMBLE!!"
|
|
146 else:
|
|
147 myStr = "To Hit:"
|
|
148 myStr += "[To Hit Roll, Modifiers, Honor]" + " [" + str(self.data[0])
|
|
149 for a in self.data[1:]:
|
|
150 myStr += ","
|
|
151 myStr += str(a)
|
|
152 myStr += "] = (" + str(self.sum()) + ")"
|
|
153 return myStr
|
|
154
|
|
155 class HMhelp(std):
|
|
156
|
|
157 def __init__(self,source=[]):
|
|
158 std.__init__(self,source)
|
|
159 self.source = source
|
|
160
|
|
161
|
|
162 def __str__(self):
|
|
163 myStr = " <br /> .attack(Bonus, Honor): <br />"
|
|
164 myStr += " The attack roll rolles the dice and adds your bonus <br />"
|
|
165 myStr += " and honor modifier and returns you final roll. <br />"
|
|
166 myStr += " On a natural 20 the dieroller displays Critical Hit!! <br />"
|
|
167 myStr += " On a natural 1 the dieroller displays FUMBLE!! <br />"
|
|
168 myStr += " Example A 1st level fighter with +1 to hit and a +2 sword and High Honor <br />"
|
|
169 myStr += " would roll [1d20.attack(3,1)] <br />"
|
|
170 myStr += " .damage(Bonus, Honor): <br />"
|
|
171 myStr += " The damage roll rolls the dice and rerolls on a max roll for <br />"
|
|
172 myStr += " penetration damage, the penetration die is -1 and is rerolled on a max roll <br />"
|
|
173 myStr += " The roller returns the damage dice, monidifiers, and honor <br />"
|
|
174 myStr += " Example A magic-user uses a quaterstaff +1 with high honor, he would roll <br />"
|
|
175 myStr += " [1d6.damage(1,1)] <br />"
|
|
176 myStr += " .severity(honor): <br />"
|
|
177 myStr += " the severity is for critical hit resolution - the character rolls <br />"
|
|
178 myStr += " a d8 and adds honor bonus. the die is rerolled on natural 8 and natural 1 with a -1 modifier <br />"
|
|
179 myStr += " on an 8 the reroll is added on a 1 the reroll is subtracted <br />"
|
|
180 myStr += " Example [1d8.severity(1)] <br />"
|
|
181 myStr += " .help() : <br />"
|
|
182 myStr += " displays this message <br />"
|
|
183
|
|
184 return myStr
|
|
185
|
|
186 # the severity roll is for critical resolution. The die is rerolled and added
|
|
187 #on a natural 8 and rerolled and subtracted on a 1
|
|
188 class HMSeverity(std):
|
|
189
|
|
190 def __init__(self, source =[], honor=0):
|
|
191 std.__init__(self,source)
|
|
192 self.source = source
|
|
193 self.hon = honor
|
|
194 self.data = []
|
|
195 self.append(di(8))
|
|
196 self.CheckReroll()
|
|
197 self.append(static_di(self.hon))
|
|
198
|
|
199
|
|
200
|
|
201 def __str__(self):
|
|
202 myStr = "[Severity Dice, Honor]" + " [" + str(self.data[0])
|
|
203 for a in self.data[1:]:
|
|
204 myStr += ","
|
|
205 myStr += str(a)
|
|
206 myStr += "] = (" + str(self.sum()) + ")"
|
|
207 return myStr
|
|
208
|
|
209
|
|
210 def CheckReroll(self):
|
|
211 if self.data[0] == self.data[0].sides:
|
|
212 self.crit_chain(0,1)
|
|
213 if self.data[0] == 1:
|
|
214 self.crit_chain(0,-1)
|
|
215
|
|
216 #this function needes moved for severity
|
|
217
|
|
218 def crit_chain(self,num,neg):
|
|
219 result = int(random.uniform(1,self.data[num].sides+1))
|
|
220 self.data[num].value += (((result - 1) * neg) + self.hon)
|
|
221 self.data[num].history.append(((result - 1) * neg) + self.hon)
|
|
222 if result >= self.data[num].sides:
|
|
223 self.crit_chain(num,1)
|
|
224 if result == 1:
|
|
225 self.crit_chain(num,-1)
|