171
|
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:
|
184
|
25 # $Id: hackmaster.py,v Traipse 'Ornery-Orc' prof.ebral Exp
|
171
|
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
|
184
|
35 __version__ = "$Id: hackmaster.py,v Traipse 'Ornery-Orc' prof.ebral Exp $"
|
171
|
36
|
|
37 import random
|
|
38 from std import std
|
|
39 from orpg.dieroller.base import *
|
|
40
|
|
41 #hackmaster Class basically passes into functional classes
|
|
42 class hackmaster(std):
|
|
43 name = "hackmaster"
|
|
44
|
|
45 def __init__(self,source=[]):
|
|
46 std.__init__(self,source)
|
|
47
|
|
48 def damage(self, mod, hon):
|
|
49 return HMdamage(self, mod, hon)
|
|
50
|
|
51 def attack(self, mod, hon):
|
|
52 return HMattack(self, mod, hon)
|
|
53
|
|
54 def help(self):
|
|
55 return HMhelp(self)
|
|
56
|
|
57 def severity(self, honor):
|
|
58 return HMSeverity(self, honor)
|
|
59
|
|
60 die_rollers.register(hackmaster)
|
|
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 def __init__(self,source=[], mod = 0, hon = 0):
|
|
67 std.__init__(self,source)
|
|
68 self.mod = mod
|
|
69 self.hon = hon
|
|
70 self.check_pen()
|
|
71 #here we roll the mod die
|
|
72 self.append(static_di(self.mod))
|
|
73 #here we roll the honor die
|
|
74 self.append(static_di(self.hon))
|
|
75
|
|
76 def damage(mod = 0, hon = 0):
|
|
77 self.mod = mod
|
|
78 self.hon = hon
|
|
79
|
|
80 # This function is called by default to display the die string to the chat window.
|
|
81 # Our die string attempts to explain the results
|
|
82 def __str__(self):
|
|
83 myStr = "Damage "
|
|
84 myStr += "[Damage Roll, Modifiers, Honor]: " + " [" + str(self.data[0])
|
|
85 for a in self.data[1:]:
|
|
86 myStr += ","
|
|
87 myStr += str(a)
|
|
88 myStr += "] = (" + str(self.sum()) + ")"
|
|
89
|
|
90 return myStr
|
|
91
|
|
92 # This function checks to see if we need to reroll for penetration
|
|
93 def check_pen(self):
|
|
94 for i in range(len(self.data)):
|
|
95 if self.data[i].lastroll() >= self.data[i].sides:
|
|
96 self.pen_roll(i)
|
|
97
|
|
98 #this function rolls the penetration die, and checks to see if it needs to be re-rolled again.
|
|
99 def pen_roll(self,num):
|
|
100 result = int(random.uniform(1,self.data[num].sides+1))
|
|
101 self.data[num].value += (result - 1 + self.hon)
|
|
102 self.data[num].history.append(result - 1 + self.hon)
|
|
103 if result >= self.data[num].sides:
|
|
104 self.pen_roll(num)
|
|
105
|
|
106 # this function rolls for the HM Attack. the function checks for a 20 and displays critical, and a 1
|
|
107 # and displays fumble
|
|
108 class HMattack(std):
|
|
109 def __init__(self, source=[], mod = 0, base_severity = 0, hon = 0, size = 0):
|
|
110 std.__init__(self,source)
|
|
111 self.size = size
|
|
112 self.mod = mod
|
|
113 self.base_severity = base_severity
|
|
114 self.hon = hon
|
|
115 self.fumble = 0
|
|
116 self.crit = 0
|
|
117 self.check_crit()
|
|
118 #this is a static die that adds the modifier
|
|
119 self.append(static_di(self.mod))
|
|
120 #this is a static die that adds honor, we want high rolls so it's +1
|
|
121 self.append(static_di(self.hon))
|
|
122
|
|
123 def check_crit(self):
|
|
124 if self.data[0] == self.data[0].sides:
|
|
125 self.crit = 1
|
|
126 if self.data[0] == 1:
|
|
127 self.fumble = 1
|
|
128
|
|
129
|
|
130 #this function is the out put to the chat window, it basicaly just displays the roll unless
|
|
131 #it's a natural 20, or a natural 1
|
|
132 def __str__(self):
|
|
133 if self.crit > 0:
|
|
134 myStr = "Critical Hit!!: "
|
|
135 elif self.fumble > 0:
|
|
136 myStr = "FUMBLE!!"
|
|
137 else:
|
|
138 myStr = "To Hit:"
|
|
139 myStr += "[To Hit Roll, Modifiers, Honor]" + " [" + str(self.data[0])
|
|
140 for a in self.data[1:]:
|
|
141 myStr += ","
|
|
142 myStr += str(a)
|
|
143 myStr += "] = (" + str(self.sum()) + ")"
|
|
144 return myStr
|
|
145
|
|
146 class HMhelp(std):
|
|
147 def __init__(self,source=[]):
|
|
148 std.__init__(self,source)
|
|
149 self.source = source
|
|
150
|
|
151 def __str__(self):
|
|
152 myStr = " <br /> .attack(Bonus, Honor): <br />"
|
|
153 myStr += " The attack roll rolles the dice and adds your bonus <br />"
|
|
154 myStr += " and honor modifier and returns you final roll. <br />"
|
|
155 myStr += " On a natural 20 the dieroller displays Critical Hit!! <br />"
|
|
156 myStr += " On a natural 1 the dieroller displays FUMBLE!! <br />"
|
|
157 myStr += " Example A 1st level fighter with +1 to hit and a +2 sword and High Honor <br />"
|
|
158 myStr += " would roll [1d20.attack(3,1)] <br />"
|
|
159 myStr += " .damage(Bonus, Honor): <br />"
|
|
160 myStr += " The damage roll rolls the dice and rerolls on a max roll for <br />"
|
|
161 myStr += " penetration damage, the penetration die is -1 and is rerolled on a max roll <br />"
|
|
162 myStr += " The roller returns the damage dice, monidifiers, and honor <br />"
|
|
163 myStr += " Example A magic-user uses a quaterstaff +1 with high honor, he would roll <br />"
|
|
164 myStr += " [1d6.damage(1,1)] <br />"
|
|
165 myStr += " .severity(honor): <br />"
|
|
166 myStr += " the severity is for critical hit resolution - the character rolls <br />"
|
|
167 myStr += " a d8 and adds honor bonus. the die is rerolled on natural 8 and natural 1 with a -1 modifier <br />"
|
|
168 myStr += " on an 8 the reroll is added on a 1 the reroll is subtracted <br />"
|
|
169 myStr += " Example [1d8.severity(1)] <br />"
|
|
170 myStr += " .help() : <br />"
|
|
171 myStr += " displays this message <br />"
|
|
172 return myStr
|
|
173
|
|
174 # the severity roll is for critical resolution. The die is rerolled and added
|
|
175 #on a natural 8 and rerolled and subtracted on a 1
|
|
176 class HMSeverity(std):
|
|
177 def __init__(self, source =[], honor=0):
|
|
178 std.__init__(self,source)
|
|
179 self.source = source
|
|
180 self.hon = honor
|
|
181 self.data = []
|
|
182 self.append(di(8))
|
|
183 self.CheckReroll()
|
|
184 self.append(static_di(self.hon))
|
|
185
|
|
186 def __str__(self):
|
|
187 myStr = "[Severity Dice, Honor]" + " [" + str(self.data[0])
|
|
188 for a in self.data[1:]:
|
|
189 myStr += ","
|
|
190 myStr += str(a)
|
|
191 myStr += "] = (" + str(self.sum()) + ")"
|
|
192 return myStr
|
|
193
|
|
194 def CheckReroll(self):
|
|
195 if self.data[0] == self.data[0].sides:
|
|
196 self.crit_chain(0,1)
|
|
197 if self.data[0] == 1:
|
|
198 self.crit_chain(0,-1)
|
|
199
|
|
200 #this function needes moved for severity
|
|
201 def crit_chain(self,num,neg):
|
|
202 result = int(random.uniform(1,self.data[num].sides+1))
|
|
203 self.data[num].value += (((result - 1) * neg) + self.hon)
|
|
204 self.data[num].history.append(((result - 1) * neg) + self.hon)
|
184
|
205 if result >= self.data[num].sides: self.crit_chain(num,1)
|
|
206 if result == 1: self.crit_chain(num,-1)
|
|
207
|