Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow item pools to accept any unknown item as a custom fruit #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions lib/NetHack/Item.pm
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ sub extract_stats {
$ # anchor
}x;

confess "Couldn't parse $raw"
unless defined($stats{item}) && length($stats{item});

# this canonicalization must come early
if ($stats{item} =~ /^potions? of ((?:un)?holy) water$/) {
$stats{item} = 'potion of water';
Expand All @@ -313,11 +316,10 @@ sub extract_stats {

if ($self->has_pool && ($stats{item} eq $self->pool->fruit_name || $stats{item} eq $self->pool->fruit_plural)) {
$stats{item} = $self->pool->fruit_name; # singularize
$stats{is_custom_fruit} = 1;
$stats{type} = 'food';
}
else {
$stats{is_custom_fruit} = 0;
elsif ($self->has_pool && $self->pool->allow_other_fruit_names) {
$stats{type} = 'food';
}

confess "Unknown item type for '$stats{item}' from $raw"
Expand Down Expand Up @@ -375,6 +377,8 @@ sub extract_stats {
$stats{$_} = '' if !defined($stats{$_});
}

$stats{is_custom_fruit} = 0;

return \%stats;
}

Expand All @@ -386,7 +390,7 @@ sub parse_raw {

# exploit the fact that appearances don't show up in the spoiler table as
# keys
$self->_set_appearance_and_identity($stats->{item});
$self->_set_appearance_and_identity($stats);

$self->_rebless_into($stats->{type}, $self->subtype);

Expand Down Expand Up @@ -468,12 +472,15 @@ sub is_artifact {
}

sub _set_appearance_and_identity {
my $self = shift;
my $best_match = shift;
my $self = shift;
my $stats = shift;

my $best_match = $stats->{item};

if ($self->has_pool && $best_match eq $self->pool->fruit_name) {
$self->identity("slime mold");
$self->appearance($best_match);
$stats->{is_custom_fruit} = 1;
}
elsif (my $spoiler = $self->spoiler_class->spoiler_for($best_match)) {
if ($spoiler->{artifact}) {
Expand All @@ -491,7 +498,11 @@ sub _set_appearance_and_identity {
$self->appearance($best_match);
my @possibilities = $self->possibilities;
if (@possibilities == 1 && $best_match ne $possibilities[0]) {
$self->_set_appearance_and_identity($possibilities[0]);
$stats->{item} = $possibilities[0];
$self->_set_appearance_and_identity($stats);
}
if ($self->identity && $self->identity eq 'slime mold') {
$stats->{is_custom_fruit} = 1;
}
}
}
Expand All @@ -506,7 +517,12 @@ sub possibilities {

return $self->tracker->possibilities if $self->has_tracker;

return sort @{ $self->spoiler_class->possibilities_for_appearance($self->appearance) };
my @possibilities = @{ $self->spoiler_class->possibilities_for_appearance($self->appearance) || [] };
if (@possibilities == 0 && $self->has_pool && $self->pool->allow_other_fruit_names) {
$self->identity('slime mold');
@possibilities = ($self->appearance);
}
return sort @possibilities;
}

sub spoiler {
Expand Down
5 changes: 5 additions & 0 deletions lib/NetHack/ItemPool.pm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ has fruit_plural => (
default => 'slime molds',
);

has allow_other_fruit_names => (
is => 'ro',
isa => 'Bool',
);

has artifacts => (
is => 'ro',
isa => 'HashRef',
Expand Down
39 changes: 39 additions & 0 deletions t/606-fruit.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env perl
use lib 't/lib';
use Test::NetHack::Item;
use Test::Fatal;

my $slime_pool = NetHack::ItemPool->new;
my $slime_mold = $slime_pool->new_item("a slime mold");
Expand All @@ -15,6 +16,12 @@ ok($molds->is_custom_fruit, "slime molds is custom fruit");
is($molds->appearance, 'slime mold');
is($molds->identity, 'slime mold');

like(
exception { $slime_pool->new_item("a server") },
qr/^Unknown item type for 'server' from a server/,
"we don't accept any random fruit type"
);


my $brain_pool = NetHack::ItemPool->new(
fruit_name => "brain",
Expand All @@ -32,6 +39,7 @@ ok($brains->is_custom_fruit, "brains is custom fruit");
is($brains->appearance, 'brain');
is($brains->identity, 'slime mold');


my $child_pool = NetHack::ItemPool->new(
fruit_name => "child",
fruit_plural => "children",
Expand All @@ -48,4 +56,35 @@ ok($children->is_custom_fruit, "children is custom fruit");
is($children->appearance, 'child');
is($children->identity, 'slime mold');


my $any_pool = NetHack::ItemPool->new(
allow_other_fruit_names => 1,
);

my $server = $any_pool->new_item("a server");
is($server->nutrition, 250);
ok($server->is_custom_fruit, "server is custom fruit");
is($server->appearance, 'server');
is($server->identity, 'slime mold');

my $servers = $any_pool->new_item("3 servers");
is($servers->nutrition, 250);
ok($servers->is_custom_fruit, "servers is custom fruit");
{ local $TODO = "we don't singularize properly yet";
is($servers->appearance, 'server');
}
is($servers->identity, 'slime mold');

my $any_slime_mold = $any_pool->new_item("a slime mold");
is($any_slime_mold->nutrition, 250);
ok($any_slime_mold->is_custom_fruit, "slime mold is custom fruit");
is($any_slime_mold->appearance, 'slime mold');
is($any_slime_mold->identity, 'slime mold');

my $any_molds = $any_pool->new_item("3 slime molds");
is($any_molds->nutrition, 250);
ok($any_molds->is_custom_fruit, "slime molds is custom fruit");
is($any_molds->appearance, 'slime mold');
is($any_molds->identity, 'slime mold');

done_testing;