… | |
… | |
147 | or warn "unable to write runtime file: $!"; |
147 | or warn "unable to write runtime file: $!"; |
148 | |
148 | |
149 | for my $map (values %cf::MAP) { |
149 | for my $map (values %cf::MAP) { |
150 | eval { |
150 | eval { |
151 | next if $map->in_memory != cf::MAP_IN_MEMORY; |
151 | next if $map->in_memory != cf::MAP_IN_MEMORY; |
|
|
152 | next if $map->players; |
152 | my $last_access = $map->last_access; |
153 | my $last_access = $map->last_access; |
153 | # not yet, because maps might become visible to players nearby |
154 | # not yet, because maps might become visible to players nearby |
154 | # we need a tiled meta map for this to work |
155 | # we need a tiled meta map for this to work |
155 | # if ($last_access + $DEACTIVATE_TIMEOUT <= $cf::RUNTIME) { |
156 | # if ($last_access + $DEACTIVATE_TIMEOUT <= $cf::RUNTIME) { |
156 | # $map->deactivate; |
157 | # $map->deactivate; |
… | |
… | |
261 | my ($path, $origin) = @_; |
262 | my ($path, $origin) = @_; |
262 | |
263 | |
263 | $path = new cf::path $path, $origin && $origin->path; |
264 | $path = new cf::path $path, $origin && $origin->path; |
264 | my $key = $path->as_string; |
265 | my $key = $path->as_string; |
265 | |
266 | |
266 | warn "find_map<$path,$origin>\n";#d# |
|
|
267 | |
|
|
268 | $cf::MAP{$key} || sync_job { |
267 | $cf::MAP{$key} || sync_job { |
269 | cf::map::find_map_nb $path; |
268 | cf::map::find_map_nb $path; |
270 | } |
269 | } |
271 | } |
270 | } |
272 | |
271 | |
… | |
… | |
297 | $self->decay_objects; |
296 | $self->decay_objects; |
298 | $self->update_buttons; |
297 | $self->update_buttons; |
299 | $self->set_darkness_map; |
298 | $self->set_darkness_map; |
300 | $self->difficulty ($self->estimate_difficulty) |
299 | $self->difficulty ($self->estimate_difficulty) |
301 | unless $self->difficulty; |
300 | unless $self->difficulty; |
|
|
301 | $self->activate; |
302 | |
302 | |
303 | $self->in_memory (cf::MAP_IN_MEMORY); |
303 | $self->in_memory (cf::MAP_IN_MEMORY); |
304 | } |
304 | } |
305 | |
305 | |
306 | sub cf::map::do_load { |
306 | sub cf::map::do_load { |
… | |
… | |
333 | } |
333 | } |
334 | |
334 | |
335 | sub cf::map::swap_out { |
335 | sub cf::map::swap_out { |
336 | my ($self) = @_; |
336 | my ($self) = @_; |
337 | |
337 | |
|
|
338 | return if $self->players; |
|
|
339 | |
338 | $self->save if $self->in_memory == cf::MAP_IN_MEMORY; |
340 | $self->save if $self->in_memory == cf::MAP_IN_MEMORY; |
339 | $self->clear; |
341 | $self->clear; |
340 | $self->in_memory (cf::MAP_SWAPPED); |
342 | $self->in_memory (cf::MAP_SWAPPED); |
341 | } |
343 | } |
342 | |
344 | |
… | |
… | |
371 | } |
373 | } |
372 | |
374 | |
373 | sub cf::object::player::enter_exit { |
375 | sub cf::object::player::enter_exit { |
374 | my ($ob, $exit) = @_; |
376 | my ($ob, $exit) = @_; |
375 | |
377 | |
376 | # if at login, move to interim map immediately |
378 | return unless $ob->type == cf::PLAYER; |
377 | unless ($exit) { |
379 | |
378 | # used on login only |
380 | my ($oldmap, $oldx, $oldy) = ($ob->map, $ob->x, $ob->y); |
379 | $ob->enter_map ($LINK_MAP, 0, 0); |
|
|
380 | } |
|
|
381 | |
381 | |
382 | #TODO: do this in the background, freeze the player if required |
382 | #TODO: do this in the background, freeze the player if required |
383 | sync_job { |
383 | sync_job { |
384 | my ($map, $x, $y); |
384 | my ($map, $x, $y); |
385 | |
385 | |
386 | unless ($exit) { |
386 | if ($exit->slaying eq "!") { |
387 | # used on login only(?) |
|
|
388 | $map = cf::map::find_map_nb $ob->contr->maplevel; |
|
|
389 | ($x, $y) = ($ob->x, $ob->y); |
|
|
390 | } else { |
387 | } else { |
391 | my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; |
388 | my $path = new cf::path $exit->slaying, $exit->map && $exit->map->path; |
392 | |
389 | |
393 | $map = cf::map::find_map_nb $path->as_string; |
390 | $map = cf::map::find_map_nb $path->as_string; |
394 | $map = $map->customise_for ($ob) if $map; |
391 | $map = $map->customise_for ($ob) if $map; |
395 | ($x, $y) = ($exit->stats->hp, $exit->stats->sp); |
392 | ($x, $y) = ($exit->stats->hp, $exit->stats->sp); |
396 | } |
393 | } |
397 | |
394 | |
398 | unless ($map) { |
395 | unless ($map) { |
399 | $map = cf::map::find_map_nb $emergency_position->[0] |
|
|
400 | or die "FATAL: cannot load emergency map\n"; |
|
|
401 | $x = $emergency_position->[1]; |
|
|
402 | $y = $emergency_position->[2]; |
|
|
403 | } |
|
|
404 | |
|
|
405 | if ($map) { |
|
|
406 | warn "entering ", $map->path, " at ($x, $y)\n";#d# |
|
|
407 | $map->do_load_nb; |
|
|
408 | $ob->enter_map ($map, $x, $y); |
|
|
409 | } else { |
|
|
410 | $ob->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED); |
396 | $ob->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED); |
|
|
397 | |
|
|
398 | # restore original map position |
|
|
399 | ($map, $x, $y) = ($oldmap, $oldx, $oldy); |
|
|
400 | |
|
|
401 | unless ($map) { |
|
|
402 | $map = cf::map::find_map_nb $emergency_position->[0] |
|
|
403 | or die "FATAL: cannot load emergency map\n"; |
|
|
404 | $x = $emergency_position->[1]; |
|
|
405 | $y = $emergency_position->[2]; |
411 | } |
406 | } |
|
|
407 | } |
|
|
408 | |
|
|
409 | # use -1, -1 as default coordinates, not 0, 0 |
|
|
410 | ($x, $y) = ($map->enter_x, $map->enter_y) |
|
|
411 | if $x <=0 && $y <= 0; |
|
|
412 | |
|
|
413 | warn "entering ", $map->path, " at ($x, $y)\n";#d# |
|
|
414 | $map->do_load_nb; |
|
|
415 | $ob->enter_map ($map, $x, $y); |
412 | } |
416 | } |
413 | } |
417 | } |
414 | |
418 | |
415 | sub cf::map::customise_for { |
419 | sub cf::map::customise_for { |
416 | my ($map, $ob) = @_; |
420 | my ($map, $ob) = @_; |