585 |
*/ |
*/ |
586 |
namespace |
namespace |
587 |
{ |
{ |
588 |
class OneWayStone : public Stone { |
class OneWayBase : public Stone { |
589 |
CLONEOBJ(OneWayStone); |
protected: |
590 |
public: |
OneWayBase(const char *kind) : Stone(kind) |
591 |
OneWayStone() : Stone("st-oneway") { |
{ |
592 |
set_orientation(SOUTH); |
set_orientation(SOUTH); |
593 |
} |
} |
|
private: |
|
|
void init_model() { |
|
|
string mname = "st-oneway"; |
|
|
mname += to_suffix(get_orientation()); |
|
|
set_model (mname); |
|
|
} |
|
594 |
Direction get_orientation() const { |
Direction get_orientation() const { |
595 |
return Direction(int_attrib("orientation")); |
return Direction(int_attrib("orientation")); |
596 |
} |
} |
597 |
void set_orientation(Direction dir) { |
void set_orientation(Direction dir) { |
598 |
set_attrib("orientation", Value(dir)); |
set_attrib("orientation", Value(dir)); |
599 |
} |
} |
|
StoneResponse collision_response(const StoneContact&); |
|
600 |
void actor_hit (const StoneContact&); |
void actor_hit (const StoneContact&); |
601 |
}; |
StoneResponse collision_response(const StoneContact &sc); |
602 |
} |
|
603 |
|
void init_model() |
604 |
|
{ |
605 |
|
string mname = get_kind(); |
606 |
|
mname += to_suffix(get_orientation()); |
607 |
|
set_model (mname); |
608 |
|
} |
609 |
|
|
610 |
StoneResponse |
virtual bool actor_may_pass (Actor *a) = 0; |
611 |
OneWayStone::collision_response(const StoneContact &sc) |
}; |
|
{ |
|
|
DirectionBits dirs=contact_faces(sc); |
|
|
Direction o=get_orientation(); |
|
|
|
|
|
return has_dir(dirs,o) ? STONE_REBOUND : STONE_PASS; |
|
612 |
} |
} |
613 |
|
|
614 |
void |
void |
615 |
OneWayStone::actor_hit(const StoneContact &sc) |
OneWayBase::actor_hit(const StoneContact &sc) |
616 |
{ |
{ |
|
DirectionBits dirs=contact_faces(sc); |
|
617 |
Direction o=get_orientation(); |
Direction o=get_orientation(); |
618 |
|
|
619 |
if (has_dir(dirs,o)) { |
if (has_dir(contact_faces(sc), o)) { |
|
// magic wand as first item? |
|
620 |
if (wielded_item_is(sc.actor, "it-magicwand")) { |
if (wielded_item_is(sc.actor, "it-magicwand")) { |
621 |
set_orientation(reverse(o)); |
set_orientation(reverse(o)); |
622 |
init_model(); |
init_model(); |
624 |
} |
} |
625 |
} |
} |
626 |
|
|
|
//---------------------------------------- |
|
|
// One Way Stone; black only |
|
|
// |
|
|
// This stone can only be passed in one direction. |
|
|
//---------------------------------------- |
|
|
|
|
|
namespace |
|
|
{ |
|
|
class OneWayStone_black : public Stone { |
|
|
CLONEOBJ(OneWayStone_black); |
|
|
public: |
|
|
OneWayStone_black() : Stone("st-oneway_black") { |
|
|
set_orientation(SOUTH); |
|
|
} |
|
|
private: |
|
|
void init_model() { |
|
|
string mname = "st-oneway_black"; |
|
|
mname += to_suffix(get_orientation()); |
|
|
set_model (mname); |
|
|
} |
|
|
Direction get_orientation() const { |
|
|
return Direction(int_attrib("orientation")); |
|
|
} |
|
|
void set_orientation(Direction dir) { |
|
|
set_attrib("orientation", Value(dir)); |
|
|
} |
|
|
StoneResponse collision_response(const StoneContact&); |
|
|
void actor_hit (const StoneContact&); |
|
|
}; |
|
|
} |
|
|
|
|
627 |
StoneResponse |
StoneResponse |
628 |
OneWayStone_black::collision_response(const StoneContact &sc) |
OneWayBase::collision_response(const StoneContact &sc) |
629 |
{ |
{ |
630 |
DirectionBits dirs=contact_faces(sc); |
DirectionBits dirs=contact_faces(sc); |
631 |
Direction o=get_orientation(); |
Direction o=get_orientation(); |
632 |
if (sc.actor->get_attrib("blackball")) |
|
633 |
return has_dir(dirs,o) ? STONE_REBOUND : STONE_PASS; |
if (actor_may_pass(sc.actor)) |
634 |
|
return has_dir(dirs,o) ? STONE_REBOUND : STONE_PASS; |
635 |
else |
else |
636 |
return STONE_REBOUND; |
return STONE_REBOUND; |
637 |
} |
} |
638 |
|
|
|
void |
|
|
OneWayStone_black::actor_hit(const StoneContact &sc) |
|
|
{ |
|
|
DirectionBits dirs=contact_faces(sc); |
|
|
Direction o=get_orientation(); |
|
|
|
|
|
if (has_dir(dirs,o)) { |
|
|
// magic wand as first item? |
|
|
if (wielded_item_is(sc.actor, "it-magicwand")) { |
|
|
set_orientation(reverse(o)); |
|
|
init_model(); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
//---------------------------------------- |
|
|
// One Way Stone ; white only |
|
|
// |
|
|
// This stone can only be passed in one direction. |
|
|
//---------------------------------------- |
|
639 |
|
|
640 |
namespace |
namespace |
641 |
{ |
{ |
642 |
class OneWayStone_white : public Stone { |
class OneWayStone : public OneWayBase { |
|
CLONEOBJ(OneWayStone_white); |
|
643 |
public: |
public: |
644 |
OneWayStone_white() : Stone("st-oneway_white") { |
OneWayStone() : OneWayBase("st-oneway") {} |
|
set_orientation(SOUTH); |
|
|
} |
|
645 |
private: |
private: |
646 |
void init_model() { |
CLONEOBJ(OneWayStone); |
647 |
string mname = "st-oneway_white"; |
virtual bool actor_may_pass (Actor *a) { return true; } |
|
mname += to_suffix(get_orientation()); |
|
|
set_model (mname); |
|
|
} |
|
|
Direction get_orientation() const { |
|
|
return Direction(int_attrib("orientation")); |
|
|
} |
|
|
void set_orientation(Direction dir) { |
|
|
set_attrib("orientation", Value(dir)); |
|
|
} |
|
|
StoneResponse collision_response(const StoneContact&); |
|
|
void actor_hit (const StoneContact&); |
|
648 |
}; |
}; |
|
} |
|
649 |
|
|
|
StoneResponse |
|
|
OneWayStone_white::collision_response(const StoneContact &sc) |
|
|
{ |
|
|
DirectionBits dirs=contact_faces(sc); |
|
|
Direction o=get_orientation(); |
|
|
if (sc.actor->get_attrib("whiteball")) |
|
|
return has_dir(dirs,o) ? STONE_REBOUND : STONE_PASS; |
|
|
else |
|
|
return STONE_REBOUND; |
|
|
} |
|
650 |
|
|
651 |
void |
class OneWayStone_black : public OneWayBase { |
652 |
OneWayStone_white::actor_hit(const StoneContact &sc) |
public: |
653 |
{ |
OneWayStone_black() : OneWayBase("st-oneway_black") {} |
654 |
DirectionBits dirs=contact_faces(sc); |
private: |
655 |
Direction o=get_orientation(); |
CLONEOBJ(OneWayStone_black); |
656 |
|
virtual bool actor_may_pass (Actor *a) { |
657 |
|
return a->get_attrib("blackball") != 0; |
658 |
|
} |
659 |
|
}; |
660 |
|
|
661 |
if (has_dir(dirs,o)) { |
class OneWayStone_white : public OneWayBase { |
662 |
// magic wand as first item? |
public: |
663 |
if (wielded_item_is(sc.actor, "it-magicwand")) { |
OneWayStone_white() : OneWayBase("st-oneway_white") {} |
664 |
set_orientation(reverse(o)); |
private: |
665 |
init_model(); |
CLONEOBJ(OneWayStone_white); |
666 |
|
virtual bool actor_may_pass (Actor *a) { |
667 |
|
return a->get_attrib("whiteball") != 0; |
668 |
} |
} |
669 |
} |
}; |
670 |
} |
} |
671 |
|
|
672 |
|
|
673 |
//---------------------------------------- |
//---------------------------------------- |
674 |
// Chameleon Stone |
// Chameleon Stone |
675 |
// |
// |
917 |
\image html st-window.png |
\image html st-window.png |
918 |
*/ |
*/ |
919 |
|
|
920 |
namespace { |
namespace |
921 |
|
{ |
922 |
class Window : public Stone { |
class Window : public Stone { |
923 |
CLONEOBJ(Window); |
CLONEOBJ(Window); |
924 |
const char *collision_sound() {return "ballcollision";} |
const char *collision_sound() {return "ballcollision";} |
929 |
State state; |
State state; |
930 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
931 |
{ |
{ |
932 |
if( state == IDLE) |
Actor *a = sc.actor; |
933 |
{ |
if( state == IDLE) |
934 |
Actor *a = sc.actor; |
{ |
935 |
if (a->get_vel() * sc.normal < -25 ) { |
if (a->get_vel() * sc.normal < -25 ) { |
936 |
play_sound("shatter"); |
play_sound("shatter"); |
937 |
state = BREAK; |
state = BREAK; |
938 |
set_anim("st-window-anim"); |
set_anim("st-window-anim"); |
939 |
} |
} |
940 |
} |
} |
941 |
{ |
{ |
942 |
Actor *a = sc.actor; |
if (a->get_vel() * sc.normal < -28 ) { |
943 |
if (a->get_vel() * sc.normal < -28 ) { |
play_sound("shatter"); |
944 |
play_sound("shatter"); |
state = BREAK; |
945 |
state = BREAK; |
set_anim("st-window-anim"); |
946 |
set_anim("st-window-anim"); |
SendMessage(a, "shatter"); |
947 |
SendMessage(a, "shatter"); |
} |
948 |
} |
} |
949 |
} |
} |
|
} |
|
950 |
void animcb() { |
void animcb() { |
951 |
if (state == BREAK) { |
if (state == BREAK) { |
952 |
KillStone(get_pos()); |
KillStone(get_pos()); |
953 |
} |
} |
954 |
} |
} |
955 |
}; |
}; |
956 |
} |
} |
957 |
|
|
958 |
//---------------------------------------- |
//---------------------------------------- |
983 |
State state; |
State state; |
984 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
985 |
{ |
{ |
986 |
if( state == IDLE) |
if( state == IDLE) |
987 |
{ |
{ |
988 |
if (wielded_item_is(sc.actor, "it-hammer")) { |
if (wielded_item_is(sc.actor, "it-hammer")) { |
989 |
play_sound("explosion1"); |
play_sound("explosion1"); |
990 |
state = BREAK; |
state = BREAK; |
991 |
set_anim("st-break-anim"); |
set_anim("st-break-anim"); |
992 |
} |
} |
993 |
|
} |
994 |
} |
} |
|
} |
|
995 |
void animcb() { |
void animcb() { |
996 |
if (state == BREAK) { |
if (state == BREAK) { |
997 |
KillStone(get_pos()); |
KillStone(get_pos()); |
998 |
} |
} |
999 |
} |
} |
1000 |
}; |
}; |
1001 |
} |
} |
1002 |
|
|
1003 |
//---------------------------------------- |
//---------------------------------------- |
1035 |
} |
} |
1036 |
|
|
1037 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
1038 |
{ |
{ |
1039 |
if (state == IDLE) { |
if (state == IDLE) { |
1040 |
if (sc.actor->get_attrib("whiteball")) { |
if (sc.actor->get_attrib("whiteball")) |
1041 |
state = FRAGILE;} |
state = FRAGILE; |
1042 |
} |
} |
1043 |
{ |
if( state == FRAGILE) { |
1044 |
if( state == FRAGILE) |
if (wielded_item_is(sc.actor, "it-hammer")) |
1045 |
{ |
change_state(BREAK); |
1046 |
if (wielded_item_is(sc.actor, "it-hammer")) { |
} |
|
play_sound("explosion1"); |
|
|
state = BREAK; |
|
|
set_anim("st-break_acwhite-anim"); |
|
|
} |
|
1047 |
} |
} |
|
} |
|
|
} |
|
1048 |
void animcb() { |
void animcb() { |
1049 |
if (state == BREAK) { |
if (state == BREAK) |
1050 |
KillStone(get_pos()); |
KillStone(get_pos()); |
1051 |
} |
} |
|
} |
|
1052 |
bool on_laserhit(Direction) { |
bool on_laserhit(Direction) { |
1053 |
change_state(BREAK); |
change_state(BREAK); |
1054 |
return false; |
return false; |
1055 |
} |
} |
1056 |
}; |
}; |
1057 |
} |
} |
1058 |
|
|
1059 |
//---------------------------------------- |
//---------------------------------------- |
1091 |
} |
} |
1092 |
|
|
1093 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
1094 |
{ |
{ |
1095 |
if (state == IDLE) { |
if (state == IDLE) { |
1096 |
if (sc.actor->get_attrib("blackball")) { |
if (sc.actor->get_attrib("blackball")) { |
1097 |
state = FRAGILE;} |
state = FRAGILE;} |
1098 |
} |
} |
1099 |
{ |
{ |
1100 |
if( state == FRAGILE) |
if( state == FRAGILE) |
1101 |
{ |
{ |
1102 |
if (wielded_item_is(sc.actor, "it-hammer")) { |
if (wielded_item_is(sc.actor, "it-hammer")) { |
1103 |
play_sound("explosion1"); |
play_sound("explosion1"); |
1104 |
state = BREAK; |
state = BREAK; |
1105 |
set_anim("st-break_acblack-anim"); |
set_anim("st-break_acblack-anim"); |
1106 |
} |
} |
1107 |
|
} |
1108 |
|
} |
1109 |
} |
} |
|
} |
|
|
} |
|
1110 |
void animcb() { |
void animcb() { |
1111 |
if (state == BREAK) { |
if (state == BREAK) { |
1112 |
KillStone(get_pos()); |
KillStone(get_pos()); |
1113 |
} |
} |
1114 |
} |
} |
1115 |
bool on_laserhit(Direction) { |
bool on_laserhit(Direction) { |
1116 |
change_state(BREAK); |
change_state(BREAK); |
1117 |
return false; |
return false; |
1118 |
} |
} |
1119 |
}; |
}; |
1120 |
} |
} |
1121 |
|
|
1122 |
//---------------------------------------- |
//---------------------------------------- |
1264 |
set_model("st-stone_break"); |
set_model("st-stone_break"); |
1265 |
} |
} |
1266 |
} |
} |
|
{ |
|
|
if( state == BRUSH) |
|
1267 |
{ |
{ |
1268 |
if (wielded_item_is(sc.actor, "it-hammer")) { |
if( state == BRUSH) |
1269 |
play_sound("explosion1"); |
{ |
1270 |
set_anim("st-break_invisible-anim"); |
if (wielded_item_is(sc.actor, "it-hammer")) { |
1271 |
} |
play_sound("explosion1"); |
1272 |
} |
set_anim("st-break_invisible-anim"); |
1273 |
|
} |
1274 |
|
} |
1275 |
|
} |
1276 |
} |
} |
|
} |
|
1277 |
void animcb() { |
void animcb() { |
1278 |
if (state == BRUSH) { |
if (state == BRUSH) { |
1279 |
KillStone(get_pos()); |
KillStone(get_pos()); |