156
|
1 ## a vs die roller as used by WOD games
|
|
2 #!/usr/bin/env python
|
|
3 # Copyright (C) 2000-2001 The OpenRPG Project
|
|
4 #
|
|
5 # openrpg-dev@lists.sourceforge.net
|
|
6 #
|
|
7 # This program is free software; you can redistribute it and/or modify
|
|
8 # it under the terms of the GNU General Public License as published by
|
|
9 # the Free Software Foundation; either version 2 of the License, or
|
|
10 # (at your option) any later version.
|
|
11 #
|
|
12 # This program is distributed in the hope that it will be useful,
|
|
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 # GNU General Public License for more details.
|
|
16 #
|
|
17 # You should have received a copy of the GNU General Public License
|
|
18 # along with this program; if not, write to the Free Software
|
|
19 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
20 # --
|
|
21 #
|
|
22 # File: sr4.py
|
|
23 # Author: Veggiesama, ripped straight from Michael Edwards (AKA akoman)
|
|
24 # Maintainer:
|
|
25 # Version: 1.1
|
|
26 #
|
|
27 # 1.1: Now with glitch and critical glitch detection!
|
|
28 # 1.1: Cleaned up some of the output to make it simpler.
|
|
29 #
|
|
30 # Description: Modified from the original Shadowrun dieroller by akoman,
|
|
31 # but altered to follow the new Shadowrun 4th Ed dice system.
|
|
32 #
|
|
33 # SR4 VS
|
|
34 # Typing [Xd6.vs(Y)] will roll X dice, checking each die
|
|
35 # roll against the MIN_TARGET_NUMBER (default: 5). If it
|
|
36 # meets or beats it, it counts as a hit. If the total hits
|
|
37 # meet or beat the Y value (threshold), there's a success.
|
|
38 #
|
|
39 # SR4 EDGE VS
|
|
40 # Identical to the above function, except it looks like
|
|
41 # [Xd6.edge(Y)] and follows the "Rule of Six". That rule
|
|
42 # states any roll of 6 is counted as a hit and rerolled
|
|
43 # with a potential to score more hits. The "Edge" bonus
|
|
44 # dice must be included into X.
|
|
45 #
|
|
46 # SR4 INIT
|
|
47 # Typing [Xd6.init(Y)] will roll X dice, checking each
|
|
48 # die for a hit. All hits are added to Y (the init attrib
|
|
49 # of the player), to give an Init Score for the combat.
|
|
50 #
|
|
51 # SR4 EDGE INIT
|
|
52 # Typing [Xd6.initedge(Y)] or [Xd6.edgeinit(Y)] will do
|
|
53 # as above, except adding the possibility of Edge dice.
|
|
54 #
|
|
55 # Note about non-traditional uses:
|
|
56 # - D6's are not required. This script will work with any
|
|
57 # die possible, and the "Rule of Six" will only trigger
|
|
58 # on the highest die roll possible. Not throughly tested.
|
|
59 # - If you want to alter the minimum target number (ex.
|
|
60 # score a hit on a 4, 5, or 6), scroll down and change
|
|
61 # the global value MIN_TARGET_NUMBER to your liking.
|
|
62
|
|
63 from die import *
|
|
64
|
|
65 __version__ = "1.1"
|
|
66
|
|
67 MIN_TARGET_NUMBER = 5
|
|
68 GLITCH_NUMBER = 1
|
|
69
|
|
70 class sr4(std):
|
|
71
|
|
72 def __init__(self,source=[]):
|
|
73 std.__init__(self,source)
|
|
74 self.threshold = None
|
|
75 self.init_attrib = None
|
|
76
|
|
77
|
|
78 def vs(self,threshold=0):
|
|
79 return sr4vs(self, threshold)
|
|
80
|
|
81
|
|
82 def edge(self,threshold=0):
|
|
83 return sr4vs(self, threshold, 1)
|
|
84
|
|
85
|
|
86 def init(self,init_attrib=0):
|
|
87 return sr4init(self, init_attrib)
|
|
88
|
|
89
|
|
90 def initedge(self,init_attrib=0):
|
|
91 return sr4init(self, init_attrib, 1)
|
|
92
|
|
93 def edgeinit(self,init_attrib=0):
|
|
94 return sr4init(self, init_attrib, 1)
|
|
95
|
|
96
|
|
97 def countEdge(self,num):
|
|
98 if num <= 1:
|
|
99 self
|
|
100 done = 1
|
|
101 for i in range(len(self.data)):
|
|
102 if (self.data[i].lastroll() >= num):
|
|
103 # counts every rerolled 6 as a hit
|
|
104 self.hits += 1
|
|
105 self.data[i].extraroll()
|
|
106 self.total += 1
|
|
107 done = 0
|
|
108 elif (self.data[i].lastroll() <= GLITCH_NUMBER):
|
|
109 self.ones += 1
|
|
110 self.total += 1
|
|
111 if done:
|
|
112 return self
|
|
113 else:
|
|
114 return self.countEdge(num)
|
|
115
|
|
116
|
|
117 def countHits(self,num):
|
|
118 for i in range(len(self.data)):
|
|
119 if (self.data[i].lastroll() >= MIN_TARGET_NUMBER):
|
|
120 # (Rule of Six taken into account in countEdge(), not here)
|
|
121 self.hits += 1
|
|
122 elif (self.data[i].lastroll() <= GLITCH_NUMBER):
|
|
123 self.ones += 1
|
|
124 self.total += 1
|
|
125
|
|
126
|
|
127 def __str__(self):
|
|
128 if len(self.data) > 0:
|
|
129 self.hits = 0
|
|
130 self.ones = 0
|
|
131 self.total = 0
|
|
132 for i in range(len(self.data)):
|
|
133 if (self.data[i].lastroll() >= MIN_TARGET_NUMBER):
|
|
134 self.hits += 1
|
|
135 elif (self.data[i].lastroll() <= GLITCH_NUMBER):
|
|
136 self.ones += 1
|
|
137 self.total += 1
|
|
138 firstpass = 0
|
|
139 myStr = "["
|
|
140 for a in self.data[0:]:
|
|
141 if firstpass != 0:
|
|
142 myStr += ","
|
|
143 firstpass = 1
|
|
144 if a >= MIN_TARGET_NUMBER:
|
|
145 myStr += "<B>" + str(a) + "</B>"
|
|
146 elif a <= GLITCH_NUMBER:
|
|
147 myStr += "<i>" + str(a) + "</i>"
|
|
148 else:
|
|
149 myStr += str(a)
|
|
150 myStr += "] " + CheckIfGlitch(self.ones, self.hits, self.total)
|
|
151 myStr += "Hits: (" + str(self.hits) + ")"
|
|
152 else:
|
|
153 myStr = "[] = (0)"
|
|
154 return myStr
|
|
155
|
|
156 class sr4init(sr4):
|
|
157
|
|
158 def __init__(self,source=[],init_attrib=1,edge=0):
|
|
159 std.__init__(self,source)
|
|
160 if init_attrib < 2:
|
|
161 self.init_attrib = 2
|
|
162 else:
|
|
163 self.init_attrib = init_attrib
|
|
164 self.dicesides = self[0].sides
|
|
165 self.hits = 0
|
|
166 self.ones = 0
|
|
167 self.total = 0
|
|
168 if edge:
|
|
169 self.countEdge(self.dicesides)
|
|
170 self.countHits(self.dicesides)
|
|
171
|
|
172
|
|
173 def __str__(self):
|
|
174 if len(self.data) > 0:
|
|
175 firstpass = 0
|
|
176 myStr = "["
|
|
177 for a in self.data[0:]:
|
|
178 if firstpass != 0:
|
|
179 myStr += ","
|
|
180 firstpass = 1
|
|
181 if a >= MIN_TARGET_NUMBER:
|
|
182 myStr += "<B>" + str(a) + "</B>"
|
|
183 elif a <= GLITCH_NUMBER:
|
|
184 myStr += "<i>" + str(a) + "</i>"
|
|
185 else:
|
|
186 myStr += str(a)
|
|
187 myStr += "] " + CheckIfGlitch(self.ones, self.hits, self.total)
|
|
188 init_score = str(self.init_attrib + self.hits)
|
|
189 myStr += "InitScore: " + str(self.init_attrib) + "+"
|
|
190 myStr += str(self.hits) + " = (" + init_score + ")"
|
|
191 else:
|
|
192 myStr = "[] = (0)"
|
|
193 return myStr
|
|
194
|
|
195 class sr4vs(sr4):
|
|
196
|
|
197 def __init__(self,source=[], threshold=1, edge=0):
|
|
198 std.__init__(self, source)
|
|
199 if threshold < 0:
|
|
200 self.threshold = 0
|
|
201 else:
|
|
202 self.threshold = threshold
|
|
203 self.dicesides = self[0].sides
|
|
204 self.hits = 0
|
|
205 self.ones = 0
|
|
206 self.total = 0
|
|
207 if edge:
|
|
208 self.countEdge(self.dicesides)
|
|
209 self.countHits(self.dicesides)
|
|
210
|
|
211
|
|
212 def __str__(self):
|
|
213 if len(self.data) > 0:
|
|
214 firstpass = 0
|
|
215 myStr = "["
|
|
216 for a in self.data[0:]:
|
|
217 if firstpass != 0:
|
|
218 myStr += ","
|
|
219 firstpass = 1
|
|
220 if a >= MIN_TARGET_NUMBER:
|
|
221 myStr += "<B>" + str(a) + "</B>"
|
|
222 elif a <= GLITCH_NUMBER:
|
|
223 myStr += "<i>" + str(a) + "</i>"
|
|
224 else:
|
|
225 myStr += str(a)
|
|
226 #myStr += "] Threshold=" + str(self.threshold)
|
|
227 myStr += "] vs " + str(self.threshold) + " "
|
|
228 myStr += CheckIfGlitch(self.ones, self.hits, self.total)
|
|
229 if self.hits >= self.threshold:
|
|
230 myStr += "*SUCCESS* "
|
|
231 else:
|
|
232 myStr += "*FAILURE* "
|
|
233 myStr += "Hits: (" + str(self.hits) + ")"
|
|
234 else:
|
|
235 myStr = "[] = (0)"
|
|
236 return myStr
|
|
237
|
|
238
|
|
239 def CheckIfGlitch(ones, hits, total_dice):
|
|
240 if (ones * 2) >= total_dice:
|
|
241 if hits >= 1:
|
|
242 return "*GLITCH* "
|
|
243 else:
|
|
244 return "*CRITICAL GLITCH* "
|
|
245 else:
|
|
246 return ""
|