--- deliantra/server/ext/00_map_handling.ext 2006/12/30 16:56:16 1.4 +++ deliantra/server/ext/00_map_handling.ext 2006/12/31 10:28:36 1.8 @@ -140,6 +140,7 @@ })->prio (Coro::PRIO_MAX); our $SCHEDULER = cf::coro { + Coro::Timer::sleep 3600;#d#TODO#for debugging only while () { Coro::Timer::sleep $SCHEDULE_INTERVAL; @@ -149,6 +150,7 @@ for my $map (values %cf::MAP) { eval { next if $map->in_memory != cf::MAP_IN_MEMORY; + next if $map->players; my $last_access = $map->last_access; # not yet, because maps might become visible to players nearby # we need a tiled meta map for this to work @@ -173,6 +175,47 @@ }; $SCHEDULER->prio (-2); +sub generate_random_map { + my ($path, $rmp) = @_; + + # mit "rum" bekleckert, nicht + cf::map::_create_random_map + $path, + $rmp->{wallstyle}, $rmp->{wall_name}, $rmp->{floorstyle}, $rmp->{monsterstyle}, + $rmp->{treasurestyle}, $rmp->{layoutstyle}, $rmp->{doorstyle}, $rmp->{decorstyle}, + $rmp->{origin_map}, $rmp->{final_map}, $rmp->{exitstyle}, $rmp->{this_map}, + $rmp->{exit_on_final_map}, + $rmp->{xsize}, $rmp->{ysize}, + $rmp->{expand2x}, $rmp->{layoutoptions1}, $rmp->{layoutoptions2}, $rmp->{layoutoptions3}, + $rmp->{symmetry}, $rmp->{difficulty}, $rmp->{difficulty_given}, $rmp->{difficulty_increase}, + $rmp->{dungeon_level}, $rmp->{dungeon_depth}, $rmp->{decoroptions}, $rmp->{orientation}, + $rmp->{origin_y}, $rmp->{origin_x}, $rmp->{random_seed}, $rmp->{total_map_hp}, + $rmp->{map_layout_style}, $rmp->{treasureoptions}, $rmp->{symmetry_used}, + $rmp->{region} +} + +sub parse_random_map_params { + my ($spec) = @_; + + my $rmp; + + for (split /\n/, $spec) { + my ($k, $v) = split /\s+/, $_, 2; + + $rmp->{lc $k} = $v if (length $k) && (length $v); + } + + $rmp +} + +sub prepare_random_map { + my ($exit) = @_; + + my $rmp = parse_random_map_params $exit->msg; + use Data::Dumper; + die Dumper $rmp; +} + sub sync_job(&) { my ($job) = @_; @@ -194,6 +237,7 @@ Event::one_event unless Coro::nready; } + warn "sync<@res>\n";#d# wantarray ? @res : $res[0] } @@ -226,10 +270,10 @@ $map } -sub cf::map::find_map_nb { +sub cf::map::find_map { my ($path, $origin) = @_; - warn "find_map_nb<$path,$origin>\n";#d# + warn "find_map<$path,$origin>\n";#d# $path = ref $path ? $path : new cf::path $path, $origin && $origin->path; my $key = $path->as_string; @@ -241,39 +285,26 @@ if (!$map) { $map = try_load_header $path->load_path or return; - } - $map or return; + $map->instantiate; + + # per-player maps become, after loading, normal maps + $map->per_player (0) if $path->{user_rel}; + } - $map->instantiate; $map->path ($key); $map->{path} = $path; - $map->per_player (0) if $path->{user_rel}; - $map->reset if $map->should_reset; $cf::MAP{$key} = $map } } -sub cf::map::find_map { - my ($path, $origin) = @_; - - $path = new cf::path $path, $origin && $origin->path; - my $key = $path->as_string; - - warn "find_map<$path,$origin>\n";#d# - - $cf::MAP{$key} || sync_job { - cf::map::find_map_nb $path; - } -} - -sub cf::map::do_load_nb { +sub cf::map::load { my ($self) = @_; - return 0 unless $self->in_memory == cf::MAP_SWAPPED; + return if $self->in_memory != cf::MAP_SWAPPED; $self->in_memory (cf::MAP_LOADING); @@ -299,18 +330,22 @@ $self->set_darkness_map; $self->difficulty ($self->estimate_difficulty) unless $self->difficulty; + $self->activate; $self->in_memory (cf::MAP_IN_MEMORY); } -sub cf::map::do_load { - my ($self) = @_; +sub cf::map::load_map_sync { + my ($path, $origin) = @_; - warn "do_load<$self>\n";#d# + warn "load_map_sync<$path, $origin>\n";#d# sync_job { - cf::map::do_load_nb $self; - }; + my $map = cf::map::find_map $path, $origin + or return; + $map->load; + $map + } } sub cf::map::save { @@ -335,7 +370,10 @@ sub cf::map::swap_out { my ($self) = @_; - $self->save if $self->in_memory == cf::MAP_IN_MEMORY; + return if $self->players; + return if $self->in_memory != cf::MAP_IN_MEMORY; + + $self->save; $self->clear; $self->in_memory (cf::MAP_SWAPPED); } @@ -345,7 +383,6 @@ # TODO: safety, remove and allow resettable per-player maps return if $map->{path}{user_rel};#d# - return if $map->per_player; return unless $map->reset_timeout; my $time = $map->fixed_resettime ? $map->reset_time : $map->last_access; @@ -373,42 +410,45 @@ sub cf::object::player::enter_exit { my ($ob, $exit) = @_; - # if at login, move to interim map immediately - unless ($exit) { - # used on login only - $ob->enter_map ($LINK_MAP, 0, 0); - } + return unless $ob->type == cf::PLAYER; + + my ($oldmap, $oldx, $oldy) = ($ob->map, $ob->x, $ob->y); #TODO: do this in the background, freeze the player if required sync_job { my ($map, $x, $y); - unless ($exit) { - # used on login only(?) - $map = cf::map::find_map_nb $ob->contr->maplevel; - ($x, $y) = ($ob->x, $ob->y); - } else { - my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; - - $map = cf::map::find_map_nb $path->as_string; - $map = $map->customise_for ($ob) if $map; - ($x, $y) = ($exit->stats->hp, $exit->stats->sp); + if ($exit->slaying eq "/!") { + prepare_random_map $exit; } - unless ($map) { - $map = cf::map::find_map_nb $emergency_position->[0] - or die "FATAL: cannot load emergency map\n"; - $x = $emergency_position->[1]; - $y = $emergency_position->[2]; - } + my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; - if ($map) { - warn "entering ", $map->path, " at ($x, $y)\n";#d# - $map->do_load_nb; - $ob->enter_map ($map, $x, $y); - } else { + $map = cf::map::find_map $path->as_string; + $map = $map->customise_for ($ob) if $map; + ($x, $y) = ($exit->stats->hp, $exit->stats->sp); + + unless ($map) { $ob->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED); + + # restore original map position + ($map, $x, $y) = ($oldmap, $oldx, $oldy); + + unless ($map) { + $map = cf::map::find_map $emergency_position->[0] + or die "FATAL: cannot load emergency map\n"; + $x = $emergency_position->[1]; + $y = $emergency_position->[2]; + } } + + # use -1, -1 as default coordinates, not 0, 0 + ($x, $y) = ($map->enter_x, $map->enter_y) + if $x <=0 && $y <= 0; + + warn "entering ", $map->path, " at ($x, $y)\n";#d# + $map->load; + $ob->enter_map ($map, $x, $y); } } @@ -416,7 +456,7 @@ my ($map, $ob) = @_; if ($map->per_player) { - return cf::map::find_map_nb "~" . $ob->name . "/" . $map->{path}{path}; + return cf::map::find_map "~" . $ob->name . "/" . $map->{path}{path}; } $map