171
|
1 # (at your option) any later version.
|
|
2 #
|
|
3 # This program is distributed in the hope that it will be useful,
|
|
4 # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
5 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
6 # GNU General Public License for more details.
|
|
7 #
|
|
8 # You should have received a copy of the GNU General Public License
|
|
9 # along with this program; if not, write to the Free Software
|
|
10 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
11 # --
|
|
12 #
|
|
13 # File: Alternity.py
|
|
14 # Version:
|
|
15 # $Id: Alternity.py,v .1 JEC (cchriss@thecastle.com)
|
|
16 #
|
|
17 # Description: Alternity die roller based on Posterboy's D20 Dieroller
|
|
18 #
|
|
19 # Changelog:
|
|
20 #
|
187
|
21 # v.1 original release JEC
|
|
22 #
|
|
23 # Traipse Release:
|
|
24 # The changes made in the Traipe release are intended to create a more direct connection
|
|
25 # between the source and the intrepretor. IF, ELIF statements have been replaced with dictionaries,
|
171
|
26 # unused objects have been replace with re-usable objects, and the code has been condensed.
|
187
|
27 #
|
|
28 # SEG: JAN 21 2010 - v.1.2 O'Flux Release:
|
|
29 # Edits & Additions: fixed a few minor bugs; Damage roll & Display Issues.
|
|
30 # Added Secondary Damage Calculation and Display. Fix all errors.
|
|
31 # Tested for Traipse on Win 7
|
|
32 #
|
|
33 # Skill Check Example:
|
|
34 # [1d20.sk(12,-2)]
|
|
35 # OUTPUT Example:
|
|
36 # => [6,-3] = (3) AMAZING Success
|
|
37 #
|
|
38 # Pistol, Laser; 0 step -- Attack Example:
|
|
39 # [1d20.at(12,0,(1d4+1,"w"),(1d6+1,"w"),(1d4,"m"))]
|
|
40 # OUTPUT Example:
|
|
41 # => [1,0] = (1) CRITICAL SUCCESS AMAZING HIT
|
|
42 # ===> Damage [4] = (4) mortal ======> Secondary Damage (2) stun / (2) wound
|
|
43 #
|
|
44 # Action Check Example:
|
|
45 # [1d20.ac(14,-1)]
|
|
46 # OUTPUT Example:
|
|
47 # => ACTION CHECK : [18,-3] = (15) Marginal failure
|
|
48 # -1 Step make up bonus next Action Check
|
|
49 #
|
|
50 #
|
171
|
51
|
|
52 import re
|
187
|
53
|
171
|
54 from std import std
|
|
55 from time import time, clock
|
|
56 from orpg.dieroller.base import di, die_base, die_rollers
|
|
57
|
187
|
58 ## from orpg.tools.orpg_log import debug
|
|
59
|
|
60
|
|
61 __version__ = "$Id: alternity.py,v 0.1 2003/01/02 12:00:00 cchriss Exp $"
|
171
|
62
|
|
63 # Alternity stands for "Alternity system" 20 sided die plus mods
|
|
64
|
|
65 class alternity(std):
|
|
66 name = "alternity" # ADDED by SEG Nov 2009 ***
|
|
67
|
|
68 def __init__(self,source=[]):
|
|
69 std.__init__(self,source)
|
|
70
|
187
|
71 # these methods return new die objects for specific options
|
171
|
72 def sk(self,score,mod):
|
|
73 return sk(self,score,mod)
|
|
74
|
|
75 def at(self,score,mod,dmgo,dmgg,dmga):
|
|
76 return at(self,score,mod,dmgo,dmgg,dmga)
|
|
77
|
187
|
78 def ac(self,score,mod):
|
|
79 return ac(self,score,mod)
|
|
80
|
171
|
81 die_rollers.register(alternity)
|
|
82
|
|
83 class sk(std):
|
|
84 def __init__(self,source=[],sc="10/5/2",mod=0):
|
|
85 std.__init__(self,source)
|
|
86 m = re.match( r"\d+", str(sc) )
|
|
87 self.score = int( m.group(0) )
|
|
88 self.mod = mod
|
|
89
|
|
90 def getMod(self,mod=0):
|
187
|
91 m=0
|
|
92 mods = { -4: -di(12), -3: -di(8), -2: -di(6), -1: -di(4), 1: di(4),
|
|
93 2: di(6), 3: di(8), 4: di(12), 5: di(20)} # SEG fix 1: di(4) #
|
|
94 if mod in mods.keys(): m = mods[mod].value
|
171
|
95 elif mod <= -5: m=-di(20).value
|
|
96 elif mod == 6: m=di(20).value + di(20).value
|
|
97 elif mod >= 7: m=di(20).value + di(20).value + di(20).value
|
|
98 return m
|
|
99
|
|
100 def getRolLStr(self):
|
187
|
101 myStr = "[" + str(self.data[0])
|
171
|
102 self.d20 = self.sum()
|
|
103 amod = self.getMod(self.mod)
|
|
104 self.dieRoll = self.d20 + amod
|
|
105 for a in self.data[1:]:
|
|
106 myStr += ","
|
|
107 myStr += str(a)
|
|
108 myStr += "," + str(amod) + "] = (" + str(self.dieRoll) + ")"
|
187
|
109 ## if ( self.d20 == 1 ): self.success = 'CS' # seg - removed - unneeded ** #
|
171
|
110 if ( self.dieRoll <= self.score / 4 ): self.success = 'A'
|
|
111 elif ( self.dieRoll <= self.score / 2 ): self.success = 'G'
|
|
112 elif ( self.dieRoll <= self.score ): self.success = 'O'
|
|
113 else: self.success = 'F'
|
|
114 if ( self.d20 == 20 ): self.success = 'CF'
|
|
115 return myStr
|
|
116
|
|
117 def __str__(self):
|
187
|
118 myStr = self.getRolLStr()
|
|
119 successes = {'CS': " <b><font color='#00aa00'>CRITICAL SUCCESS</font></b>",
|
|
120 'CF': " <b><font color='#ff0000'>CRITICAL FAILURE</font></b>",
|
|
121 'A': " <b><font color='#00aa00'>AMAZING Success</b>",
|
|
122 'G': " <b>Good Success</b>",
|
|
123 'O': " <b>Ordinary Success</b>",
|
|
124 'F': " <b>failure</b>"}
|
|
125 if ( self.d20 == 1 ): myStr += successes['CS'] # SEG Dec 19 2009
|
171
|
126 myStr += successes[self.success]
|
|
127 return myStr
|
|
128
|
187
|
129 class at(sk):
|
|
130 ## Traipse Usage: The source I received had the damage rolls like this 1d6s, with the damage type a
|
|
131 ## letter that could be sliced from the roll. However, the roll is parsed before the letter can be
|
|
132 ## sliced from it, and with the letter attached it created an error.
|
|
133 ##
|
|
134 ## The Traipse method puts the damage type and the damage roll into a Tuple, ie (1d6, 's').
|
|
135 ## When using this method you must include single or double quoutes around the damage type or the
|
171
|
136 ## software will treat it as an object.
|
187
|
137
|
171
|
138 def __init__(self,source=[],sc=10, mod=0, dmgo="(1d6, 's')",dmgg="(1d6, 'w')",dmga="(1d6, 'm')"):
|
|
139 sk.__init__(self,source,sc,mod)
|
|
140 self.dmgo = dmgo
|
|
141 self.dmgg = dmgg
|
|
142 self.dmga = dmga
|
|
143
|
187
|
144 def getdmg(self,dmgroll):
|
|
145 astr = "<b>===></b> Damage "
|
171
|
146 droll = str(dmgroll[0])
|
187
|
147 xyz = droll.split('(')
|
|
148 secD = (int(xyz[1][:-1])/2) ## SEG* Calculate Secondary Damage
|
|
149 ## debug(secD) ## seg added debug output
|
171
|
150 dtype = dmgroll[1]
|
|
151 astr += droll
|
187
|
152 if dtype=="s": astr += " <b><font size=2 color='#52D017'>stun</font></b><BR>"
|
|
153 elif dtype=="w":
|
|
154 astr += " <b><font size=2 color='#C11B17'>wound</font></b>"+" <b>======></b> Secondary Damage ("+str(secD) \
|
|
155 +") <b><font size=2 color='#52D017'>stun</font></b><BR>" # SEG* Display Secondary Damage
|
|
156 elif dtype=="m":
|
|
157 astr += " <b><font size=2 color='#FF0000'>mortal</font></b>"+" <b>======></b> Secondary Damage ("+str(secD) \
|
|
158 +") <b><font size=2 color='#52D017'>stun</font></b>"+" <b>/</b> ("+str(secD)+") <b><font size=2 color='#C11B17'>wound</font></b><BR>" # SEG* Display Secondary Damage
|
171
|
159 return astr
|
|
160
|
|
161 def __str__(self):
|
187
|
162 myStr = self.getRolLStr()
|
|
163 successes = {'CS': " <b><font size=2 color='#8D38C9'>CRITICAL SUCCESS</font></b>",
|
|
164 'CF': " <b><font size=2 color='#151B54'>CRITICAL FAILURE</font></b>",
|
|
165 'A': " <b><font size=2 color='#E42217'>AMAZING HIT</font></b><BR> ",
|
|
166 'G': " <b><font size=2 color='#306EFF'>Good HIT</font></b><BR> ",
|
|
167 'O': " <b><font size=2 color='#52D017'>Ordinary HIT</font></b><BR> ",
|
|
168 'F': " <b><font size=2 color='#41627E'>miss</font></b>"}
|
|
169 if ( self.d20 == 1 ): myStr += successes['CS'] # SEG Dec 19 2009
|
|
170 myStr += successes[self.success]
|
|
171 if self.success == 'A': myStr += self.getdmg(self.dmga)
|
|
172 elif self.success == 'G': myStr += self.getdmg(self.dmgg)
|
|
173 elif self.success == 'O': myStr += self.getdmg(self.dmgo)
|
171
|
174 return myStr
|
187
|
175
|
|
176 class ac(sk):
|
|
177 def __init__(self,source=[],sc=10,mod=0):
|
|
178 sk.__init__(self,source,sc,mod)
|
|
179
|
|
180 def GetRoLLStr(self):
|
|
181 myStr = "[" + str(self.data[0])
|
|
182 self.d20 = self.sum()
|
|
183 amod = self.getMod(self.mod)
|
|
184 self.dieRoll = self.d20 + amod
|
|
185 for a in self.data[1:]:
|
|
186 myStr += ","
|
|
187 myStr += str(a)
|
|
188 myStr += "," + str(amod) + "] = (" + str(self.dieRoll) + ")"
|
|
189 if ( self.dieRoll <= self.score / 4 ): self.success = 'A'
|
|
190 elif ( self.dieRoll <= self.score / 2 ): self.success = 'G'
|
|
191 elif ( self.dieRoll <= self.score ): self.success = 'O'
|
|
192 else: self.success = 'F'
|
|
193 if ( self.d20 == 20 ): self.success = 'CF'
|
|
194 return myStr
|
|
195
|
|
196 def __str__(self):
|
|
197 myStr = self.GetRoLLStr()
|
|
198 myStr = " <b><font color='#E42217'>ACTION CHECK : </font></b>"+myStr
|
|
199 successes = {'CS': " <b><font color='#00aa00'>CRITICAL SUCCESS</font></b>",
|
|
200 'CF': " <b><font color='#ff0000'>CRITICAL FAILURE</font></b><BR> -2 Step make up bonus next Action Check",
|
|
201 'A': " <b><font color='#00aa00'>AMAZING Success</b>",
|
|
202 'G': " <b>Good Success</b>",
|
|
203 'O': " <b>Ordinary Success</b>",
|
|
204 'F': " <b>Marginal failure</b><BR> -1 Step make up bonus next Action Check"}
|
|
205 if ( self.d20 == 1 ): myStr += successes['CS'] # SEG Dec 19 2009
|
|
206 myStr += successes[self.success]
|
|
207 return myStr
|
|
208
|
|
209
|
|
210
|
|
211
|
|
212
|
|
213
|
|
214
|
|
215
|
|
216
|
|
217
|
|
218
|
|
219
|
|
220
|
|
221
|