… | |
… | |
472 | } |
472 | } |
473 | |
473 | |
474 | # escape the /'s in the path |
474 | # escape the /'s in the path |
475 | sub _escaped_path { |
475 | sub _escaped_path { |
476 | (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/g; |
476 | (my $path = $_[0]{path}) =~ s/\//$PATH_SEP/g; |
|
|
477 | |
477 | $path |
478 | $path |
478 | } |
479 | } |
479 | |
480 | |
480 | # the original (read-only) location |
481 | # the original (read-only) location |
481 | sub load_path { |
482 | sub load_path { |
… | |
… | |
486 | |
487 | |
487 | # the temporary/swap location |
488 | # the temporary/swap location |
488 | sub save_path { |
489 | sub save_path { |
489 | my ($self) = @_; |
490 | my ($self) = @_; |
490 | |
491 | |
|
|
492 | $self->{user_rel} |
491 | $self->{user_rel} ? sprintf "%s/%s/%s/%s", cf::localdir, cf::playerdir, $self->{user}, $self->_escaped_path |
493 | ? sprintf "%s/%s/%s/%s", cf::localdir, cf::playerdir, $self->{user}, $self->_escaped_path |
492 | : $self->{random} ? sprintf "%s/%s", $RANDOM_MAPS, $self->{path} |
|
|
493 | : sprintf "%s/%s/%s", cf::localdir, cf::tmpdir, $self->_escaped_path |
494 | : sprintf "%s/%s/%s", cf::localdir, cf::tmpdir, $self->_escaped_path |
494 | } |
495 | } |
495 | |
496 | |
496 | # the unique path, undef == no special unique path |
497 | # the unique path, undef == no special unique path |
497 | sub uniq_path { |
498 | sub uniq_path { |
498 | my ($self) = @_; |
499 | my ($self) = @_; |
499 | |
500 | |
|
|
501 | $self->{user_rel} || $self->{ext} |
|
|
502 | ? undef |
500 | sprintf "%s/%s/%s", cf::localdir, cf::uniquedir, $self->_escaped_path |
503 | : sprintf "%s/%s/%s", cf::localdir, cf::uniquedir, $self->_escaped_path |
|
|
504 | } |
|
|
505 | |
|
|
506 | sub customise_for { |
|
|
507 | my ($self, $map, $ob) = @_; |
|
|
508 | |
|
|
509 | if ($map->per_player) { |
|
|
510 | return cf::map::find ("~" . $ob->name . "/" . $map->{path}{path}); |
|
|
511 | } |
|
|
512 | |
|
|
513 | $map |
501 | } |
514 | } |
502 | |
515 | |
503 | # this is somewhat ugly, but style maps do need special treatment |
516 | # this is somewhat ugly, but style maps do need special treatment |
504 | sub is_style_map { |
517 | sub is_style_map { |
505 | $_[0]{path} =~ m{^/styles/} |
518 | $_[0]{path} =~ m{^/styles/} |
… | |
… | |
513 | |
526 | |
514 | sub load_temp { |
527 | sub load_temp { |
515 | my ($self) = @_; |
528 | my ($self) = @_; |
516 | |
529 | |
517 | &cf::map::load_map_header ($self->save_path) |
530 | &cf::map::load_map_header ($self->save_path) |
|
|
531 | } |
|
|
532 | |
|
|
533 | sub unlink_save { |
|
|
534 | my ($self) = @_; |
|
|
535 | |
|
|
536 | utf8::encode (my $save = $self->save_path); |
|
|
537 | IO::AIO::aioreq_pri 4; IO::AIO::aio_unlink $save; |
|
|
538 | IO::AIO::aioreq_pri 4; IO::AIO::aio_unlink "$save.pst"; |
518 | } |
539 | } |
519 | |
540 | |
520 | package cf; |
541 | package cf; |
521 | |
542 | |
522 | ############################################################################# |
543 | ############################################################################# |
… | |
… | |
1265 | |
1286 | |
1266 | sub generate_random_map { |
1287 | sub generate_random_map { |
1267 | my ($path, $rmp) = @_; |
1288 | my ($path, $rmp) = @_; |
1268 | |
1289 | |
1269 | # mit "rum" bekleckern, nicht |
1290 | # mit "rum" bekleckern, nicht |
1270 | cf::map::_create_random_map |
1291 | cf::map::_create_random_map ( |
1271 | $path, |
1292 | $path, |
1272 | $rmp->{wallstyle}, $rmp->{wall_name}, $rmp->{floorstyle}, $rmp->{monsterstyle}, |
1293 | $rmp->{wallstyle}, $rmp->{wall_name}, $rmp->{floorstyle}, $rmp->{monsterstyle}, |
1273 | $rmp->{treasurestyle}, $rmp->{layoutstyle}, $rmp->{doorstyle}, $rmp->{decorstyle}, |
1294 | $rmp->{treasurestyle}, $rmp->{layoutstyle}, $rmp->{doorstyle}, $rmp->{decorstyle}, |
1274 | $rmp->{origin_map}, $rmp->{final_map}, $rmp->{exitstyle}, $rmp->{this_map}, |
1295 | $rmp->{origin_map}, $rmp->{final_map}, $rmp->{exitstyle}, $rmp->{this_map}, |
1275 | $rmp->{exit_on_final_map}, |
1296 | $rmp->{exit_on_final_map}, |
… | |
… | |
1277 | $rmp->{expand2x}, $rmp->{layoutoptions1}, $rmp->{layoutoptions2}, $rmp->{layoutoptions3}, |
1298 | $rmp->{expand2x}, $rmp->{layoutoptions1}, $rmp->{layoutoptions2}, $rmp->{layoutoptions3}, |
1278 | $rmp->{symmetry}, $rmp->{difficulty}, $rmp->{difficulty_given}, $rmp->{difficulty_increase}, |
1299 | $rmp->{symmetry}, $rmp->{difficulty}, $rmp->{difficulty_given}, $rmp->{difficulty_increase}, |
1279 | $rmp->{dungeon_level}, $rmp->{dungeon_depth}, $rmp->{decoroptions}, $rmp->{orientation}, |
1300 | $rmp->{dungeon_level}, $rmp->{dungeon_depth}, $rmp->{decoroptions}, $rmp->{orientation}, |
1280 | $rmp->{origin_y}, $rmp->{origin_x}, $rmp->{random_seed}, $rmp->{total_map_hp}, |
1301 | $rmp->{origin_y}, $rmp->{origin_x}, $rmp->{random_seed}, $rmp->{total_map_hp}, |
1281 | $rmp->{map_layout_style}, $rmp->{treasureoptions}, $rmp->{symmetry_used}, |
1302 | $rmp->{map_layout_style}, $rmp->{treasureoptions}, $rmp->{symmetry_used}, |
1282 | (cf::region::find $rmp->{region}) |
1303 | (cf::region::find $rmp->{region}), $rmp->{custom} |
|
|
1304 | ) |
1283 | } |
1305 | } |
1284 | |
1306 | |
1285 | # and all this just because we cannot iterate over |
1307 | # and all this just because we cannot iterate over |
1286 | # all maps in C++... |
1308 | # all maps in C++... |
1287 | sub change_all_map_light { |
1309 | sub change_all_map_light { |
… | |
… | |
1399 | |
1421 | |
1400 | if ($self->{path}->is_style_map) { |
1422 | if ($self->{path}->is_style_map) { |
1401 | $self->{deny_save} = 1; |
1423 | $self->{deny_save} = 1; |
1402 | $self->{deny_reset} = 1; |
1424 | $self->{deny_reset} = 1; |
1403 | } else { |
1425 | } else { |
|
|
1426 | $self->decay_objects; |
1404 | $self->fix_auto_apply; |
1427 | $self->fix_auto_apply; |
1405 | $self->decay_objects; |
|
|
1406 | $self->update_buttons; |
1428 | $self->update_buttons; |
1407 | $self->set_darkness_map; |
1429 | $self->set_darkness_map; |
1408 | $self->difficulty ($self->estimate_difficulty) |
1430 | $self->difficulty ($self->estimate_difficulty) |
1409 | unless $self->difficulty; |
1431 | unless $self->difficulty; |
1410 | $self->activate; |
1432 | $self->activate; |
… | |
… | |
1546 | my ($self) = @_; |
1568 | my ($self) = @_; |
1547 | |
1569 | |
1548 | $self->reset_at <= $cf::RUNTIME |
1570 | $self->reset_at <= $cf::RUNTIME |
1549 | } |
1571 | } |
1550 | |
1572 | |
1551 | sub unlink_save { |
|
|
1552 | my ($self) = @_; |
|
|
1553 | |
|
|
1554 | utf8::encode (my $save = $self->{path}->save_path); |
|
|
1555 | aioreq_pri 3; IO::AIO::aio_unlink $save; |
|
|
1556 | aioreq_pri 3; IO::AIO::aio_unlink "$save.pst"; |
|
|
1557 | } |
|
|
1558 | |
|
|
1559 | sub rename { |
1573 | sub rename { |
1560 | my ($self, $new_path) = @_; |
1574 | my ($self, $new_path) = @_; |
1561 | |
1575 | |
1562 | $self->unlink_save; |
1576 | $self->{path}->unlink_save; |
1563 | |
1577 | |
1564 | delete $cf::MAP{$self->path}; |
1578 | delete $cf::MAP{$self->path}; |
1565 | $self->{path} = new cf::path $new_path; |
1579 | $self->{path} = new cf::path $new_path; |
1566 | $self->path ($self->{path}->as_string); |
1580 | $self->path ($self->{path}->as_string); |
1567 | $cf::MAP{$self->path} = $self; |
1581 | $cf::MAP{$self->path} = $self; |
… | |
… | |
1581 | |
1595 | |
1582 | delete $cf::MAP{$self->path}; |
1596 | delete $cf::MAP{$self->path}; |
1583 | |
1597 | |
1584 | $_->clear_links_to ($self) for values %cf::MAP; |
1598 | $_->clear_links_to ($self) for values %cf::MAP; |
1585 | |
1599 | |
1586 | $self->unlink_save; |
1600 | $self->{path}->unlink_save; |
1587 | $self->destroy; |
1601 | $self->destroy; |
1588 | } |
1602 | } |
1589 | |
1603 | |
1590 | my $nuke_counter = "aaaa"; |
1604 | my $nuke_counter = "aaaa"; |
1591 | |
1605 | |
… | |
… | |
1594 | |
1608 | |
1595 | $self->{deny_save} = 1; |
1609 | $self->{deny_save} = 1; |
1596 | $self->reset_timeout (1); |
1610 | $self->reset_timeout (1); |
1597 | $self->rename ("{nuke}/" . ($nuke_counter++)); |
1611 | $self->rename ("{nuke}/" . ($nuke_counter++)); |
1598 | $self->reset; # polite request, might not happen |
1612 | $self->reset; # polite request, might not happen |
1599 | } |
|
|
1600 | |
|
|
1601 | sub customise_for { |
|
|
1602 | my ($map, $ob) = @_; |
|
|
1603 | |
|
|
1604 | if ($map->per_player) { |
|
|
1605 | return cf::map::find "~" . $ob->name . "/" . $map->{path}{path}; |
|
|
1606 | } |
|
|
1607 | |
|
|
1608 | $map |
|
|
1609 | } |
1613 | } |
1610 | |
1614 | |
1611 | =item cf::map::unique_maps |
1615 | =item cf::map::unique_maps |
1612 | |
1616 | |
1613 | Returns an arrayref of cf::path's of all shared maps that have |
1617 | Returns an arrayref of cf::path's of all shared maps that have |
… | |
… | |
1813 | |
1817 | |
1814 | $self->enter_link; |
1818 | $self->enter_link; |
1815 | |
1819 | |
1816 | (async { |
1820 | (async { |
1817 | my $map = cf::map::find $path->as_string; |
1821 | my $map = cf::map::find $path->as_string; |
1818 | $map = $map->customise_for ($self) if $map; |
1822 | $map = $map->{path}->customise_for ($map, $self) if $map; |
1819 | |
1823 | |
1820 | # warn "entering ", $map->path, " at ($x, $y)\n" |
1824 | # warn "entering ", $map->path, " at ($x, $y)\n" |
1821 | # if $map; |
1825 | # if $map; |
1822 | |
1826 | |
1823 | $map or $self->message ("The exit to '" . ($path->visible_name) . "' is closed", cf::NDI_UNIQUE | cf::NDI_RED); |
1827 | $map or $self->message ("The exit to '" . ($path->visible_name) . "' is closed", cf::NDI_UNIQUE | cf::NDI_RED); |
… | |
… | |
2466 | reentrant => 0, |
2470 | reentrant => 0, |
2467 | prio => 0, |
2471 | prio => 0, |
2468 | at => $NEXT_TICK || $TICK, |
2472 | at => $NEXT_TICK || $TICK, |
2469 | data => WF_AUTOCANCEL, |
2473 | data => WF_AUTOCANCEL, |
2470 | cb => sub { |
2474 | cb => sub { |
|
|
2475 | $NOW = Event::time; |
|
|
2476 | |
2471 | cf::server_tick; # one server iteration |
2477 | cf::server_tick; # one server iteration |
2472 | $RUNTIME += $TICK; |
2478 | $RUNTIME += $TICK; |
2473 | $NEXT_TICK += $TICK; |
2479 | $NEXT_TICK += $TICK; |
2474 | |
2480 | |
2475 | $WAIT_FOR_TICK->broadcast; |
2481 | $WAIT_FOR_TICK->broadcast; |