427 |
bool is_transparent() const { return int_attrib("transparent"); } |
bool is_transparent() const { return int_attrib("transparent"); } |
428 |
bool is_movable() const { return int_attrib("movable"); } |
bool is_movable() const { return int_attrib("movable"); } |
429 |
|
|
430 |
void set_orientation(int o) {set_attrib("orientation", o);} |
void set_orientation(int o) { set_attrib("orientation", o); } |
431 |
int get_orientation() {return int_attrib("orientation");} |
int get_orientation() { return int_attrib("orientation"); } |
432 |
|
|
433 |
void emit_light(Direction dir) { |
void emit_light(Direction dir) { |
434 |
if (!has_dir(outdirs, dir)) |
if (!has_dir(outdirs, dir)) |
527 |
{ |
{ |
528 |
if (is_movable()) |
if (is_movable()) |
529 |
MovableStone::actor_hit(sc); |
MovableStone::actor_hit(sc); |
530 |
rotate_right(); |
rotate_right(); |
531 |
} |
} |
532 |
|
|
533 |
void MirrorStone::on_creation() |
void MirrorStone::on_creation() |
566 |
PlaneMirror(char orientation='/', bool movable=false, bool transparent=false) |
PlaneMirror(char orientation='/', bool movable=false, bool transparent=false) |
567 |
: MirrorStone("st-pmirror", movable, transparent) |
: MirrorStone("st-pmirror", movable, transparent) |
568 |
{ |
{ |
569 |
set_orientation(orientation); |
SetOrientation(orientation); |
570 |
} |
} |
571 |
private: |
private: |
572 |
void set_orientation(char o) { |
void SetOrientation(char o) { |
573 |
const char *a = " -\\|/"; |
const char *a = " -\\|/"; |
574 |
MirrorStone::set_orientation(strchr(a,o)-a); |
MirrorStone::set_orientation(strchr(a,o)-a); |
575 |
} |
} |
576 |
char get_orientation() { |
char GetOrientation() { |
577 |
const char *a = " -\\|/"; |
const char *a = " -\\|/"; |
578 |
return a[MirrorStone::get_orientation()]; |
return a[MirrorStone::get_orientation()]; |
579 |
} |
} |
584 |
bool |
bool |
585 |
PlaneMirror::on_laserhit(Direction dir) |
PlaneMirror::on_laserhit(Direction dir) |
586 |
{ |
{ |
587 |
char orientation = get_orientation(); |
char orientation = GetOrientation(); |
588 |
bool transparent = is_transparent(); |
bool transparent = is_transparent(); |
589 |
|
|
590 |
switch (orientation) { |
switch (orientation) { |
594 |
if (transparent) |
if (transparent) |
595 |
emit_light(dir); |
emit_light(dir); |
596 |
} |
} |
597 |
|
else { |
598 |
|
// @@@ FIXME: oxyd1 lets light pass if mirror is transparent |
599 |
|
} |
600 |
break; |
break; |
601 |
case '-': |
case '-': |
602 |
if (dir==NORTH || dir==SOUTH) { |
if (dir==NORTH || dir==SOUTH) { |
604 |
if (transparent) |
if (transparent) |
605 |
emit_light(dir); |
emit_light(dir); |
606 |
} |
} |
607 |
|
else { |
608 |
|
// @@@ FIXME: oxyd1 lets light pass if mirror is transparent |
609 |
|
} |
610 |
break; |
break; |
611 |
case '/': |
case '/': |
612 |
switch(dir) { |
switch(dir) { |
640 |
|
|
641 |
/** \page st-3mirror Triangle Mirror Stone |
/** \page st-3mirror Triangle Mirror Stone |
642 |
|
|
643 |
|
|
644 |
*/ |
*/ |
645 |
|
|
646 |
namespace |
namespace |
647 |
{ |
{ |
648 |
|
// The orientations of the TriangleMirror have an unusual definition, |
649 |
|
// but we cannot change them w/o changing many levels |
650 |
|
// |
651 |
|
// Flat side of the triangle |
652 |
|
// points to : Orientation : |
653 |
|
// |
654 |
|
// WEST 4 |
655 |
|
// SOUTH 3 |
656 |
|
// EAST 2 |
657 |
|
// NORTH 1 |
658 |
|
|
659 |
class TriangleMirror : public MirrorStone { |
class TriangleMirror : public MirrorStone { |
660 |
CLONEOBJ(TriangleMirror); |
CLONEOBJ(TriangleMirror); |
661 |
public: |
public: |
662 |
TriangleMirror(Direction dir=NORTH) |
TriangleMirror(char orientation='v', bool movable=false, bool transparent=false) |
663 |
: MirrorStone("st-3mirror") |
: MirrorStone("st-3mirror", movable, transparent) |
664 |
{ |
{ |
665 |
set_orientation(dir+1); |
// const int a[] = { 4, 3, 2, 1 }; // direction -> orientation (weird) |
666 |
|
// set_orientation(a[dir]); |
667 |
|
SetOrientation(orientation); |
668 |
} |
} |
669 |
private: |
private: |
670 |
|
|
671 |
Direction get_orientation() |
void SetOrientation(char o) { |
672 |
|
const char *a = " v<^>"; |
673 |
|
MirrorStone::set_orientation(strchr(a,o)-a); |
674 |
|
} |
675 |
|
|
676 |
|
Direction GetOrientation() // orientation of the flat side of the mirror |
677 |
{ |
{ |
678 |
Direction a[] = {NODIR, SOUTH, WEST, NORTH, EAST}; |
const Direction a[] = {NODIR, NORTH, EAST, SOUTH, WEST}; |
679 |
return a[MirrorStone::get_orientation()]; |
return a[MirrorStone::get_orientation()]; |
680 |
} |
} |
681 |
bool on_laserhit(Direction dir); |
bool on_laserhit(Direction dir); |
683 |
} |
} |
684 |
|
|
685 |
bool |
bool |
686 |
TriangleMirror::on_laserhit(Direction dir) |
TriangleMirror::on_laserhit(Direction beam_dir) |
687 |
|
// note: 'beam_dir' is the direction where laserbeam goes to |
688 |
{ |
{ |
689 |
Direction orient = get_orientation(); |
// direction where flat side of triangle points to |
690 |
|
Direction flat_dir = GetOrientation(); |
691 |
if (dir == orient) |
Direction tip_dir = reverse(flat_dir); |
692 |
emit_light(reverse(dir)); |
|
693 |
else if (dir == reverse(orient)) { |
if (beam_dir == tip_dir) // beam hits the flat side |
694 |
|
emit_light(flat_dir); |
695 |
|
else if (beam_dir == flat_dir) { |
696 |
// this is the "complicated" case where the light falls |
// this is the "complicated" case where the light falls |
697 |
// on the tip of the triangle |
// on the tip of the triangle |
698 |
switch (dir) { |
switch (beam_dir) { |
699 |
case SOUTH: case NORTH: |
case SOUTH: case NORTH: |
700 |
emit_light(EAST); emit_light(WEST); break; |
emit_light(EAST); emit_light(WEST); break; |
701 |
case WEST: case EAST: |
case WEST: case EAST: |
702 |
emit_light(SOUTH); emit_light(NORTH); break; |
emit_light(SOUTH); emit_light(NORTH); break; |
703 |
case NODIR: break; |
case NODIR: break; |
704 |
} |
} |
705 |
} else |
} else |
706 |
emit_light(orient); |
emit_light(tip_dir); |
707 |
|
|
708 |
if (is_transparent()) |
if (is_transparent()) |
709 |
emit_light(dir); |
emit_light(beam_dir); |
710 |
|
|
711 |
return false; |
return false; |
712 |
} |
} |
713 |
|
|
731 |
Register ("st-laser-w", new LaserStone(WEST)); |
Register ("st-laser-w", new LaserStone(WEST)); |
732 |
|
|
733 |
Register (new TriangleMirror); |
Register (new TriangleMirror); |
734 |
Register ("st-mirror-3n", new TriangleMirror(NORTH)); |
Register ("st-mirror-3v", new TriangleMirror('v')); |
735 |
Register ("st-mirror-3e", new TriangleMirror(EAST)); |
Register ("st-mirror-3<", new TriangleMirror('<')); |
736 |
Register ("st-mirror-3s", new TriangleMirror(SOUTH)); |
Register ("st-mirror-3^", new TriangleMirror('^')); |
737 |
Register ("st-mirror-3w", new TriangleMirror(WEST)); |
Register ("st-mirror-3>", new TriangleMirror('>')); |
738 |
|
Register ("st-mirror-3vm", new TriangleMirror('v', true)); |
739 |
|
Register ("st-mirror-3<m", new TriangleMirror('<', true)); |
740 |
|
Register ("st-mirror-3^m", new TriangleMirror('^', true)); |
741 |
|
Register ("st-mirror-3>m", new TriangleMirror('>', true)); |
742 |
|
Register ("st-mirror-3vt", new TriangleMirror('v', false, true)); |
743 |
|
Register ("st-mirror-3<t", new TriangleMirror('<', false, true)); |
744 |
|
Register ("st-mirror-3^t", new TriangleMirror('^', false, true)); |
745 |
|
Register ("st-mirror-3>t", new TriangleMirror('>', false, true)); |
746 |
|
|
747 |
Register (new PlaneMirror); |
Register (new PlaneMirror); |
748 |
Register ("st-mirror-p|", new PlaneMirror('|')); |
Register ("st-mirror-p|", new PlaneMirror('|')); |