449 |
enum State { |
enum State { |
450 |
ACTIVE, // may send trigger into direction |
ACTIVE, // may send trigger into direction |
451 |
IDLE, // already sent trigger w/o success |
IDLE, // already sent trigger w/o success |
452 |
MOVING // inside move |
MOVING, // inside move |
453 |
|
FALLING // falling into abyss/water |
454 |
} state; |
} state; |
455 |
|
|
456 |
|
void set_alarm() { |
457 |
|
if (state != MOVING) |
458 |
|
g_timer.set_alarm(this, 0.3, true); |
459 |
|
} |
460 |
|
void remove_alarm() { |
461 |
|
if (state != MOVING) |
462 |
|
g_timer.remove_alarm(this); |
463 |
|
} |
464 |
|
|
465 |
Direction get_dir() const { |
Direction get_dir() const { |
466 |
return static_cast<Direction>(int_attrib("direction")); |
return static_cast<Direction>(int_attrib("direction")); |
467 |
} |
} |
471 |
set_attrib("direction", d); |
set_attrib("direction", d); |
472 |
} |
} |
473 |
|
|
474 |
|
void floor_change() { |
475 |
|
Floor *fl = GetFloor(get_pos()); |
476 |
|
if (fl->is_kind("fl-abyss")) { |
477 |
|
state = FALLING; |
478 |
|
} |
479 |
|
} |
480 |
|
|
481 |
void on_creation() { |
void on_creation() { |
482 |
if (state != MOVING) |
set_alarm(); |
|
g_timer.set_alarm(this, 0.3, true); |
|
483 |
Stone::on_creation(); |
Stone::on_creation(); |
484 |
} |
} |
485 |
void on_removal() { |
void on_removal() { |
486 |
if (state != MOVING) |
remove_alarm(); |
|
g_timer.remove_alarm(this); |
|
487 |
Stone::on_removal(); |
Stone::on_removal(); |
488 |
} |
} |
489 |
|
|
499 |
} |
} |
500 |
|
|
501 |
void alarm() { |
void alarm() { |
502 |
Direction dir = get_dir(); |
if (state == FALLING) { |
503 |
if (!check_blocked(dir)) { |
remove_alarm(); |
504 |
state = MOVING; |
init_model(); |
505 |
if (move_stone(dir)) { |
} |
506 |
// if moved -> try to hit obstacle |
else { |
507 |
state = ACTIVE; |
Direction dir = get_dir(); |
508 |
check_blocked(dir); |
if (!check_blocked(dir)) { |
509 |
} |
state = MOVING; |
510 |
else { |
if (move_stone(dir)) { |
511 |
state = IDLE; |
// if moved -> try to hit obstacle |
512 |
|
if (state == MOVING) // state may be FALLING |
513 |
|
state = ACTIVE; |
514 |
|
check_blocked(dir); |
515 |
|
} |
516 |
|
else { |
517 |
|
state = IDLE; |
518 |
|
} |
519 |
} |
} |
520 |
} |
} |
521 |
} |
} |
529 |
// Stone interface. |
// Stone interface. |
530 |
void init_model() |
void init_model() |
531 |
{ |
{ |
532 |
string mname = "st-bolder" + to_suffix(get_dir()); |
string mname = "st-bolder" + to_suffix(get_dir()); |
533 |
set_model(mname); |
if (state == FALLING) { |
534 |
|
mname += "-fall-anim"; |
535 |
|
set_anim(mname); |
536 |
|
} |
537 |
|
else { |
538 |
|
set_model(mname); |
539 |
|
} |
540 |
|
} |
541 |
|
|
542 |
|
void animcb() { |
543 |
|
if (state == FALLING) { |
544 |
|
KillStone(get_pos()); |
545 |
|
} |
546 |
} |
} |
547 |
|
|
548 |
bool is_movable() { return true; } |
bool is_movable() { return state != FALLING; } |
549 |
|
|
550 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
551 |
{ |
{ |
564 |
} |
} |
565 |
|
|
566 |
void on_impulse (const Impulse& impulse) { |
void on_impulse (const Impulse& impulse) { |
567 |
|
if (state == FALLING) |
568 |
|
return; |
569 |
|
|
570 |
if (impulse.sender && 0 == strncmp(impulse.sender->get_kind(), "st-rotator-", 11)) { |
if (impulse.sender && 0 == strncmp(impulse.sender->get_kind(), "st-rotator-", 11)) { |
571 |
set_dir(impulse.dir); |
set_dir(impulse.dir); |
572 |
} |
} |