cypher: distinguish between a task roll and an attack roll
attack = A, otherwise the same options as with a generic task (= T) Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
		
							parent
							
								
									3b7c871a94
								
							
						
					
					
						commit
						6d8ba18380
					
				| @ -13,7 +13,7 @@ from ircbot.lib import Plugin | |||||||
| 
 | 
 | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| 
 | 
 | ||||||
| CYPHER_ROLL_REGEX = r'(T(?P<difficulty>\d+))?(?P<mods>(?:\s*(-|\+)\d+)*)\s*(?P<comment>.*)?' | CYPHER_ROLL_REGEX = r'((?P<type>A|T)(?P<difficulty>\d+))?(?P<mods>(?:\s*(-|\+)\d+)*)\s*(?P<comment>.*)?' | ||||||
| CYPHER_COMMAND_REGEX = r'^!cypher\s+(' + CYPHER_ROLL_REGEX + ')' | CYPHER_COMMAND_REGEX = r'^!cypher\s+(' + CYPHER_ROLL_REGEX + ')' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -52,8 +52,9 @@ class Dice(Plugin): | |||||||
|         task_group = re.search(CYPHER_ROLL_REGEX, task, re.IGNORECASE) |         task_group = re.search(CYPHER_ROLL_REGEX, task, re.IGNORECASE) | ||||||
|         difficulty = int(task_group.group('difficulty')) if task_group.group('difficulty') else None |         difficulty = int(task_group.group('difficulty')) if task_group.group('difficulty') else None | ||||||
|         mods = task_group.group('mods') |         mods = task_group.group('mods') | ||||||
|  |         is_attack = True if task_group.group('type') and task_group.group('type').upper() == 'A' else False | ||||||
|         comment = task_group.group('comment') |         comment = task_group.group('comment') | ||||||
|         result, beats, success, effect = cypher_roll(difficulty=difficulty, mods=mods) |         result, beats, success, effect = cypher_roll(difficulty=difficulty, mods=mods, is_attack=is_attack) | ||||||
| 
 | 
 | ||||||
|         if success is not None: |         if success is not None: | ||||||
|             if success: |             if success: | ||||||
| @ -81,7 +82,8 @@ class Dice(Plugin): | |||||||
|         if comment: |         if comment: | ||||||
|             return self.bot.reply(event, f"{nick}: {comment} {result_str} {detail_str}") |             return self.bot.reply(event, f"{nick}: {comment} {result_str} {detail_str}") | ||||||
|         else: |         else: | ||||||
|             return self.bot.reply(event, f"{nick}: your check {result_str} {detail_str}") |             type_str = 'attack' if is_attack else 'check' | ||||||
|  |             return self.bot.reply(event, f"{nick}: your {type_str} {result_str} {detail_str}") | ||||||
| 
 | 
 | ||||||
|     def handle_random(self, connection, event, match): |     def handle_random(self, connection, event, match): | ||||||
|         """Handle the !random command which picks an item from a list.""" |         """Handle the !random command which picks an item from a list.""" | ||||||
|  | |||||||
| @ -6,12 +6,13 @@ import numexpr | |||||||
| rand = random.SystemRandom() | rand = random.SystemRandom() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def cypher_roll(difficulty=None, mods=0): | def cypher_roll(difficulty=None, mods=0, is_attack=False): | ||||||
|     """Make a Cypher System roll. |     """Make a Cypher System roll. | ||||||
| 
 | 
 | ||||||
|     Args: |     Args: | ||||||
|         difficulty: the original difficulty to beat; if provided, success or failure is indicated in the results |         difficulty: the original difficulty to beat; if provided, success or failure is indicated in the results | ||||||
|         mods: eases(-) and hindrances(+) to apply to the check, as a string (e.g. '-3+1') |         mods: eases(-) and hindrances(+) to apply to the check, as a string (e.g. '-3+1') | ||||||
|  |         is_attack: if the roll is an attack (in which case the damage-only effects are included) | ||||||
|     Returns: |     Returns: | ||||||
|         tuple of: |         tuple of: | ||||||
|             - the result on the d20 |             - the result on the d20 | ||||||
| @ -24,9 +25,9 @@ def cypher_roll(difficulty=None, mods=0): | |||||||
|         return (roll, None, False if difficulty else None, 'a GM intrusion') |         return (roll, None, False if difficulty else None, 'a GM intrusion') | ||||||
| 
 | 
 | ||||||
|     effect = None |     effect = None | ||||||
|     if roll == 17: |     if roll == 17 and is_attack: | ||||||
|         effect = '+1 damage' |         effect = '+1 damage' | ||||||
|     elif roll == 18: |     elif roll == 18 and is_attack: | ||||||
|         effect = '+2 damage' |         effect = '+2 damage' | ||||||
|     elif roll == 19: |     elif roll == 19: | ||||||
|         effect = 'a minor effect' |         effect = 'a minor effect' | ||||||
|  | |||||||
| @ -30,14 +30,24 @@ class MarkovTestCase(TestCase): | |||||||
|         mock_event.target = '#test' |         mock_event.target = '#test' | ||||||
|         mock_event.recursing = False |         mock_event.recursing = False | ||||||
| 
 | 
 | ||||||
|         # general task roll |         # general task roll (no damage output on a 17) | ||||||
|         mock_event.arguments = ['!cypher T3'] |         mock_event.arguments = ['!cypher T3'] | ||||||
|         match = re.search(dice.ircplugin.CYPHER_COMMAND_REGEX, mock_event.arguments[0]) |         match = re.search(dice.ircplugin.CYPHER_COMMAND_REGEX, mock_event.arguments[0]) | ||||||
|         with mock.patch('random.SystemRandom.randint', return_value=17): |         with mock.patch('random.SystemRandom.randint', return_value=17): | ||||||
|             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) |             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) | ||||||
|         self.mock_bot.reply.assert_called_with( |         self.mock_bot.reply.assert_called_with( | ||||||
|             mock_event, |             mock_event, | ||||||
|             'test: your check 9succeeded, with +1 damage! 14(d20=17 vs. diff. 3)' |             'test: your check 9succeeded! 14(d20=17 vs. diff. 3)' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # general attack roll (incl. damage output on a 17) | ||||||
|  |         mock_event.arguments = ['!cypher A3'] | ||||||
|  |         match = re.search(dice.ircplugin.CYPHER_COMMAND_REGEX, mock_event.arguments[0]) | ||||||
|  |         with mock.patch('random.SystemRandom.randint', return_value=17): | ||||||
|  |             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) | ||||||
|  |         self.mock_bot.reply.assert_called_with( | ||||||
|  |             mock_event, | ||||||
|  |             'test: your attack 9succeeded, with +1 damage! 14(d20=17 vs. diff. 3)' | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         # general task roll, case insensitive |         # general task roll, case insensitive | ||||||
| @ -47,7 +57,7 @@ class MarkovTestCase(TestCase): | |||||||
|             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) |             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) | ||||||
|         self.mock_bot.reply.assert_called_with( |         self.mock_bot.reply.assert_called_with( | ||||||
|             mock_event, |             mock_event, | ||||||
|             'test: your check 9succeeded, with +1 damage! 14(d20=17 vs. diff. 3)' |             'test: your check 9succeeded! 14(d20=17 vs. diff. 3)' | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         # unknown target roll |         # unknown target roll | ||||||
| @ -57,7 +67,7 @@ class MarkovTestCase(TestCase): | |||||||
|             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) |             self.plugin.handle_cypher_roll(self.mock_connection, mock_event, match) | ||||||
|         self.mock_bot.reply.assert_called_with( |         self.mock_bot.reply.assert_called_with( | ||||||
|             mock_event, |             mock_event, | ||||||
|             'test: your check beats a difficulty 4 task, with +1 damage! 14(d20=17 with +1 levels)' |             'test: your check beats a difficulty 4 task. 14(d20=17 with +1 levels)' | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         # no mod or known difficulty |         # no mod or known difficulty | ||||||
|  | |||||||
| @ -26,15 +26,25 @@ class DiceLibTestCase(TestCase): | |||||||
|             result = dice.lib.cypher_roll(difficulty=1) |             result = dice.lib.cypher_roll(difficulty=1) | ||||||
|         self.assertEqual(result, (1, None, False, 'a GM intrusion')) |         self.assertEqual(result, (1, None, False, 'a GM intrusion')) | ||||||
| 
 | 
 | ||||||
|  |         # rolled a 17 on an attack | ||||||
|  |         with mock.patch('random.SystemRandom.randint', return_value=17): | ||||||
|  |             result = dice.lib.cypher_roll(difficulty=1, is_attack=True) | ||||||
|  |         self.assertEqual(result, (17, 5, True, '+1 damage')) | ||||||
|  | 
 | ||||||
|  |         # rolled a 18 on an attack | ||||||
|  |         with mock.patch('random.SystemRandom.randint', return_value=18): | ||||||
|  |             result = dice.lib.cypher_roll(difficulty=1, is_attack=True) | ||||||
|  |         self.assertEqual(result, (18, 6, True, '+2 damage')) | ||||||
|  | 
 | ||||||
|         # rolled a 17 |         # rolled a 17 | ||||||
|         with mock.patch('random.SystemRandom.randint', return_value=17): |         with mock.patch('random.SystemRandom.randint', return_value=17): | ||||||
|             result = dice.lib.cypher_roll(difficulty=1) |             result = dice.lib.cypher_roll(difficulty=1) | ||||||
|         self.assertEqual(result, (17, 5, True, '+1 damage')) |         self.assertEqual(result, (17, 5, True, None)) | ||||||
| 
 | 
 | ||||||
|         # rolled a 18 |         # rolled a 18 | ||||||
|         with mock.patch('random.SystemRandom.randint', return_value=18): |         with mock.patch('random.SystemRandom.randint', return_value=18): | ||||||
|             result = dice.lib.cypher_roll(difficulty=1) |             result = dice.lib.cypher_roll(difficulty=1) | ||||||
|         self.assertEqual(result, (18, 6, True, '+2 damage')) |         self.assertEqual(result, (18, 6, True, None)) | ||||||
| 
 | 
 | ||||||
|         # rolled a 19 |         # rolled a 19 | ||||||
|         with mock.patch('random.SystemRandom.randint', return_value=19): |         with mock.patch('random.SystemRandom.randint', return_value=19): | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user