Deliantra
view release on metacpan or search on metacpan
Deliantra.pm view on Meta::CPAN
our %FACE; # face32
our %FACEDATA;
our $TILE;
our %FIELD_MULTILINE = (
msg => "endmsg",
lore => "endlore",
maplore => "endmaplore",
);
# movement bit type, PITA
our %FIELD_MOVEMENT = map +($_ => undef),
qw(move_type move_block move_allow move_on move_off move_slow);
# same as in server save routine, to (hopefully) be compatible
# to the other editors.
our @FIELD_ORDER_MAP = (qw(
file_format_version
name attach swap_time reset_timeout fixed_resettime difficulty
region music
shopitems shopgreed shopmin shopmax shoprace
darkness width height enter_x enter_y msg maplore
unique template
outdoor temp pressure humid windspeed winddir sky nosmooth
tile_path_1 tile_path_2 tile_path_3 tile_path_4
));
our @FIELD_ORDER = (qw(
inherit
elevation
name name_pl custom_name attach title race
slaying skill msg lore other_arch
sound sound_destroy face animation is_animated
magicmap glyph smoothlevel smoothface
str dex con wis pow cha int
hp maxhp sp maxsp grace maxgrace
exp perm_exp expmul
food dam luck wc ac x y speed speed_left move_state attack_movement
nrof level direction type subtype attacktype
resist_physical resist_magic resist_fire resist_electricity
resist_cold resist_confusion resist_acid resist_drain
resist_weaponmagic resist_ghosthit resist_poison resist_slow
resist_paralyze resist_turn_undead resist_fear resist_cancellation
resist_deplete resist_death resist_chaos resist_counterspell
resist_godpower resist_holyword resist_blind resist_internal
resist_life_stealing resist_disease
path_attuned path_repelled path_denied material materialname
value carrying weight invisible state magic
last_heal last_sp last_grace last_eat
connected glow_radius randomitems tresure_env npx_status npc_program
run_away pick_up container will_apply smoothlevel
current_weapon_script weapontype tooltype elevation client_type
item_power duration range
range_modifier duration_modifier dam_modifier gen_sp_armour
move_type move_block move_allow move_on move_off move_on move_slow move_slow_penalty
alive wiz was_wiz applied unpaid can_use_shield no_pick is_animated monster
friendly generator is_thrown auto_apply treasure player sold see_invisible
can_roll overlay_floor is_turnable is_used_up identified reflecting changing
splitting hitback startequip blocksview undead scared unaggressive
reflect_missile reflect_spell no_magic no_fix_player is_lightable tear_down
run_away pick_up unique no_drop can_cast_spell can_use_scroll can_use_range
can_use_bow can_use_armour can_use_weapon can_use_ring has_ready_range
has_ready_bow xrays is_floor lifesave no_strength sleep stand_still
random_move only_attack confused stealth cursed damned see_anywhere
known_magical known_cursed can_use_skill been_applied has_ready_scroll
can_use_rod can_use_horn make_invisible inv_locked is_wooded is_hilly
has_ready_skill has_ready_weapon no_skill_ident is_blind can_see_in_dark
is_cauldron is_dust no_steal one_hit berserk neutral no_attack no_damage
activate_on_push activate_on_release is_water use_content_on_gen is_buildable
precious
body_range body_arm body_torso body_head body_neck body_skill
body_finger body_shoulder body_foot body_hand body_wrist body_waist
));
our %EVENT_TYPE = (
apply => 1,
attack => 2,
death => 3,
drop => 4,
pickup => 5,
say => 6,
stop => 7,
time => 8,
throw => 9,
trigger => 10,
close => 11,
timer => 12,
);
# 1 up 2 right 4 down 8 left
our %WALLDIR = (
0 => 0,
1_2 => 1,
1_4 => 2,
2_2_1 => 3,
1_1 => 4,
2_1_1 => 5,
2_2_2 => 6,
3_2 => 7,
1_3 => 8,
2_2_4 => 9,
2_1_2 => 10,
3_1 => 11,
2_2_3 => 12,
3_4 => 13,
3_3 => 14,
4 => 15,
);
sub MOVE_WALK (){ 0x01 }
sub MOVE_FLY_LOW (){ 0x02 }
sub MOVE_FLY_HIGH (){ 0x04 }
sub MOVE_FLYING (){ 0x06 }
sub MOVE_SWIM (){ 0x08 }
sub MOVE_BOAT (){ 0x10 }
Deliantra.pm view on Meta::CPAN
my $face = $FACE{$a->{face} || $o->{face} || "blank.111"};
unless ($face) {
$face = $FACE{"blank.x11"}
or (warn "no face data found for arch '$a->{_name}'"), return;
}
if ($face->{w} > 1 || $face->{h} > 1) {
# bigface
return (0, 0, $face->{w} - 1, $face->{h} - 1);
} elsif ($o->{more}) {
# linked face
my ($minx, $miny, $maxx, $maxy) = ($o->{x}, $o->{y}) x 2;
for (; $o; $o = $o->{more}) {
$minx = min $minx, $o->{x};
$miny = min $miny, $o->{y};
$maxx = max $maxx, $o->{x};
$maxy = max $maxy, $o->{y};
}
return ($minx, $miny, $maxx, $maxy);
} else {
# single face
return (0, 0, 0, 0);
}
}
=item $type = arch_attr $arch
Returns a hashref describing the object and its attributes. It can contain
the following keys:
name the name, suitable for display purposes
ignore
attr
desc
use
section => [name => \%attr, name => \%attr]
import
=cut
sub arch_attr($) {
my ($obj) = @_;
require Deliantra::Data;
my $root;
my $attr = { };
my $arch = $ARCH{ $obj->{_name} };
my $type = $obj->{type} || $arch->{type};
if ($type > 0) {
$root = $Deliantra::Data::ATTR{$type};
} else {
my %a = (%$arch, %$obj);
if ($a{is_floor} && !$a{alive}) {
$root = $Deliantra::Data::TYPE{Floor};
} elsif (!$a{is_floor} && $a{alive} && !$a{tear_down}) {
$root = $Deliantra::Data::TYPE{"Monster & NPC"};
} elsif (!$a{is_floor} && !$a{alive} && $a{move_block}) {
$root = $Deliantra::Data::TYPE{Wall};
} elsif (!$a{is_floor} && $a{alive} && $a{tear_down}) {
$root = $Deliantra::Data::TYPE{"Weak Wall"};
} else {
$root = $Deliantra::Data::TYPE{Misc};
}
}
my (%ignore);
my @import = ($root);
my @new_import;
while (my $type = shift @import) {
# first import everything we will need:
push @import,
grep $_,
map $Deliantra::Data::TYPE{$_},
@{$type->{import} || []};
# and compute the ignored attributes
for (@{$type->{ignore} || []}) {
$ignore{$_}++ for ref $_ ? @$_ : $_;
}
push @new_import, $type;
}
(@import) = @new_import;
# then add defaults to the back of the list, so they are added
# as last resort.
push @import, \%Deliantra::Data::DEFAULT_ATTR
unless $type == 116;
my (@section_order, %section, @attr_order);
# @import = root, imported, default
while (my $type = pop @import) {
$attr->{$_} ||= $type->{$_}
for qw(name desc use);
for ([general => ($type->{attr} || [])], @{$type->{section} || []}) {
my ($name, $attr) = @$_;
push @section_order, $name;
for (@$attr) {
my ($k, $v) = @$_;
push @attr_order, $k;
$section{$name}{$k} = $v; # overwrite, so that the root decides
}
}
}
# remove ignores for "root" type
for (
map @{$_->[1]}, # section attributes
[general => ($root->{attr} || [])],
@{$root->{section} || []}
) {
my ($k, $v) = @$_;
# skip fixed attributes, if they are ignored thats fine
next if $v->{type} eq 'fixed';
delete $ignore{$k}; # if the attributes are defined explicitly they
( run in 1.633 second using v1.01-cache-2.11-cpan-df04353d9ac )