… | |
… | |
25 | |
25 | |
26 | use Glib::Object::Subclass |
26 | use Glib::Object::Subclass |
27 | 'Gtk2::DrawingArea'; |
27 | 'Gtk2::DrawingArea'; |
28 | |
28 | |
29 | use List::Util qw(min max); |
29 | use List::Util qw(min max); |
|
|
30 | |
|
|
31 | #my ($TILE_MINX, $TILE_MINY, $TILE_MAXX, $TILE_MAXY); |
|
|
32 | # |
|
|
33 | #for (values %TILE) { |
|
|
34 | # $TILE_MAXX = max $TILE_MAXX, $_->{w} - 1; |
|
|
35 | # $TILE_MAXY = max $TILE_MAXY, $_->{h} - 1; |
|
|
36 | #} |
|
|
37 | # |
|
|
38 | #for (values %ARCH) { |
|
|
39 | # for (; $_; $_ = $_->{more}) { |
|
|
40 | # $TILE_MINX = min $TILE_MINX, $_->{x}; |
|
|
41 | # $TILE_MINY = min $TILE_MINY, $_->{y}; |
|
|
42 | # $TILE_MAXX = max $TILE_MAXX, $_->{x}; |
|
|
43 | # $TILE_MAXY = max $TILE_MAXY, $_->{y}; |
|
|
44 | # } |
|
|
45 | #} |
30 | |
46 | |
31 | sub INIT_INSTANCE { |
47 | sub INIT_INSTANCE { |
32 | my ($self) = @_; |
48 | my ($self) = @_; |
33 | |
49 | |
34 | $self->signal_connect (destroy => sub { |
50 | $self->signal_connect (destroy => sub { |
… | |
… | |
194 | |
210 | |
195 | $self->{window}->draw_rectangle ($_ & 1 ? $self->style->black_gc : $self->style->white_gc, 0, |
211 | $self->{window}->draw_rectangle ($_ & 1 ? $self->style->black_gc : $self->style->white_gc, 0, |
196 | $x + $_, $y + $_, |
212 | $x + $_, $y + $_, |
197 | TILESIZE - 1 - $_ * 2, TILESIZE - 1 - $_ * 2) |
213 | TILESIZE - 1 - $_ * 2, TILESIZE - 1 - $_ * 2) |
198 | for 0..3; |
214 | for 0..3; |
199 | |
|
|
200 | my $req = $self->{tip}->size_request; |
|
|
201 | $self->{tip}->resize ($req->width, $req->height); |
|
|
202 | }); |
215 | }); |
|
|
216 | |
|
|
217 | my $req = $self->{tip}->size_request; |
|
|
218 | $self->{tip}->resize ($req->width, $req->height); |
203 | } |
219 | } |
204 | |
220 | |
205 | $self->{tip}->move ($x + TILESIZE, $y); |
221 | $self->{tip}->move ($x + TILESIZE, $y); |
206 | $self->{tip}->show_all; |
222 | $self->{tip}->show_all; |
207 | |
223 | |
… | |
… | |
234 | # fill tooltip with info about $x, $y |
250 | # fill tooltip with info about $x, $y |
235 | my $as = $self->{map}{map}[$x][$y] || []; |
251 | my $as = $self->{map}{map}[$x][$y] || []; |
236 | for my $a (reverse @$as) { |
252 | for my $a (reverse @$as) { |
237 | $vbox->add (my $hbox = new Gtk2::HBox 0, 2); |
253 | $vbox->add (my $hbox = new Gtk2::HBox 0, 2); |
238 | |
254 | |
239 | my $tile = $Crossfire::Tilecache::TILECACHE{ $a->{face} || $ARCH->{$a->{_name}}{face} }; |
255 | my $tile = $FACE{ $a->{face} || $ARCH{$a->{_name}}{face} }; |
240 | |
256 | |
241 | # this is awful, is this really the best way? |
257 | # this is awful, is this really the best way? |
242 | my $pb = new Gtk2::Gdk::Pixbuf 'rgb', 1, 8, TILESIZE, TILESIZE; |
258 | my $pb = new Gtk2::Gdk::Pixbuf 'rgb', 1, 8, TILESIZE, TILESIZE; |
243 | $pb->fill (0x00000000); |
259 | $pb->fill (0x00000000); |
244 | |
260 | |
245 | $Crossfire::Tilecache::TILECACHE->composite ($pb, |
261 | $TILE->composite ($pb, |
246 | 0, 0, |
262 | 0, 0, |
247 | TILESIZE, TILESIZE, |
263 | TILESIZE, TILESIZE, |
248 | - ($tile->{idx} % 64) * TILESIZE, - TILESIZE * int $tile->{idx} / 64, |
264 | - ($tile->{idx} % 64) * TILESIZE, - TILESIZE * int $tile->{idx} / 64, |
249 | 1, 1, 'nearest', 255 |
265 | 1, 1, 'nearest', 255 |
250 | ); |
266 | ); |
… | |
… | |
282 | $self->{x} = |
298 | $self->{x} = |
283 | $self->{y} = 0; |
299 | $self->{y} = 0; |
284 | |
300 | |
285 | delete $self->{face}; |
301 | delete $self->{face}; |
286 | delete $self->{face_extents}; |
302 | delete $self->{face_extents}; |
287 | $self->update_map (0, 0, $map->{width}, $map->{height}); |
303 | $self->update_map (0, 0, $map->{width} - 1, $map->{height} - 1); |
288 | delete $self->{tipinfo}; $self->update_tooltip; |
304 | delete $self->{tipinfo}; $self->update_tooltip; |
289 | $self->invalidate_all; |
305 | $self->invalidate_all; |
290 | } |
306 | } |
291 | |
307 | |
292 | sub coord { |
308 | sub coord { |
… | |
… | |
326 | my ($self) = @_; |
342 | my ($self) = @_; |
327 | |
343 | |
328 | $self->queue_draw; |
344 | $self->queue_draw; |
329 | } |
345 | } |
330 | |
346 | |
|
|
347 | sub expose { |
|
|
348 | my ($self, $event) = @_; |
|
|
349 | |
|
|
350 | no integer; |
|
|
351 | |
|
|
352 | my $ox = $self->{x}; my $ix = int $ox / TILESIZE; |
|
|
353 | my $oy = $self->{y}; my $iy = int $oy / TILESIZE; |
|
|
354 | |
|
|
355 | # get_rectangles is buggy in older versions |
|
|
356 | my @rectangles = $Gtk2::VERSION > 1.115 |
|
|
357 | ? $event->region->get_rectangles : $event->area; |
|
|
358 | |
|
|
359 | for my $area (@rectangles) { |
|
|
360 | my ($x, $y, $w, $h) = $area->values; # x y w h |
|
|
361 | |
|
|
362 | my @x = ((int ($ox + $x) / TILESIZE) .. int +($ox + $x + $w + TILESIZE - 1) / TILESIZE); |
|
|
363 | my @y = ((int ($oy + $y) / TILESIZE) .. int +($oy + $y + $h + TILESIZE - 1) / TILESIZE); |
|
|
364 | |
|
|
365 | my $window = $self->{window}; |
|
|
366 | |
|
|
367 | my $pb = new Gtk2::Gdk::Pixbuf 'rgb', 0, 8, TILESIZE * (@x + 1), TILESIZE * (@y + 1); |
|
|
368 | $pb->fill (0xff69b400); |
|
|
369 | |
|
|
370 | for my $x (@x) { |
|
|
371 | my $dx = ($x - $x[0]) * TILESIZE; |
|
|
372 | my $oss = $self->{face}[$x]; |
|
|
373 | |
|
|
374 | for my $y (@y) { |
|
|
375 | my $dy = ($y - $y[0]) * TILESIZE; |
|
|
376 | |
|
|
377 | for my $idx (@{$oss->[$y]}) { |
|
|
378 | $TILE->composite ($pb, |
|
|
379 | $dx, $dy, |
|
|
380 | TILESIZE, TILESIZE, |
|
|
381 | $dx - ($idx % 64) * TILESIZE, $dy - TILESIZE * int $idx / 64, |
|
|
382 | 1, 1, 'nearest', 255 |
|
|
383 | ); |
|
|
384 | } |
|
|
385 | } |
|
|
386 | } |
|
|
387 | |
|
|
388 | $pb->render_to_drawable ($window, $self->style->black_gc, |
|
|
389 | 0, 0, |
|
|
390 | $x[0] * TILESIZE - $ox, $y[0] * TILESIZE - $oy, |
|
|
391 | TILESIZE * @x, TILESIZE * @y, |
|
|
392 | 'max', 0, 0); |
|
|
393 | } |
|
|
394 | |
|
|
395 | $_->[4]->($self, $_->[0] - $self->{x}, $_->[1] - $self->{y}) |
|
|
396 | for values %{ $self->{overlay} || {} }; |
|
|
397 | } |
|
|
398 | |
331 | sub update_map { |
399 | sub update_map { |
332 | my ($self, $x, $y, $w, $h) = @_; |
400 | my ($self, $x1, $y1, $x2, $y2) = @_; |
333 | |
401 | |
334 | delete $self->{tipinfo}; $self->update_tooltip; |
402 | delete $self->{tipinfo}; $self->update_tooltip; |
335 | |
|
|
336 | my ($x1, $y1, $x2, $y2) = ($x, $y, $x + $w - 1, $y + $h - 1); |
|
|
337 | |
403 | |
338 | # push @{ $self->{queue_draw_areay} }, [$x * TILESIZE - $self->{x}, |
404 | # push @{ $self->{queue_draw_areay} }, [$x * TILESIZE - $self->{x}, |
339 | # $y * TILESIZE - $self->{y}, |
405 | # $y * TILESIZE - $self->{y}, |
340 | # $w * TILESIZE, $h * TILESIZE]; |
406 | # $w * TILESIZE, $h * TILESIZE]; |
341 | |
407 | |
342 | # we store precomputed tile info into $self->{face} |
408 | # we store precomputed tile info into $self->{face} |
343 | # and the minimum/maximum extents into $self->{face_extents} |
409 | # and the minimum/maximum extents into $self->{face_extents} |
344 | my $map = $self->{map}{map}; |
410 | my $map = $self->{map}{map}; |
345 | my $ov = $self->{face} ||= []; |
411 | my $ov = $self->{face} ||= []; |
346 | my $ext = $self->{face_extents} ||= []; |
412 | my $ext = $self->{face_extents} ||= []; |
|
|
413 | |
|
|
414 | $x1 = max 0, min $self->{map}{width} - 1, $x1; |
|
|
415 | $y1 = max 0, min $self->{map}{height} - 1, $y1; |
|
|
416 | $x2 = max 0, min $self->{map}{width} - 1, $x2; |
|
|
417 | $y2 = max 0, min $self->{map}{height} - 1, $y2; |
347 | |
418 | |
348 | # extend update area as neccessary to include all bigfaces |
419 | # extend update area as neccessary to include all bigfaces |
349 | # that overlap the update area |
420 | # that overlap the update area |
350 | for (;;) { |
421 | for (;;) { |
351 | my $redo; |
422 | my $redo; |
… | |
… | |
364 | } |
435 | } |
365 | } |
436 | } |
366 | $redo or last; |
437 | $redo or last; |
367 | } |
438 | } |
368 | |
439 | |
369 | my $TC = \%Crossfire::Tilecache::TILECACHE; |
440 | $x1 = max 0, min $self->{map}{width} - 1, $x1; |
|
|
441 | $y1 = max 0, min $self->{map}{height} - 1, $y1; |
|
|
442 | $x2 = max 0, min $self->{map}{width} - 1, $x2; |
|
|
443 | $y2 = max 0, min $self->{map}{height} - 1, $y2; |
370 | |
444 | |
371 | $self->queue_draw_area ( |
445 | $self->queue_draw_area ( |
372 | $x1 * TILESIZE - $self->{x}, $y1 * TILESIZE - $self->{y}, |
446 | $x1 * TILESIZE - $self->{x}, $y1 * TILESIZE - $self->{y}, |
373 | ($x2 - $x1 + 1) * TILESIZE , ($y2 - $y1 + 1) * TILESIZE , |
447 | ($x2 - $x1 + 1) * TILESIZE , ($y2 - $y1 + 1) * TILESIZE , |
374 | ); |
448 | ); |
… | |
… | |
376 | my @ov; |
450 | my @ov; |
377 | |
451 | |
378 | # update overlay map with bigfaces and chained faces |
452 | # update overlay map with bigfaces and chained faces |
379 | my $a; |
453 | my $a; |
380 | for my $x ($x1 .. $x2) { |
454 | for my $x ($x1 .. $x2) { |
381 | my $ass = $self->{map}{map}[$x]; |
455 | my $ass = $map->[$x]; |
382 | my $oss = $ov->[$x] ||= []; |
456 | my $oss = $ov->[$x] ||= []; |
383 | for my $y ($y1 .. $y2) { |
457 | for my $y ($y1 .. $y2) { |
384 | my $os = $oss->[$y] = []; |
458 | my $os = $oss->[$y] = []; |
385 | for my $a (@{ $ass->[$y] || [] }) { |
459 | for my $a (@{ $ass->[$y] || [] }) { |
386 | my $o = $ARCH->{$a->{_name}} |
460 | my $o = $ARCH{$a->{_name}} |
387 | or (warn "arch '$a->{_name}' not found at ($x|$y)\n"), next; |
461 | or (warn "arch '$a->{_name}' not found at ($x|$y)\n"), next; |
388 | |
462 | |
389 | my $tile = $TC->{$a->{face} || $o->{face}} |
463 | my $tile = $FACE{$a->{face} || $o->{face}} |
390 | or (warn "no gfx found for arch '$a->{_name}' at ($x|$y)\n"), next; |
464 | or (warn "no gfx found for arch '$a->{_name}' at ($x|$y)\n"), next; |
391 | |
465 | |
392 | if ($tile->{w} > 1 || $tile->{h} > 1) { |
466 | if ($tile->{w} > 1 || $tile->{h} > 1) { |
393 | # bigfaces |
467 | # bigfaces |
394 | my $maxx = $x + $tile->{w} - 1; |
468 | my $maxx = $x + $tile->{w} - 1; |
… | |
… | |
396 | |
470 | |
397 | for my $ox (0 .. $tile->{w} - 1) { |
471 | for my $ox (0 .. $tile->{w} - 1) { |
398 | for my $oy (0 .. $tile->{h} - 1) { |
472 | for my $oy (0 .. $tile->{h} - 1) { |
399 | my $ext = $ext->[$x + $ox][$y + $oy]; |
473 | my $ext = $ext->[$x + $ox][$y + $oy]; |
400 | |
474 | |
401 | $ext->[0] = $x if $ext->[0] > $x; |
475 | $ext->[0] = min $ext->[0], $x; |
402 | $ext->[1] = $y if $ext->[1] > $y; |
476 | $ext->[1] = min $ext->[1], $y; |
403 | $ext->[2] = $maxx if $ext->[2] < $maxx; |
477 | $ext->[2] = max $ext->[2], $maxx; |
404 | $ext->[3] = $maxy if $ext->[3] < $maxy; |
478 | $ext->[3] = max $ext->[3], $maxy; |
405 | |
479 | |
406 | push @ov, [$x + $ox, $y + $oy, |
480 | push @ov, [$x + $ox, $y + $oy, |
407 | $tile->{idx} + $ox + $oy * $tile->{w}]; |
481 | $tile->{idx} + $ox + $oy * $tile->{w}]; |
408 | } |
482 | } |
409 | } |
483 | } |
410 | |
484 | |
411 | } elsif ($o->{more}) { |
485 | } elsif ($o->{more}) { |
412 | # linked faces, slowest and mosta nnoying |
486 | # linked faces, slowest and most annoying |
413 | |
487 | |
414 | my ($minx, $miny, $maxx, $maxy); |
488 | my ($minx, $miny, $maxx, $maxy); |
415 | |
489 | |
416 | for (my $o = $o; $o; $o = $o->{more}) { |
490 | for (my $o = $o; $o; $o = $o->{more}) { |
417 | $minx = $o->{x} if $minx > $o->{x}; |
491 | $minx = min $minx, $o->{x}; |
418 | $miny = $o->{y} if $miny > $o->{y}; |
492 | $miny = min $miny, $o->{y}; |
419 | $maxx = $o->{x} if $maxx < $o->{x}; |
493 | $maxx = max $maxx, $o->{x}; |
420 | $maxy = $o->{y} if $maxy < $o->{y}; |
494 | $maxy = max $maxy, $o->{y}; |
421 | } |
495 | } |
422 | |
496 | |
423 | $minx += $x; |
497 | $minx += $x; $miny += $y; |
424 | $miny += $y; |
|
|
425 | $maxx += $x; |
498 | $maxx += $x; $maxy += $y; |
426 | $maxy += $y; |
|
|
427 | |
499 | |
428 | for (my $o = $o; $o; $o = $o->{more}) { |
500 | for (my $o = $o; $o; $o = $o->{more}) { |
429 | my $tile = $TC->{$o->{face}} |
501 | my $tile = $FACE{$o->{face}} |
430 | or (warn "no gfx found for arch '$a->{_name}' at ($x*|$y*)\n"), next; |
502 | or (warn "no gfx found for arch '$a->{_name}' at ($x*|$y*)\n"), next; |
431 | |
503 | |
432 | my $ext = $ext->[$x + $o->{x}][$y + $o->{y}]; |
504 | my $ext = $ext->[$x + $o->{x}][$y + $o->{y}]; |
433 | |
505 | |
434 | $ext->[0] = $minx if $ext->[0] > $minx; |
506 | $ext->[0] = min $ext->[0], $minx; |
435 | $ext->[1] = $miny if $ext->[1] > $miny; |
507 | $ext->[1] = min $ext->[1], $miny; |
436 | $ext->[2] = $maxx if $ext->[2] < $maxx; |
508 | $ext->[2] = max $ext->[2], $maxx; |
437 | $ext->[3] = $maxy if $ext->[3] < $maxy; |
509 | $ext->[3] = max $ext->[3], $maxy; |
438 | |
510 | |
439 | push @ov, [$x + $o->{x}, $y + $o->{y}, $tile->{idx}]; |
511 | push @ov, [$x + $o->{x}, $y + $o->{y}, $tile->{idx}]; |
440 | } |
512 | } |
441 | |
513 | |
442 | } else { |
514 | } else { |
… | |
… | |
449 | } |
521 | } |
450 | |
522 | |
451 | # bigger faces always on top, I don't give a shit to those who think otherwise |
523 | # bigger faces always on top, I don't give a shit to those who think otherwise |
452 | for (@ov) { |
524 | for (@ov) { |
453 | my ($x, $y, $idx) = @$_; |
525 | my ($x, $y, $idx) = @$_; |
|
|
526 | |
|
|
527 | next if $x < 0 || $self->{map}{width} <= $x |
|
|
528 | || $y < 0 || $self->{map}{height} <= $y; |
454 | |
529 | |
455 | push @{ $ov->[$x][$y] }, $idx; |
530 | push @{ $ov->[$x][$y] }, $idx; |
456 | } |
531 | } |
457 | |
532 | |
458 | # dump extent info |
533 | # dump extent info |
… | |
… | |
464 | # } |
539 | # } |
465 | # } |
540 | # } |
466 | # } |
541 | # } |
467 | } |
542 | } |
468 | |
543 | |
469 | sub expose { |
544 | sub change_begin { |
470 | my ($self, $event) = @_; |
545 | my ($self, $title) = @_; |
471 | |
546 | |
472 | no integer; |
547 | $self->{change} ||= { |
473 | |
548 | title => $title, |
474 | my $ox = $self->{x}; my $ix = int $ox / TILESIZE; |
|
|
475 | my $oy = $self->{y}; my $iy = int $oy / TILESIZE; |
|
|
476 | |
|
|
477 | # get_rectangles is buggy in older versions |
|
|
478 | my @rectangles = $Gtk2::VERSION > 1.115 |
|
|
479 | ? $event->region->get_rectangles : $event->area; |
|
|
480 | |
|
|
481 | for my $area (@rectangles) { |
|
|
482 | my ($x, $y, $w, $h) = $area->values; # x y w h |
|
|
483 | |
|
|
484 | my @x = ((int ($ox + $x) / TILESIZE) .. int +($ox + $x + $w + TILESIZE - 1) / TILESIZE); |
|
|
485 | my @y = ((int ($oy + $y) / TILESIZE) .. int +($oy + $y + $h + TILESIZE - 1) / TILESIZE); |
|
|
486 | |
|
|
487 | my $PB = $Crossfire::Tilecache::TILECACHE; |
|
|
488 | |
|
|
489 | my $window = $self->{window}; |
|
|
490 | |
|
|
491 | my $pb = new Gtk2::Gdk::Pixbuf 'rgb', 0, 8, TILESIZE * (@x + 1), TILESIZE * (@y + 1); |
|
|
492 | $pb->fill (0x00000000); |
|
|
493 | |
|
|
494 | for my $x (@x) { |
|
|
495 | my $dx = ($x - $x[0]) * TILESIZE; |
|
|
496 | my $oss = $self->{face}[$x]; |
|
|
497 | |
|
|
498 | for my $y (@y) { |
|
|
499 | my $dy = ($y - $y[0]) * TILESIZE; |
|
|
500 | |
|
|
501 | for my $idx (@{$oss->[$y]}) { |
|
|
502 | $PB->composite ($pb, |
|
|
503 | $dx, $dy, |
|
|
504 | TILESIZE, TILESIZE, |
|
|
505 | $dx - ($idx % 64) * TILESIZE, $dy - TILESIZE * int $idx / 64, |
|
|
506 | 1, 1, 'nearest', 255 |
|
|
507 | ); |
|
|
508 | } |
|
|
509 | } |
|
|
510 | } |
|
|
511 | |
|
|
512 | $pb->render_to_drawable ($window, $self->style->black_gc, |
|
|
513 | 0, 0, |
|
|
514 | $x[0] * TILESIZE - $ox, $y[0] * TILESIZE - $oy, |
|
|
515 | TILESIZE * @x, TILESIZE * @y, |
|
|
516 | 'max', 0, 0); |
|
|
517 | } |
549 | }; |
|
|
550 | $self->{change}{nest}++; |
|
|
551 | } |
518 | |
552 | |
519 | $_->[4]->($self, $_->[0] - $self->{x}, $_->[1] - $self->{y}) |
553 | sub get { |
520 | for values %{ $self->{overlay} || {} }; |
554 | my ($self, $x, $y) = @_; |
|
|
555 | |
|
|
556 | $self->{map}{map}[$x][$y] || [] |
|
|
557 | } |
|
|
558 | |
|
|
559 | sub set { |
|
|
560 | my ($self, $x, $y, $as) = @_; |
|
|
561 | |
|
|
562 | $self->{map}{map}[$x][$y] = $as; |
|
|
563 | |
|
|
564 | $self->{update} ||= [$x, $y, $x, $y]; |
|
|
565 | |
|
|
566 | for (@$as) { |
|
|
567 | my ($x1, $y1, $x2, $y2) = arch_extents $_; |
|
|
568 | |
|
|
569 | $self->{update}[0] = min $self->{update}[0], $x + $x1; |
|
|
570 | $self->{update}[1] = min $self->{update}[1], $y + $y1; |
|
|
571 | $self->{update}[2] = max $self->{update}[2], $x + $x2; |
|
|
572 | $self->{update}[3] = max $self->{update}[3], $y + $y2; |
|
|
573 | } |
|
|
574 | |
|
|
575 | $self->{update_idle} ||= add Glib::Idle sub { |
|
|
576 | delete $self->{update_idle}; |
|
|
577 | my $coord = delete $self->{update}; |
|
|
578 | |
|
|
579 | $self->update_map (@$coord); |
|
|
580 | |
|
|
581 | 0 |
|
|
582 | }, undef, 10; |
|
|
583 | } |
|
|
584 | |
|
|
585 | sub change_stack { |
|
|
586 | my ($self, $x, $y, $as) = @_; |
|
|
587 | |
|
|
588 | $self->{change}{map}[$x][$y] ||= [$x, $y, $self->{map}{map}[$x][$y]]; |
|
|
589 | |
|
|
590 | $self->set ($x, $y, $as); |
|
|
591 | } |
|
|
592 | |
|
|
593 | sub change_end { |
|
|
594 | my ($self) = @_; |
|
|
595 | |
|
|
596 | --$self->{change}{nest} and return; |
|
|
597 | |
|
|
598 | my $change = delete $self->{change}; |
|
|
599 | |
|
|
600 | delete $change->{nest}; |
|
|
601 | |
|
|
602 | $change->{set} = [ |
|
|
603 | grep $_, |
|
|
604 | map @$_, |
|
|
605 | grep $_, |
|
|
606 | @{ delete $change->{map} || [] } |
|
|
607 | ]; |
|
|
608 | |
|
|
609 | @{ $change->{set} } or return; |
|
|
610 | |
|
|
611 | $change |
|
|
612 | } |
|
|
613 | |
|
|
614 | sub change_swap { |
|
|
615 | my ($self, $change) = @_; |
|
|
616 | |
|
|
617 | for (@{ $change->{set} }) { |
|
|
618 | my $stack = \$self->{map}{map}[$_->[0]][$_->[1]]; |
|
|
619 | |
|
|
620 | ($$stack, $_->[2]) = ($_->[2], $$stack); |
|
|
621 | } |
521 | } |
622 | } |
522 | |
623 | |
523 | =back |
624 | =back |
524 | |
625 | |
525 | =head1 AUTHOR |
626 | =head1 AUTHOR |