Dice Roller Comcode?
Posted
#3889
(In Topic #775)
I've been struggling to try to make a custom comcode that would well, roll dice. Basically I wanted to do something like
Code
[roll]1d12[/roll]
which would give me some random number from such a dice roll. I've tried to find similar bbcode dice rollers out there to have something to go by since comcode isn't too distant from bbcode (or is it), but I've had no luck.
Anyone have any ideas?
Posted
Posted
Curious, this would obviously work for a simple d6 dice roll. Is there any way to make it more user defined? Lets say from my previous 1d12 example, it would take the number in front of the "d" to know how many dice to roll and the number after the "d" to know how many numbers to randomize.
EDIT: Testing the code out, there's one problem. It changes in the posts it was used in each time the page is refreshed.
Last edit: by mythus
Posted
Posted
I just need to figure out a way to stop the rolled results from changing in the post after the page refreshes. Any hints Chris, or anyone else for that matter?
Posted
Posted
Edit: Actually I'd struggle to even do against the URL, I can't see a way to save data from Tempcode.
Posted
Posted
First I had to make a code change to allow Custom Comcode tag hooks with PHP code (previously it had to only be Tempcode). This will be in the next patch release:
https://github.com/ocproducts/composr/commit/09ea2cffc609e260427071f63948de9724f53d8f
Then here's a Custom Comcode tag hook…
sources_custom/hooks/systems/comcode/roller.php:
Code (PHP)
<?php
class Hook_comcode_roller
{
public function get_tag()
{
return array(
'tag_title' => 'Dice Roller',
'tag_description' => 'Produce a random dice roll.',
'tag_example' => '[roller="some_id"]1,2,3,4,5,6[/roller]',
'tag_tag' => 'roller',
'tag_replace' => array($this, 'tag_replace'),
'tag_parameters' => 'param',
'tag_block_tag' => 0,
'tag_textual_tag' => 0,
'tag_dangerous_tag' => 0,
);
}
public function tag_replace($embed, $map)
{
$id = empty($map['param']) ? get_page_name() : $map['param'];
$_embed = $embed->evaluate();
$cache_bucket_id = fix_id('roller_' . $id . '_' . $_embed);
$cached = get_value($cache_bucket_id, null, true);
if ($cached !== null) {
return make_string_tempcode(escape_html($cached));
}
$matches = array();
if (preg_match('#^(\d+)d(\d+)$#', $_embed, $matches) == 0) {
// Pick from a set style...
if (!empty($_embed)) {
$rand_options = array_map('trim', explode(',', $_embed));
} else {
$rand_options = array('1', '2', '3', '4', '5', '6');
}
shuffle($rand_options);
$output = $rand_options[0];
} else {
// xdy format (where x is number of rolls and y is number of dice faces)...
$num_rolls = intval($matches[1]);
$num_faces = intval($matches[2]);
$output = '';
for ($i = 0; $i < $num_rolls; $i++) {
if ($output != '') {
$output .= ' & ';
}
$output .= strval(mt_rand(1, $num_faces));
}
}
if (!running_script('preview')) {
set_value($cache_bucket_id, $output, true);
}
return make_string_tempcode(escape_html($output));
}
}
class Hook_comcode_roller
{
public function get_tag()
{
return array(
'tag_title' => 'Dice Roller',
'tag_description' => 'Produce a random dice roll.',
'tag_example' => '[roller="some_id"]1,2,3,4,5,6[/roller]',
'tag_tag' => 'roller',
'tag_replace' => array($this, 'tag_replace'),
'tag_parameters' => 'param',
'tag_block_tag' => 0,
'tag_textual_tag' => 0,
'tag_dangerous_tag' => 0,
);
}
public function tag_replace($embed, $map)
{
$id = empty($map['param']) ? get_page_name() : $map['param'];
$_embed = $embed->evaluate();
$cache_bucket_id = fix_id('roller_' . $id . '_' . $_embed);
$cached = get_value($cache_bucket_id, null, true);
if ($cached !== null) {
return make_string_tempcode(escape_html($cached));
}
$matches = array();
if (preg_match('#^(\d+)d(\d+)$#', $_embed, $matches) == 0) {
// Pick from a set style...
if (!empty($_embed)) {
$rand_options = array_map('trim', explode(',', $_embed));
} else {
$rand_options = array('1', '2', '3', '4', '5', '6');
}
shuffle($rand_options);
$output = $rand_options[0];
} else {
// xdy format (where x is number of rolls and y is number of dice faces)...
$num_rolls = intval($matches[1]);
$num_faces = intval($matches[2]);
$output = '';
for ($i = 0; $i < $num_rolls; $i++) {
if ($output != '') {
$output .= ' & ';
}
$output .= strval(mt_rand(1, $num_faces));
}
}
if (!running_script('preview')) {
set_value($cache_bucket_id, $output, true);
}
return make_string_tempcode(escape_html($output));
}
}
You can use either like this to just give an option from a set of options:
[roller="some_id"]1,2,3,4,5,6[/roller]
or like this to do your multiple dice rolling (assumption of numeric dice starting with '1'):
[roller="some_id"]3d10[/roller]
It's important to pass some_id uniquely for each roll, as the tag will otherwise lose its value if the Comcode cache is emptied. The ID gives it a key to cache against.
It would be great if you could write this up into a tutorial (in a topic) and add it to the tutorial directory. I don't want to personally maintain this as an addon, but it's pretty straight-forward and a good programming example.
Posted
I'll test this out and tomorrow I'll see about putting it in tutorials for you. I did try to so something similar using php but got the fun little warning with composr protecting me from using the evil php.
6 guests and 0 members have recently viewed this.
