Mercurial > traipse_dev
comparison orpg/dieroller/rollers/runequest.py @ 167:5c9a118476b2 alpha
Traipse Alpha 'OpenRPG' {091210-00}
Traipse is a distribution of OpenRPG that is designed to be easy to
setup and go. Traipse also makes it easy for developers to work on code
without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy'
and adds fixes to the code. 'Ornery-Orc's main goal is to offer more
advanced features and enhance the productivity of the user.
Update Summary (Keeping up with Beta)
New Features:
Added Bookmarks
Added 'boot' command to remote admin
Added confirmation window for sent nodes
Minor changes to allow for portability to an OpenSUSE linux OS
Miniatures Layer pop up box allows users to turn off Mini labels, from
FlexiRPG
Zoom Mouse plugin added
Images added to Plugin UI
Switching to Element Tree
Map efficiency, from FlexiRPG
Added Status Bar to Update Manager
New TrueDebug Class in orpg_log (See documentation for usage)
Portable Mercurial
Tip of the Day added, from Core and community
New Reference Syntax added for custom PC sheets
New Child Reference for gametree
New Parent Reference for gametree
New Gametree Recursion method, mapping, context sensitivity, and
effeciency..
New Features node with bonus nodes and Node Referencing help added
Dieroller structure from Core
Added 7th Sea die roller method; ie [7k3] =
[7d10.takeHighest(3).open(10)]
New 'Mythos' System die roller added
Added new vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)].
Includes support for Mythos roller
Fixes:
Fix to Text based Server
Fix to Remote Admin Commands
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
Fix to Map from gametree not showing to all clients
Fix to gametree about menus
Fix to Password Manager check on startup
Fix to PC Sheets from tool nodes. They now use the tabber_panel
Fixed Whiteboard ID to prevent random line or text deleting.
Modified ID's to prevent non updated clients from ruining the fix.
default_manifest.xml renamed to default_upmana.xml
Fix to Update Manager; cleaner clode for saved repositories
Fixes made to Settings Panel and no reactive settings when Ok is pressed
Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of
a Splice
author | sirebral |
---|---|
date | Thu, 10 Dec 2009 10:53:33 -0600 |
parents | |
children | dcae32e219f1 |
comparison
equal
deleted
inserted
replaced
166:eef2463cd441 | 167:5c9a118476b2 |
---|---|
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 # | |
14 # Usage: | |
15 # | |
16 # Die Roller: /dieroller rq | |
17 # | |
18 # Skill Roll: [1d100.skill(50,0,0)] # ( skill%, modifer, MA% ) | |
19 # | |
20 # Parry Roll: [1d100.parry(50,0,0,12)] # ( skill%, modifer, MA%, Weapon/Shield AP ) | |
21 # | |
22 # Dodge Roll: [1d100.parry(50,0,0)] # ( skill%, modifer, MA% ) | |
23 # | |
24 # Attack Roll: [1d100.attack(50,0,0,2,9,3,0)] | |
25 # ( skill%, modifer, MA%, min weap dam, max weap dam, dam bonus, truesword ) | |
26 # | |
27 # Sorcery Roll: [1d100.sorcery(90, 0, 3, 6, 1, 1, 1)] | |
28 # (sk, mod, pow, cer, int, acc, mlt) | |
29 # | |
30 # | |
31 # | |
32 # Skill Training Unlimited Roll: [1d100.trainskill(30,75)] # (starting skill%, desired skill%) | |
33 # Skill Training Cost Limited: [1d100.trainskillcost(1000, 50) # (payment, starting skill%) | |
34 # Skill Training Time Limited: [1d100.trainskilltime(150, 50) # (time, strting skill%) | |
35 # | |
36 #------------------------------------------------------------------------- | |
37 # -- | |
38 # | |
39 # File: rq.py | |
40 # Version: | |
41 # $Id: rq.py,v .1 pelwer | |
42 # | |
43 # Description: Runequest die roller originally based on Heroman's Hero Dieroller | |
44 # | |
45 # | |
46 # v.1 - pelwer - 2/5/2005 | |
47 # o Original release | |
48 # v.2 - pelwer - 10/30/2006 | |
49 # o Ported to openrpg+ by removing dependance on whrandom | |
50 # o Fixed Riposte spelling | |
51 # o Deleted sorcalc - never used | |
52 # o Added Sorcery Fumble table to sorcery spell roller | |
53 # | |
54 | |
55 __version__ = "$Id: runequest.py,v 1.4 2006/11/15 12:11:22 digitalxero Exp $" | |
56 | |
57 from time import time, clock | |
58 import random | |
59 from math import floor | |
60 | |
61 from std import std | |
62 from orpg.dieroller.base import * | |
63 | |
64 # rq stands for "Runequest" | |
65 | |
66 class runequest(std): | |
67 name = "runequest" | |
68 def __init__(self,source=[]): | |
69 std.__init__(self,source) | |
70 | |
71 # these methods return new die objects for specific options | |
72 | |
73 def skill(self,sk,mod,ma): | |
74 return rqskill(self,sk,mod,ma) | |
75 | |
76 def parry(self,sk,mod,ma,AP): | |
77 return rqparry(self,sk,mod,ma,AP) | |
78 | |
79 def dodge(self,sk,mod,ma): | |
80 return rqdodge(self,sk,mod,ma) | |
81 | |
82 def attack(self,sk,mod,ma,mindam,maxdam,bondam,trueswd): | |
83 return rqattack(self,sk,mod,ma,mindam,maxdam,bondam,trueswd) | |
84 | |
85 def sorcery(self,sk,mod,pow,cer,int,acc,mlt): | |
86 return rqsorcery(self,sk,mod,pow,cer,int,acc,mlt) | |
87 | |
88 def trainskill(self,initial,final): | |
89 return rqtrainskill(self,initial,final) | |
90 | |
91 def trainskillcost(self,cost,sk): | |
92 return rqtrainskillcost(self,cost,sk) | |
93 | |
94 def trainskilltime(self,time,sk): | |
95 return rqtrainskilltime(self,time,sk) | |
96 | |
97 die_rollers.register(runequest) | |
98 | |
99 # RQ Skill Training Cost/Time unlimited | |
100 # | |
101 # [1d100.trainskill(10,20)] | |
102 # initial skill%, final skill% | |
103 # | |
104 # sk = skill % | |
105 # | |
106 # | |
107 class rqtrainskill(std): | |
108 def __init__(self,source=[],initial=11,final=0): | |
109 std.__init__(self,source) | |
110 self.s = initial | |
111 self.f = final | |
112 | |
113 def __str__(self): | |
114 myStr = "Unrestricted Training" | |
115 | |
116 if self.s == 0: | |
117 myStr = "Initial training completed for Cost(50) Time(20) Skill(1 + modifier)" | |
118 else: | |
119 cost = 0 | |
120 time = 0 | |
121 myStr = "Training: " | |
122 | |
123 while self.s < self.f and self.s < 75: | |
124 cost += self.s * 5 | |
125 time += self.s * 1 | |
126 self.s += random.uniform(1,4) + 1 | |
127 | |
128 myStr = "Training completed:\n" | |
129 myStr += "\tCost(" + str(int(cost)) + ")\n" | |
130 myStr += "\tTime(" + str(int(time)) + ")\n" | |
131 myStr += "\tSkill(" + str(int(self.s)) + ")" | |
132 | |
133 return myStr | |
134 | |
135 | |
136 # RQ Skill Training Cost Limited | |
137 # | |
138 # [1d100.trainskillcost(50,0)] | |
139 # cost, skill% | |
140 # | |
141 # cost = cash for training | |
142 # sk = skill % | |
143 # | |
144 # | |
145 class rqtrainskillcost(std): | |
146 def __init__(self,source=[],cost=11,sk=0): | |
147 std.__init__(self,source) | |
148 self.cost = cost | |
149 self.sk = sk | |
150 | |
151 def __str__(self): | |
152 myStr = "" | |
153 | |
154 if self.sk == 0 and self.cost >= 50: | |
155 myStr = "Initial training completed for Cost(50), Time(50), Skill(1 + modifier)" | |
156 else: | |
157 cost = 0 | |
158 time = 0 | |
159 icost = self.sk * 5 | |
160 | |
161 myStr = "Training: " | |
162 | |
163 while (cost + icost) < self.cost: | |
164 if self.sk >= 75: | |
165 break | |
166 | |
167 cost += icost | |
168 time += self.sk * 1 | |
169 self.sk += random.uniform(1,4) + 1 | |
170 icost = self.sk * 5 | |
171 | |
172 myStr = "Training completed: " | |
173 myStr += "Cost(" + str(int(cost)) + ") " | |
174 myStr += "Time(" + str(int(time)) + ") " | |
175 myStr += "Skill(" + str(int(self.sk)) + ")" | |
176 | |
177 return myStr | |
178 | |
179 | |
180 # RQ Skill Training Time Limited | |
181 # | |
182 # [1d100.trainskilltime(50,0)] | |
183 # time, skill% | |
184 # | |
185 # time = time for training | |
186 # sk = skill % | |
187 # | |
188 # | |
189 class rqtrainskilltime(std): | |
190 def __init__(self,source=[],time=11,sk=0): | |
191 std.__init__(self,source) | |
192 self.time = time | |
193 self.sk = sk | |
194 | |
195 def __str__(self): | |
196 myStr = "" | |
197 | |
198 if self.sk == 0 and self.time >= 20: | |
199 myStr = "Initial training completed for Cost(50), Time(50), Skill(1 + modifier)" | |
200 else: | |
201 cost = 0 | |
202 time = 0 | |
203 itime = self.sk * 1 | |
204 | |
205 myStr = "Trainingsss: " | |
206 | |
207 while (time + itime) < self.time: | |
208 if self.sk >= 75: | |
209 break | |
210 | |
211 cost += self.sk * 5 | |
212 time += itime | |
213 self.sk += random.uniform(1,4) + 1 | |
214 itime = self.sk * 5 | |
215 | |
216 myStr = "Training completed: " | |
217 myStr += "Cost(" + str(int(cost)) + ") " | |
218 myStr += "Time(" + str(int(time)) + ") " | |
219 myStr += "Skill(" + str(int(self.sk)) + ")" | |
220 | |
221 return myStr | |
222 | |
223 # RQ Skill Roll | |
224 # | |
225 # [1d100.skill(50,0,0)] | |
226 # skill%, modifer, ma% | |
227 # | |
228 # sk = skill % | |
229 # mod = modifier % | |
230 # ma = martial arts % | |
231 # skill = sk + mod | |
232 # | |
233 # success roll <= skill | |
234 # | |
235 # failure roll > skill | |
236 # | |
237 # crit | |
238 # push( @{$::Cre{Weapons}{$weap_cnt}}, POSIX::floor( skill/20 ) ); | |
239 # | |
240 # special | |
241 # push( @{$::Cre{Weapons}{$weap_cnt}}, POSIX::floor( $skill/5 ) ); | |
242 # | |
243 # fumble: if ( $skill > 100 ) { $fum = 0; } else { $fum = 100 - $skill; } | |
244 # $fum = 100 - POSIX::floor( $fum/20 ); | |
245 # if ( $fum == 100 ) { $fum = '00'; }; | |
246 # | |
247 class rqskill(std): | |
248 def __init__(self,source=[],sk=11,mod=0,ma=0): | |
249 std.__init__(self,source) | |
250 self.sk = sk | |
251 self.mod = mod | |
252 self.ma = ma | |
253 | |
254 def is_success(self): | |
255 return (((self.sum() <= (self.sk + self.mod)) or (self.sum() <= 5)) and (self.sum() <= 95)) | |
256 | |
257 def is_ma(self): | |
258 return (self.sum() <= self.ma) | |
259 | |
260 def is_special(self): | |
261 return (self.sum() <= int(floor((self.sk + self.mod)/5))) | |
262 | |
263 def is_critical(self): | |
264 return (self.sum() <= int(floor((self.sk + self.mod) / 20))) | |
265 | |
266 def is_fumble(self): | |
267 if ( self.sk >= 100 ): | |
268 fum = 0 | |
269 else: | |
270 fum = (100 - self.sk ) | |
271 final_fum = ( 100 - int( floor( fum/20 ) ) ) | |
272 return ( self.sum() >= final_fum ) | |
273 | |
274 def __str__(self): | |
275 strAdd="+" | |
276 swapmod= self.mod | |
277 if self.mod < 0: | |
278 strAdd= "-" | |
279 swapmod= -self.mod | |
280 modSum = self.sum() | |
281 # build output string | |
282 myStr = " (" + str(modSum) + ")" | |
283 myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" | |
284 | |
285 if self.is_fumble(): | |
286 myStr += " <b><font color=red>Fumble!</font></b>" | |
287 elif self.is_critical(): | |
288 myStr += " <b><font color=green>Critical!</font></b>" | |
289 elif self.is_special(): | |
290 myStr += " <i><font color=green>Special!</font></i>" | |
291 elif self.is_success() and self.is_ma(): | |
292 myStr += " <i><font color=green>Special!</font></i>" | |
293 elif self.is_success(): | |
294 myStr += " <font color=blue>Success!</font>" | |
295 else: | |
296 myStr += " <font color=red>Failure!</font>" | |
297 | |
298 Diff = self.sk - modSum | |
299 myStr += " </font>" | |
300 | |
301 return myStr | |
302 | |
303 # | |
304 # RQ Parry Roll | |
305 # | |
306 # same as skill but with fumble dice and armor points | |
307 # | |
308 # [1d100.parry(50,0,0,12)] | |
309 # skill%, modifer, ma%, Weapon AP | |
310 # | |
311 | |
312 class rqparry(std): | |
313 def __init__(self,source=[],sk=11,mod=0,ma=0,AP=0): | |
314 std.__init__(self,source) | |
315 self.sk = sk | |
316 self.mod = mod | |
317 self.ma = ma | |
318 self.AP = AP | |
319 | |
320 def is_success(self): | |
321 return (((self.sum() <= (self.sk + self.mod)) or (self.sum() <= 5)) and (self.sum() <= 95)) | |
322 | |
323 def is_special(self): | |
324 return (self.sum() <= int(floor((self.sk + self.mod) / 5))) | |
325 | |
326 def is_ma(self): | |
327 return (self.sum() <= self.ma) | |
328 | |
329 def is_riposte(self): | |
330 return (self.sum() <= (self.ma / 5)) | |
331 | |
332 def is_critical(self): | |
333 return ( ( self.sum() <= int( floor( ( self.sk + self.mod )/20 ) ) ) ) | |
334 | |
335 def is_fumble(self): | |
336 if ( self.sk >= 100 ): | |
337 fum = 0 | |
338 else: | |
339 fum = (100 - self.sk ) | |
340 final_fum = ( 100 - int( floor( fum/20 ) ) ) | |
341 return ( self.sum() >= final_fum ) | |
342 | |
343 def __str__(self): | |
344 | |
345 # get fumble roll result in case needed | |
346 fum_roll = random.randint(1,100) | |
347 | |
348 # get special AP | |
349 spec_AP = int( floor ( self.AP * 1.5 ) ) | |
350 | |
351 # figure out +/- for modifer | |
352 strAdd="+" | |
353 swapmod= self.mod | |
354 if self.mod < 0: | |
355 strAdd= "-" | |
356 swapmod= -self.mod | |
357 modSum = self.sum() | |
358 | |
359 # build output string | |
360 myStr = " (" + str(modSum) + ")" | |
361 myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" | |
362 | |
363 if self.is_fumble(): | |
364 myStr += " <b><font color=red>Fumble!</font> See Fumble Chart [" + str(fum_roll) + "]</b>" | |
365 elif self.is_critical() and self.is_riposte(): | |
366 myStr += " <b><font color=green>Critical!</font> All damage blocked!</b>" | |
367 myStr += " Riposte next SR" | |
368 elif self.is_critical(): | |
369 myStr += " <b><font color=green>Critical!</font> All damage blocked!</b>" | |
370 elif self.is_special and self.is_riposte(): | |
371 myStr += " <i><font color=green>Special!</font> Weapon/Shield AP [" + str(spec_AP) + "]</i>" | |
372 myStr += " Riposte next SR" | |
373 elif self.is_special(): | |
374 myStr += " <i><font color=green>Special!</font> Weapon/Shield AP [" + str(spec_AP) + "]</i>" | |
375 elif self.is_success() and self.is_ma(): | |
376 myStr += " <i><font color=green>Special!</font> Weapon/Shield AP [" + str(spec_AP) + "]</i>" | |
377 elif self.is_success(): | |
378 myStr += " <font color=blue>Success!</font> Weapon/Shield AP [" + str(self.AP) + "]" | |
379 else: | |
380 myStr += " <font color=red>Failure!</font>" | |
381 | |
382 Diff = self.sk - modSum | |
383 myStr += " </font>" | |
384 | |
385 return myStr | |
386 | |
387 # RQ Dodge Roll | |
388 # | |
389 # same as skill but with fumble dice and armor points | |
390 # | |
391 # [1d100.parry(50,0,0)] | |
392 # skill%, modifer, ma% | |
393 # | |
394 | |
395 class rqdodge(std): | |
396 def __init__(self,source=[],sk=11,mod=0,ma=0,AP=0): | |
397 std.__init__(self,source) | |
398 self.sk = sk | |
399 self.mod = mod | |
400 self.ma = ma | |
401 self.AP = AP | |
402 | |
403 def is_success(self): | |
404 return (((self.sum() <= (self.sk + self.mod)) or (self.sum() <= 5)) and (self.sum() <= 95)) | |
405 | |
406 def is_special(self): | |
407 return (self.sum() <= int(floor((self.sk + self.mod) / 5))) | |
408 | |
409 def is_ma(self): | |
410 return (self.sum() <= self.ma) | |
411 | |
412 def is_riposte(self): | |
413 return (self.sum() <= (self.ma / 5)) | |
414 | |
415 def is_critical(self): | |
416 return ( ( self.sum() <= int( floor( ( self.sk + self.mod )/20 ) ) ) ) | |
417 | |
418 def is_fumble(self): | |
419 if ( self.sk >= 100 ): | |
420 fum = 0 | |
421 else: | |
422 fum = (100 - self.sk ) | |
423 final_fum = ( 100 - int( floor( fum/20 ) ) ) | |
424 return ( self.sum() >= final_fum ) | |
425 | |
426 def __str__(self): | |
427 | |
428 # get fumble roll result in case needed | |
429 fum_roll = random.randint(1,100) | |
430 | |
431 # get special AP | |
432 spec_AP = int( floor ( self.AP * 1.5 ) ) | |
433 | |
434 # figure out +/- for modifer | |
435 strAdd="+" | |
436 swapmod= self.mod | |
437 if self.mod < 0: | |
438 strAdd= "-" | |
439 swapmod= -self.mod | |
440 modSum = self.sum() | |
441 | |
442 # build output string | |
443 myStr = " (" + str(modSum) + ")" | |
444 myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" | |
445 | |
446 if self.is_fumble(): | |
447 myStr += " <b><font color=red>Fumble!</font> See Fumble Chart [" + str(fum_roll) + "]</b>" | |
448 elif self.is_critical() and self.is_riposte(): | |
449 myStr += " <b><font color=green>Critical!</font> All damage dodged!</b>" | |
450 myStr += " Riposte on next SR" | |
451 elif self.is_critical(): | |
452 myStr += " <b><font color=green>Critical!</font> All damage dodged!</b>" | |
453 elif self.is_special and self.is_riposte(): | |
454 myStr += " <i><font color=green>Special!</font> Damage dodged</b>" | |
455 myStr += " Riposte on next SR" | |
456 elif self.is_special(): | |
457 myStr += " <i><font color=green>Special!</font> Damage dodged</b>" | |
458 elif self.is_success() and self.is_ma(): | |
459 myStr += " <i><font color=green>Special!</font> Damage dodged</b>" | |
460 elif self.is_success(): | |
461 myStr += " <font color=blue>Success!</font> Damage dodged</b>" | |
462 else: | |
463 myStr += " <font color=red>Failure!</font>" | |
464 | |
465 Diff = self.sk - modSum | |
466 myStr += " </font>" | |
467 | |
468 return myStr | |
469 | |
470 | |
471 | |
472 # | |
473 # RQ Attack Roll | |
474 # | |
475 # same as skill but with fumble dice and armor points | |
476 # | |
477 # [1d100.attack(50,0,0,2,9,3,1)] | |
478 # skill%, modifer, ma%, min weap dam, max weap dam, dam bonus, truesword_enabled | |
479 # | |
480 class rqattack(std): | |
481 def __init__(self,source=[],sk=11,mod=0,ma=0,mindam=0,maxdam=0,bondam=0,trueswd=0): | |
482 std.__init__(self,source) | |
483 self.sk = sk | |
484 self.mod = mod | |
485 self.ma = ma | |
486 self.mindam = mindam | |
487 self.maxdam = maxdam | |
488 self.bondam = bondam | |
489 self.trueswd = trueswd | |
490 | |
491 def is_success(self): | |
492 return (((self.sum() <= (self.sk + self.mod)) or (self.sum() <= 5)) and (self.sum() <= 95)) | |
493 | |
494 def is_ma(self): | |
495 return (self.sum() <= self.ma) | |
496 | |
497 def is_special(self): | |
498 return (self.sum() <= int(floor((self.sk + self.mod) / 5))) | |
499 | |
500 def is_critical(self): | |
501 return ((self.sum() <= int(floor((self.sk + self.mod) / 20)))) | |
502 | |
503 def is_supercritical(self): | |
504 return (self.sum() == 1) | |
505 | |
506 def is_fumble(self): | |
507 if ( self.sk >= 100 ): | |
508 fum = 0 | |
509 else: | |
510 fum = (100 - self.sk ) | |
511 final_fum = ( 100 - int( floor( fum/20 ) ) ) | |
512 return ( self.sum() >= final_fum ) | |
513 | |
514 def __str__(self): | |
515 | |
516 # get fumble roll result in case needed | |
517 fum_roll = random.randint(1,100) | |
518 | |
519 # get hit location roll result in case needed | |
520 location = random.randint(1,20) | |
521 myStr = " to the ["+ str(location) + "] " | |
522 if location < 5: | |
523 myStr += "<B>Right Leg</B>" | |
524 elif location < 9: | |
525 myStr += "<B>Left Leg</B>" | |
526 elif location < 12: | |
527 myStr += "<B>Abdomen</B>" | |
528 elif location < 13: | |
529 myStr += "<B>Chest</B>" | |
530 elif location < 16: | |
531 myStr += "<B>Right Arm</B>" | |
532 elif location < 19: | |
533 myStr += "<B>Left Arm</B>" | |
534 else: | |
535 myStr += "<B>Head</B>" | |
536 hit_loc = myStr | |
537 | |
538 | |
539 # get normal damage in case needed | |
540 norm_damage = random.randint(self.mindam*(self.trueswd+1),self.maxdam*(self.trueswd+1)) + self.bondam | |
541 norm_damage_string = "{" + str( self.mindam*(self.trueswd+1) ) + "-" | |
542 norm_damage_string += str(self.maxdam*(self.trueswd+1)) + "+" + str(self.bondam) | |
543 norm_damage_string += "}[" + str(norm_damage) + "] " | |
544 | |
545 # get special/critical damage in case needed | |
546 crit_damage = random.randint( self.mindam*(self.trueswd+2), self.maxdam*(self.trueswd+2) ) + self.bondam | |
547 crit_damage_string = "{" + str( self.mindam*(self.trueswd+2) ) + "-" + str(self.maxdam*(self.trueswd+2)) + "+" + str(self.bondam) + "}[" + str(crit_damage) + "] " | |
548 | |
549 # get supercritical damage in case needed | |
550 super_damage = norm_damage + self.maxdam | |
551 super_damage_string = "{" + str( self.mindam*(self.trueswd+1) ) + "-" | |
552 super_damage_string += str(self.maxdam*(self.trueswd+1)) + "+" + str(self.maxdam) | |
553 super_damage_string += "+" + str(self.bondam) + "}[" + str(super_damage) + "] " | |
554 | |
555 # figure out +/- for modifer | |
556 strAdd="+" | |
557 swapmod= self.mod | |
558 if self.mod < 0: | |
559 strAdd= "-" | |
560 swapmod= -self.mod | |
561 modSum = self.sum() | |
562 | |
563 # build output string | |
564 myStr = " (" + str(modSum) + ")" | |
565 myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" | |
566 | |
567 if self.is_fumble(): | |
568 myStr += " <b><font color=red>Fumble!</font> See Fumble Chart [" + str(fum_roll) + "]</b>" | |
569 elif (self.is_supercritical() and self.is_success()): | |
570 myStr += " <b><font color=green>Super Critical!</font></b> Damage: " + str(super_damage_string) + "<u>No Armor Stops</u>" + str(hit_loc) | |
571 elif (self.is_critical() and self.is_success()): | |
572 myStr += " <b><font color=green>Critical!</font></b> Damage: " + str(crit_damage_string) + "<u>No Armor Stops</u>" + str(hit_loc) | |
573 elif ( self.is_special() and self.is_success() ): | |
574 myStr += " <i><font color=green>Special!</font></i> Damage: " + str(crit_damage_string) + str(hit_loc) | |
575 elif (self.is_success() and self.is_ma()): | |
576 myStr += " <i><font color=green>Special!</font></i> Damage: " + str(crit_damage_string) + str(hit_loc) | |
577 elif self.is_success(): | |
578 myStr += " <font color=blue>Success!</font> Damage: " + str(norm_damage_string) + str(hit_loc) | |
579 else: | |
580 myStr += " <font color=red>Failure!</font>" | |
581 | |
582 return myStr | |
583 | |
584 # | |
585 # | |
586 # Sorcery Roll: [1d100.sorcery(90, 10, 5, 4, 3, 2, 1)] | |
587 # (sk, mod, pow, cer, int, acc, mlt) | |
588 # | |
589 # Ceremony: (+1d6% per strike rank spent on ceremony) | |
590 # Intensity: (-3% per point of Intensity) | |
591 # Duration: (-4% per point of Duration) | |
592 # Range: (-5% per point of Range) | |
593 # Multispell: (-10% per each spell over 1) | |
594 # Acceleration: (-5% per point of Acceleration) | |
595 # Hold: (-2% per point in spell Held) | |
596 # | |
597 class rqsorcery(std): | |
598 def __init__(self,source=[],sk=11,mod=0,pow=0,cer=0,int=0,acc=0,mlt=0): | |
599 std.__init__(self,source) | |
600 self.sk = sk # sorcery skill | |
601 self.mod = mod # additional modifier ( from duration, range, etc ) | |
602 self.pow = pow # boost pow and additional pow ( from duration, range, etc ) | |
603 self.cer = cer # ceremony d6 | |
604 self.int = int # intensity ( -3% ) | |
605 self.acc = acc # accelerate ( -5% ) | |
606 self.mlt = mlt # multispell ( -10% ) | |
607 | |
608 def is_success(self): | |
609 return (((self.sum() <= (self.sk + self.mod)) or (self.sum() <= 5)) and (self.sum() <= 95)) | |
610 | |
611 def is_special(self): | |
612 return ( ( self.sum() <= int( floor( ( self.sk + self.mod )/5 ) ) ) ) | |
613 | |
614 def is_critical(self): | |
615 return ( ( self.sum() <= int( floor( ( self.sk + self.mod )/20 ) ) ) ) | |
616 | |
617 def is_fumble(self): | |
618 if ( self.sk >= 100 ): | |
619 fum = 0 | |
620 else: | |
621 fum = (100 - self.sk ) | |
622 final_fum = ( 100 - int( floor( fum/20 ) ) ) | |
623 return ( self.sum() >= final_fum ) | |
624 | |
625 def __str__(self): | |
626 | |
627 # get fumble roll result in case needed | |
628 fum_roll = random.randint(2,12) | |
629 if fum_roll == 12 : | |
630 fum_string = "<br /><font color=purple>Caster temporarily forgets spell. Make an INTx5 roll each day to remember.</font>" | |
631 if fum_roll == 11 : | |
632 fum_string = "<br /><font color=purple>Caster temporarily forgets spell. Make an INTx5 roll each hour to remember. </font>" | |
633 if fum_roll == 10 : | |
634 fum_string = "<br /><font color=purple>Spell produces reverse of the intended effect. </font>" | |
635 if fum_roll == 9 : | |
636 fum_string = "<br /><font color=purple>Caster is Stunned. Roll INTx3 to recover at SR 10 each round. </font>" | |
637 if fum_roll == 8 : | |
638 fum_string = "<br /><font color=purple>Caster takes 2D6 Damage to THP </font>" | |
639 if fum_roll == 7 : | |
640 fum_string = "<br /><font color=purple>Spell produces reverse of the intended effect at 2x Intensity. </font>" | |
641 if fum_roll == 6 : | |
642 fum_string = "<br /><font color=purple>Spell is cast on companions (if harmful) or on random nearby foes (if beneficial) </font>" | |
643 if fum_roll == 5 : | |
644 fum_string = "<br /><font color=purple>Caster takes 1d6 Damage to Head </font>" | |
645 if fum_roll == 4 : | |
646 fum_string = "<br /><font color=purple>Spell is cast on caster (if harmful) or on random nearby foe (if beneficial) </font>" | |
647 if fum_roll == 3 : | |
648 fum_string = "<br /><font color=purple>Caster takes 1d6 Damage to THP </font>" | |
649 if fum_roll == 2 : | |
650 fum_string = "<br /><font color=purple>Caster takes 1 point of Damage to Head </font>" | |
651 | |
652 # roll ceremony | |
653 ceremony_roll = random.randint( self.cer, (self.cer*6) ) | |
654 | |
655 # subtract manipulations | |
656 extra_mod = self.mod | |
657 self.mod += ceremony_roll - self.int*3 - self.acc*5 - self.mlt*10 | |
658 | |
659 # add up power cost | |
660 extra_pow = self.pow | |
661 self.pow += self.int + self.mlt + self.acc | |
662 special_pow = int( floor( ( self.pow )/2 ) ) | |
663 | |
664 # figure out +/- for modifer | |
665 strAdd="+" | |
666 swapmod= self.mod | |
667 if self.mod < 0: | |
668 strAdd= "-" | |
669 swapmod= -self.mod | |
670 modSum = self.sum() | |
671 | |
672 # build output string | |
673 myStr = " (" + str(modSum) + ")" | |
674 myStr += " vs [" + str(self.sk) + strAdd + str(swapmod) + "]" | |
675 | |
676 if self.is_fumble(): | |
677 myStr += " <b><font color=red>Fumble!</font> POW Cost: [" + str(self.pow) + "],</b> " + fum_string | |
678 elif self.is_critical(): | |
679 myStr += " <b><font color=green>Critical!</font></b> POW Cost: [1] " | |
680 elif self.is_special(): | |
681 myStr += " <i><font color=green>Special!</font></i> POW Cost: [" + str(special_pow) + "] " | |
682 elif self.is_success(): | |
683 myStr += " <font color=blue>Success!</font> POW Cost: [" + str(self.pow) + "] " | |
684 else: | |
685 myStr += " <font color=red>Failure!</font> POW Cost: [1]" | |
686 | |
687 # print spell details | |
688 myStr += "<br /> --- Other Modifiers:[" + str( extra_mod ) + "], " | |
689 myStr += "Extra POW:[" + str( extra_pow ) + "], " | |
690 myStr += "Ceremony:[+" + str( ceremony_roll ) + "%], " | |
691 myStr += "Intensity(-3):[" + str( self.int ) + "], " | |
692 myStr += "Accelerate(-5):[" + str( self.acc ) + "], " | |
693 myStr += "Multispell(-10):[" + str( self.mlt ) + "] ---" | |
694 | |
695 return myStr | |
696 |