… | |
… | |
281 | |
281 | |
282 | $self->{x} = |
282 | $self->{x} = |
283 | $self->{y} = 0; |
283 | $self->{y} = 0; |
284 | |
284 | |
285 | delete $self->{face}; |
285 | delete $self->{face}; |
|
|
286 | delete $self->{face_extents}; |
286 | $self->update_map (0, 0, $self->{width}, $self->{height}); |
287 | $self->update_map (0, 0, $map->{width}, $map->{height}); |
287 | delete $self->{tipinfo}; $self->update_tooltip; |
288 | delete $self->{tipinfo}; $self->update_tooltip; |
288 | $self->invalidate_all; |
289 | $self->invalidate_all; |
289 | } |
290 | } |
290 | |
291 | |
291 | sub coord { |
292 | sub coord { |
… | |
… | |
330 | sub update_map { |
331 | sub update_map { |
331 | my ($self, $x, $y, $w, $h) = @_; |
332 | my ($self, $x, $y, $w, $h) = @_; |
332 | |
333 | |
333 | delete $self->{tipinfo}; $self->update_tooltip; |
334 | delete $self->{tipinfo}; $self->update_tooltip; |
334 | |
335 | |
|
|
336 | my ($x1, $y1, $x2, $y2) = ($x, $y, $x + $w - 1, $y + $h - 1); |
|
|
337 | |
335 | # push @{ $self->{queue_draw_areay} }, [$x * TILESIZE - $self->{x}, |
338 | # push @{ $self->{queue_draw_areay} }, [$x * TILESIZE - $self->{x}, |
336 | # $y * TILESIZE - $self->{y}, |
339 | # $y * TILESIZE - $self->{y}, |
337 | # $w * TILESIZE, $h * TILESIZE]; |
340 | # $w * TILESIZE, $h * TILESIZE]; |
338 | |
341 | |
339 | $self->{update_map} ||= add Glib::Idle sub { |
342 | # we store precomputed tile info into $self->{face} |
340 | delete $self->{update_map}; |
343 | # and the minimum/maximum extents into $self->{face_extents} |
341 | |
|
|
342 | my $map = $self->{map}{map}; |
344 | my $map = $self->{map}{map}; |
343 | my $ov = $self->{face} ||= []; |
345 | my $ov = $self->{face} ||= []; |
|
|
346 | my $ext = $self->{face_extents} ||= []; |
344 | |
347 | |
345 | my ($x, $w) = (0, $self->{map}{width}); |
348 | # extend update area as neccessary to include all bigfaces |
346 | my ($y, $h) = (0, $self->{map}{height}); |
349 | # that overlap the update area |
|
|
350 | for my $x ($x1 .. $x2) { |
|
|
351 | my $col = $ext->[$x] ||= []; |
|
|
352 | for my $y ($y1 .. $y2) { |
|
|
353 | if (my $ext = $col->[$y]) { |
|
|
354 | $x1 = $ext->[0] if $ext->[0] < $x1; |
|
|
355 | $y1 = $ext->[1] if $ext->[1] < $y1; |
|
|
356 | $x2 = $ext->[2] if $ext->[2] > $x2; |
|
|
357 | $y2 = $ext->[3] if $ext->[3] > $y2; |
|
|
358 | } |
|
|
359 | |
|
|
360 | # reset extents |
|
|
361 | $col->[$y] = [$x, $y, $x, $y]; |
|
|
362 | } |
|
|
363 | } |
347 | |
364 | |
348 | my @x = ($x .. $x + $w - 1); |
|
|
349 | my @y = ($y .. $y + $h - 1); |
|
|
350 | |
|
|
351 | my $TC = \%Crossfire::Tilecache::TILECACHE; |
365 | my $TC = \%Crossfire::Tilecache::TILECACHE; |
352 | |
366 | |
|
|
367 | $self->queue_draw_area ( |
|
|
368 | $x1 * TILESIZE - $self->{x}, $y1 * TILESIZE - $self->{y}, |
|
|
369 | ($x2 - $x1 + 1) * TILESIZE , ($y2 - $y1 + 1) * TILESIZE , |
|
|
370 | ); |
|
|
371 | |
353 | my @ov; |
372 | my @ov; |
354 | |
373 | |
355 | # update overlay map with bigfaces and chained faces |
374 | # update overlay map with bigfaces and chained faces |
356 | my $a; |
375 | my $a; |
357 | for my $x (@x) { |
376 | for my $x ($x1 .. $x2) { |
358 | my $ass = $self->{map}{map}[$x]; |
377 | my $ass = $self->{map}{map}[$x]; |
359 | my $oss = $ov->[$x] ||= []; |
378 | my $oss = $ov->[$x] ||= []; |
360 | for my $y (@y) { |
379 | for my $y ($y1 .. $y2) { |
361 | my $os = $oss->[$y] = []; |
380 | my $os = $oss->[$y] = []; |
362 | for my $a (@{ $ass->[$y] || [] }) { |
381 | for my $a (@{ $ass->[$y] || [] }) { |
363 | my $o = $ARCH->{$a->{_name}} |
382 | my $o = $ARCH->{$a->{_name}} |
364 | or (warn "arch '$a->{_name}' not found at ($x|$y)\n"), next; |
383 | or (warn "arch '$a->{_name}' not found at ($x|$y)\n"), next; |
365 | |
384 | |
366 | my $tile = $TC->{$a->{face} || $o->{face}} |
385 | my $tile = $TC->{$a->{face} || $o->{face}} |
367 | or (warn "no gfx found for arch '$a->{_name}' at ($x|$y)\n"), next; |
386 | or (warn "no gfx found for arch '$a->{_name}' at ($x|$y)\n"), next; |
368 | |
387 | |
369 | if ($tile->{w} > 1 || $tile->{h} > 1) { |
388 | if ($tile->{w} > 1 || $tile->{h} > 1) { |
370 | # bigfaces |
389 | # bigfaces |
|
|
390 | my $maxx = $x + $tile->{w} - 1; |
|
|
391 | my $maxy = $y + $tile->{h} - 1; |
|
|
392 | |
371 | for my $ox (0 .. $tile->{w} - 1) { |
393 | for my $ox (0 .. $tile->{w} - 1) { |
372 | for my $oy (0 .. $tile->{h} - 1) { |
394 | for my $oy (0 .. $tile->{h} - 1) { |
|
|
395 | my $ext = $ext->[$x + $ox][$y + $oy]; |
|
|
396 | |
|
|
397 | $ext->[0] = $x if $ext->[0] > $x; |
|
|
398 | $ext->[1] = $y if $ext->[1] > $y; |
|
|
399 | $ext->[2] = $maxx if $ext->[2] < $maxx; |
|
|
400 | $ext->[3] = $maxy if $ext->[3] < $maxy; |
|
|
401 | |
373 | push @ov, [$x + $ox, $y + $oy, |
402 | push @ov, [$x + $ox, $y + $oy, |
374 | $tile->{idx} + $ox + $oy * $tile->{w}]; |
403 | $tile->{idx} + $ox + $oy * $tile->{w}]; |
375 | } |
|
|
376 | } |
404 | } |
377 | |
|
|
378 | } elsif ($o->{more}) { |
|
|
379 | # linked faces |
|
|
380 | do { |
|
|
381 | my $tile = $TC->{$o->{face}} |
|
|
382 | or (warn "no gfx found for arch '$a->{_name}' at ($x*|$y*)\n"), next; |
|
|
383 | push @ov, [$x + $o->{x}, $y + $o->{y}, $tile->{idx}]; |
|
|
384 | } while $o = $o->{more}; |
|
|
385 | |
|
|
386 | } else { |
|
|
387 | # single face |
|
|
388 | push @$os, $tile->{idx}; |
|
|
389 | |
|
|
390 | } |
405 | } |
|
|
406 | |
|
|
407 | } elsif ($o->{more}) { |
|
|
408 | # linked faces, slowest and mosta nnoying |
|
|
409 | |
|
|
410 | my ($minx, $miny, $maxx, $maxy); |
|
|
411 | |
|
|
412 | for (my $o = $o; $o; $o = $o->{more}) { |
|
|
413 | $minx = $o->{x} if $minx > $o->{x}; |
|
|
414 | $miny = $o->{y} if $miny > $o->{y}; |
|
|
415 | $maxx = $o->{x} if $maxx < $o->{x}; |
|
|
416 | $maxy = $o->{y} if $maxy < $o->{y}; |
|
|
417 | } |
|
|
418 | |
|
|
419 | $minx += $x; |
|
|
420 | $miny += $y; |
|
|
421 | $maxx += $x; |
|
|
422 | $maxy += $y; |
|
|
423 | |
|
|
424 | for (my $o = $o; $o; $o = $o->{more}) { |
|
|
425 | my $tile = $TC->{$o->{face}} |
|
|
426 | or (warn "no gfx found for arch '$a->{_name}' at ($x*|$y*)\n"), next; |
|
|
427 | |
|
|
428 | my $ext = $ext->[$x + $o->{x}][$y + $o->{y}]; |
|
|
429 | |
|
|
430 | $ext->[0] = $minx if $ext->[0] > $minx; |
|
|
431 | $ext->[1] = $miny if $ext->[1] > $miny; |
|
|
432 | $ext->[2] = $maxx if $ext->[2] < $maxx; |
|
|
433 | $ext->[3] = $maxy if $ext->[3] < $maxy; |
|
|
434 | |
|
|
435 | push @ov, [$x + $o->{x}, $y + $o->{y}, $tile->{idx}]; |
|
|
436 | } |
|
|
437 | |
|
|
438 | } else { |
|
|
439 | # single face |
|
|
440 | push @$os, $tile->{idx}; |
|
|
441 | |
391 | } |
442 | } |
392 | } |
443 | } |
393 | } |
444 | } |
|
|
445 | } |
394 | |
446 | |
395 | # bigger faces always on top, I don't give a shit to those who think otherwise |
447 | # bigger faces always on top, I don't give a shit to those who think otherwise |
396 | for (@ov) { |
448 | for (@ov) { |
397 | my ($x, $y, $idx) = @$_; |
449 | my ($x, $y, $idx) = @$_; |
398 | |
450 | |
399 | push @{ $ov->[$x][$y] }, $idx; |
451 | push @{ $ov->[$x][$y] }, $idx; |
|
|
452 | } |
|
|
453 | |
|
|
454 | # dump extent info |
|
|
455 | # for my $x ($x1 .. $x2) { |
|
|
456 | # for my $y ($y1 .. $y2) { |
|
|
457 | # my $ext = $ext->[$x][$y]; |
|
|
458 | # if ($ext->[0] != $x || $ext->[1] != $y || $ext->[2] != $x || $ext->[3] != $y) { |
|
|
459 | # warn "EXT $x $y (@$ext)\n";#d# |
|
|
460 | # } |
400 | } |
461 | # } |
401 | |
|
|
402 | # $self->queue_draw_area (@$_) |
|
|
403 | # for @{ delete $self->{queue_draw_areay} }; |
|
|
404 | $self->invalidate_all; |
|
|
405 | |
|
|
406 | 0 |
|
|
407 | }; |
462 | # } |
408 | } |
463 | } |
409 | |
464 | |
410 | sub expose { |
465 | sub expose { |
411 | my ($self, $event) = @_; |
466 | my ($self, $event) = @_; |
412 | |
467 | |