#!perl our %materials; $cf::CFG{"editor_builder_ui"} or return; cf::register_extcmd builder_player_items => sub { my ($pl, $msg) = @_; # my @builditems = ext::reseller::find_rec ($pl->ob, sub { # my ($item) = @_; # return $item->type == cf::MATERIAL # }); (items => { map { $_->name => { value => $_->clone->value } } values %materials }) }; cf::register_extcmd builder_build => sub { my ($pl, $msg) = @_; my ($dx, $dy) = @$msg{qw(dx dy)}; my ($x, $y) = ($pl->ob->x + $dx, $pl->ob->y + $dy); my $near = (abs $dx) <= 2 && (abs $dy) <= 2; return unless $near; my $buildable = 0; for ($pl->ob->map->at ($x, $y)) { unless ($_->flag (cf::FLAG_IS_BUILDABLE)) { return; } } if ($msg->{do_erase}) { for my $ob ($pl->ob->map->at ($x, $y)) { unless ($ob->type == cf::WALL || $ob->type == cf::FLOOR || $ob->flag (cf::FLAG_IS_FLOOR)) { $ob->remove; $ob->free; } } } return unless $msg->{item}; if ($pl->cell_visible ($dx, $dy)) { my $arch = cf::arch::find $msg->{item}; if ($arch->clone->subtype == cf::ST_MAT_FLOOR) { my $above_floor; for my $ob ($pl->ob->map->at ($x, $y)) { if ($ob->type == cf::WALL) { undef $above_floor if $above_floor == $ob; $ob->remove; $ob->free; } elsif ($ob->type == cf::FLOOR || $ob->flag (cf::FLAG_IS_FLOOR)) { undef $above_floor if $above_floor == $ob; $above_floor = $ob->above; $ob->remove; $ob->free; } } # my @obs = $pl->ob->map->at ($x, $y); # for (@obs) { $_->remove; $_->free } my $floor = cf::object::new $arch->clone->slaying; $floor->flag (cf::FLAG_IS_BUILDABLE, 1); $floor->flag (cf::FLAG_UNIQUE, 1); $floor->flag (cf::FLAG_IS_FLOOR, 1); $floor->type (cf::FLOOR); $floor->insert_ob_in_map_at ($pl->ob->map, $above_floor, ($above_floor ? cf::INS_BELOW_ORIGINATOR : cf::INS_ON_TOP), $x, $y); $pl->ob->map->fix_walls_around ($x, $y); } elsif ($arch->clone->subtype == cf::ST_MAT_WALL) { my @obs = $pl->ob->map->at ($x, $y); my $prev_wall; for (@obs) { if ($_->type == cf::WALL) { $prev_wall = $_; last; } } my ($floor) = grep { $_->type == cf::FLOOR || $_->flag (cf::FLAG_IS_FLOOR) } $pl->ob->map->at ($x, $y); my $above_floor = $floor->above; if ($above_floor) { return; } my $wall = cf::object::new $arch->clone->slaying; $wall->type (cf::WALL); $wall->flag (cf::FLAG_IS_BUILDABLE, 1); $wall->insert_ob_in_map_at ($pl->ob->map, undef, cf::INS_ABOVE_FLOOR_ONLY, $x, $y); if ($prev_wall) { $prev_wall->remove; $prev_wall->free; $pl->ob->map->fix_walls ($pl->ob->x + $dx, $pl->ob->y + $dy); } else { $pl->ob->map->fix_walls_around ($pl->ob->x + $dx, $pl->ob->y + $dy); } } elsif ($arch->clone->subtype == cf::ST_MAT_ITEM) { my ($floor) = grep { $_->type == cf::FLOOR || $_->flag (cf::FLAG_IS_FLOOR) } $pl->ob->map->at ($x, $y); unless ($floor) { return; } my $above_floor = $floor->above; if ($above_floor) { return; } my $ob = cf::object::new $arch->clone->slaying; $ob->flag (cf::FLAG_IS_BUILDABLE, 1); $ob->flag (cf::FLAG_NO_PICK, 1); $ob->insert_ob_in_map_at ($pl->ob->map, undef, cf::INS_ABOVE_FLOOR_ONLY, $x, $y); } } # my $arch = cf::arch::find ($msg->{item}); }; my $farch = cf::arch::first; while ($farch) { if ($farch->clone->type == cf::MATERIAL) { $materials{$farch->name} = $farch; } $farch = $farch->next; }