ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.560 by root, Fri Apr 22 02:03:12 2011 UTC vs.
Revision 1.569 by root, Wed May 4 07:36:40 2011 UTC

1# 1#
2# This file is part of Deliantra, the Roguelike Realtime MMORPG. 2# This file is part of Deliantra, the Roguelike Realtime MMORPG.
3# 3#
4# Copyright (©) 2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4# Copyright (©) 2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5# 5#
6# Deliantra is free software: you can redistribute it and/or modify it under 6# Deliantra is free software: you can redistribute it and/or modify it under
7# the terms of the Affero GNU General Public License as published by the 7# the terms of the Affero GNU General Public License as published by the
8# Free Software Foundation, either version 3 of the License, or (at your 8# Free Software Foundation, either version 3 of the License, or (at your
9# option) any later version. 9# option) any later version.
1555 1555
1556 while (my ($k, $v) = each %todo) { 1556 while (my ($k, $v) = each %todo) {
1557 cf::cleanup "mandatory extension '$k' has unresolved dependencies, exiting." 1557 cf::cleanup "mandatory extension '$k' has unresolved dependencies, exiting."
1558 if exists $v->{meta}{mandatory}; 1558 if exists $v->{meta}{mandatory};
1559 } 1559 }
1560
1561 last;
1560 } 1562 }
1561 } 1563 }
1562 }; 1564 };
1563} 1565}
1564 1566
1992 1994
1993 Carp::cluck "unable to resolve path '$path' (base '$base')"; 1995 Carp::cluck "unable to resolve path '$path' (base '$base')";
1994 () 1996 ()
1995} 1997}
1996 1998
1999# may re-bless or do other evil things
1997sub init { 2000sub init {
1998 my ($self) = @_; 2001 my ($self) = @_;
1999 2002
2000 $self 2003 $self
2001} 2004}
2066 $self->{load_path} = $path; 2069 $self->{load_path} = $path;
2067 2070
2068 1 2071 1
2069} 2072}
2070 2073
2074# used to laod the header of an original map
2071sub load_header_orig { 2075sub load_header_orig {
2072 my ($self) = @_; 2076 my ($self) = @_;
2073 2077
2074 $self->load_header_from ($self->load_path) 2078 $self->load_header_from ($self->load_path)
2075} 2079}
2076 2080
2081# used to laod the header of an instantiated map
2077sub load_header_temp { 2082sub load_header_temp {
2078 my ($self) = @_; 2083 my ($self) = @_;
2079 2084
2080 $self->load_header_from ($self->save_path) 2085 $self->load_header_from ($self->save_path)
2081} 2086}
2082 2087
2088# called after loading the header from an instantiated map
2083sub prepare_temp { 2089sub prepare_temp {
2084 my ($self) = @_; 2090 my ($self) = @_;
2085 2091
2086 $self->last_access ((delete $self->{last_access}) 2092 $self->last_access ((delete $self->{last_access})
2087 || $cf::RUNTIME); #d# 2093 || $cf::RUNTIME); #d#
2088 # safety 2094 # safety
2089 $self->{instantiate_time} = $cf::RUNTIME 2095 $self->{instantiate_time} = $cf::RUNTIME
2090 if $self->{instantiate_time} > $cf::RUNTIME; 2096 if $self->{instantiate_time} > $cf::RUNTIME;
2091} 2097}
2092 2098
2099# called after loading the header from an original map
2093sub prepare_orig { 2100sub prepare_orig {
2094 my ($self) = @_; 2101 my ($self) = @_;
2095 2102
2096 $self->{load_original} = 1; 2103 $self->{load_original} = 1;
2097 $self->{instantiate_time} = $cf::RUNTIME; 2104 $self->{instantiate_time} = $cf::RUNTIME;
2123sub find { 2130sub find {
2124 my ($path, $origin) = @_; 2131 my ($path, $origin) = @_;
2125 2132
2126 cf::cede_to_tick; 2133 cf::cede_to_tick;
2127 2134
2128 $path = normalise $path, $origin && $origin->path; 2135 $path = normalise $path, $origin;
2129 2136
2130 my $guard1 = cf::lock_acquire "map_data:$path";#d#remove 2137 my $guard1 = cf::lock_acquire "map_data:$path";#d#remove
2131 my $guard2 = cf::lock_acquire "map_find:$path"; 2138 my $guard2 = cf::lock_acquire "map_find:$path";
2132 2139
2133 $cf::MAP{$path} || do { 2140 $cf::MAP{$path} || do {
2166 my $guard = cf::lock_acquire "map_data:$path"; 2173 my $guard = cf::lock_acquire "map_data:$path";
2167 2174
2168 return unless $self->valid; 2175 return unless $self->valid;
2169 return unless $self->in_memory == cf::MAP_SWAPPED; 2176 return unless $self->in_memory == cf::MAP_SWAPPED;
2170 2177
2171 $self->in_memory (cf::MAP_LOADING);
2172
2173 $self->alloc; 2178 $self->alloc;
2174 2179
2175 $self->pre_load; 2180 $self->pre_load;
2176 cf::cede_to_tick; 2181 cf::cede_to_tick;
2177 2182
2183 if (exists $self->{load_path}) {
2178 my $f = new_from_file cf::object::thawer $self->{load_path}; 2184 my $f = new_from_file cf::object::thawer $self->{load_path};
2179 $f->skip_block; 2185 $f->skip_block;
2180 $self->_load_objects ($f) 2186 $self->_load_objects ($f)
2181 or return; 2187 or return;
2182 2188
2183 $self->post_load_original 2189 $self->post_load_original
2184 if delete $self->{load_original}; 2190 if delete $self->{load_original};
2185 2191
2186 if (my $uniq = $self->uniq_path) { 2192 if (my $uniq = $self->uniq_path) {
2187 utf8::encode $uniq; 2193 utf8::encode $uniq;
2188 unless (aio_stat $uniq) { 2194 unless (aio_stat $uniq) {
2189 if (my $f = new_from_file cf::object::thawer $uniq) { 2195 if (my $f = new_from_file cf::object::thawer $uniq) {
2190 $self->clear_unique_items; 2196 $self->clear_unique_items;
2191 $self->_load_objects ($f); 2197 $self->_load_objects ($f);
2192 $f->resolve_delayed_derefs; 2198 $f->resolve_delayed_derefs;
2199 }
2193 } 2200 }
2194 } 2201 }
2195 }
2196 2202
2197 $f->resolve_delayed_derefs; 2203 $f->resolve_delayed_derefs;
2204 } else {
2205 $self->post_load_original
2206 if delete $self->{load_original};
2207 }
2208
2209 $self->in_memory (cf::MAP_INACTIVE);
2198 2210
2199 cf::cede_to_tick; 2211 cf::cede_to_tick;
2200 # now do the right thing for maps 2212 # now do the right thing for maps
2201 $self->link_multipart_objects; 2213 $self->link_multipart_objects;
2202 $self->difficulty ($self->estimate_difficulty) 2214 $self->difficulty ($self->estimate_difficulty)
2206 unless ($self->{deny_activate}) { 2218 unless ($self->{deny_activate}) {
2207 $self->decay_objects; 2219 $self->decay_objects;
2208 $self->fix_auto_apply; 2220 $self->fix_auto_apply;
2209 $self->update_buttons; 2221 $self->update_buttons;
2210 cf::cede_to_tick; 2222 cf::cede_to_tick;
2211 $self->activate; 2223 #$self->activate; # no longer activate maps automatically
2212 } 2224 }
2213 2225
2214 $self->{last_save} = $cf::RUNTIME; 2226 $self->{last_save} = $cf::RUNTIME;
2215 $self->last_access ($cf::RUNTIME); 2227 $self->last_access ($cf::RUNTIME);
2216
2217 $self->in_memory (cf::MAP_ACTIVE);
2218 } 2228 }
2219 2229
2220 $self->post_load; 2230 $self->post_load;
2221 2231
2222 1 2232 1
2265} 2275}
2266 2276
2267sub find_sync { 2277sub find_sync {
2268 my ($path, $origin) = @_; 2278 my ($path, $origin) = @_;
2269 2279
2280 # it's a bug to call this from the main context
2270 return cf::LOG cf::llevError | cf::logBacktrace, "do_find_sync" 2281 return cf::LOG cf::llevError | cf::logBacktrace, "do_find_sync"
2271 if $Coro::current == $Coro::main; 2282 if $Coro::current == $Coro::main;
2272 2283
2273 find $path, $origin 2284 find $path, $origin
2274} 2285}
2275 2286
2276sub do_load_sync { 2287sub do_load_sync {
2277 my ($map) = @_; 2288 my ($map) = @_;
2278 2289
2290 # it's a bug to call this from the main context
2279 return cf::LOG cf::llevError | cf::logBacktrace, "do_load_sync" 2291 return cf::LOG cf::llevError | cf::logBacktrace, "do_load_sync"
2280 if $Coro::current == $Coro::main; 2292 if $Coro::current == $Coro::main;
2281 2293
2282 $map->load; 2294 $map->load;
2283} 2295}
2286our $MAP_PREFETCHER = undef; 2298our $MAP_PREFETCHER = undef;
2287 2299
2288sub find_async { 2300sub find_async {
2289 my ($path, $origin, $load) = @_; 2301 my ($path, $origin, $load) = @_;
2290 2302
2291 $path = normalise $path, $origin && $origin->{path}; 2303 $path = normalise $path, $origin;
2292 2304
2293 if (my $map = $cf::MAP{$path}) { 2305 if (my $map = $cf::MAP{$path}) {
2294 return $map if !$load || $map->in_memory == cf::MAP_ACTIVE; 2306 return $map if !$load || $map->linkable;
2295 } 2307 }
2296 2308
2297 $MAP_PREFETCH{$path} |= $load; 2309 $MAP_PREFETCH{$path} |= $load;
2298 2310
2299 $MAP_PREFETCHER ||= cf::async { 2311 $MAP_PREFETCHER ||= cf::async {
2358sub swap_out { 2370sub swap_out {
2359 my ($self) = @_; 2371 my ($self) = @_;
2360 2372
2361 my $lock = cf::lock_acquire "map_data:$self->{path}"; 2373 my $lock = cf::lock_acquire "map_data:$self->{path}";
2362 2374
2363 return if $self->in_memory != cf::MAP_ACTIVE; 2375 return if !$self->linkable;
2364 return if $self->{deny_save}; 2376 return if $self->{deny_save};
2365 return if $self->players; 2377 return if $self->players;
2366 2378
2367 # first deactivate the map and "unlink" it from the core 2379 # first deactivate the map and "unlink" it from the core
2368 $self->deactivate; 2380 $self->deactivate;
2807 ($path, $x, $y) = (undef, undef, undef); 2819 ($path, $x, $y) = (undef, undef, undef);
2808 } 2820 }
2809 } 2821 }
2810 2822
2811 my $map = eval { 2823 my $map = eval {
2812 my $map = defined $path ? cf::map::find $path : undef; 2824 my $map = defined $path ? cf::map::find $path, $self->map : undef;
2813 2825
2814 if ($map) { 2826 if ($map) {
2815 $map = $map->customise_for ($self); 2827 $map = $map->customise_for ($self);
2816 $map = $check->($map, $x, $y, $self) if $check && $map; 2828 $map = $check->($map, $x, $y, $self) if $check && $map;
2817 } else { 2829 } else {
2907 $Coro::current->{desc} = "enter_exit"; 2919 $Coro::current->{desc} = "enter_exit";
2908 2920
2909 unless (eval { 2921 unless (eval {
2910 $self->deactivate_recursive; # just to be sure 2922 $self->deactivate_recursive; # just to be sure
2911 2923
2912 # random map handling
2913 {
2914 my $guard = cf::lock_acquire "exit_prepare:$exit";
2915
2916 prepare_random_map $exit
2917 if $exit->slaying eq "/!";
2918 }
2919
2920 my $map = cf::map::normalise $exit->slaying, $exit->map && $exit->map->path; 2924 my $map = cf::map::normalise $exit->slaying, $exit->map;
2921 my $x = $exit->stats->hp; 2925 my $x = $exit->stats->hp;
2922 my $y = $exit->stats->sp; 2926 my $y = $exit->stats->sp;
2927
2928 # special map handling
2929 my $slaying = $exit->slaying;
2930
2931 # special map handling
2932 if ($slaying eq "/!") {
2933 my $guard = cf::lock_acquire "exit_prepare:$exit";
2934
2935 prepare_random_map $exit
2936 if $exit->slaying eq "/!"; # need to re-check after getting the lock
2937
2938 $map = $exit->slaying;
2939
2940 } elsif ($slaying eq '!up') {
2941 $map = $exit->map->tile_path (cf::TILE_UP);
2942 $x = $exit->x;
2943 $y = $exit->y;
2944
2945 } elsif ($slaying eq '!down') {
2946 $map = $exit->map->tile_path (cf::TILE_DOWN);
2947 $x = $exit->x;
2948 $y = $exit->y;
2949 }
2923 2950
2924 $self->goto ($map, $x, $y); 2951 $self->goto ($map, $x, $y);
2925 2952
2926 # if exit is damned, update players death & WoR home-position 2953 # if exit is damned, update players death & WoR home-position
2927 $self->contr->savebed ($map, $x, $y) 2954 $self->contr->savebed ($map, $x, $y)
3655 3682
3656sub main { 3683sub main {
3657 cf::init_globals; # initialise logging 3684 cf::init_globals; # initialise logging
3658 3685
3659 LOG llevInfo, "Welcome to Deliantra, v" . VERSION; 3686 LOG llevInfo, "Welcome to Deliantra, v" . VERSION;
3660 LOG llevInfo, "Copyright (C) 2005-2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team."; 3687 LOG llevInfo, "Copyright (C) 2005-2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team.";
3661 LOG llevInfo, "Copyright (C) 1994 Mark Wedel."; 3688 LOG llevInfo, "Copyright (C) 1994 Mark Wedel.";
3662 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; 3689 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen.";
3663 3690
3664 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority 3691 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority
3665 3692

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines