113 |
|
|
114 |
private: |
private: |
115 |
|
|
|
void on_move() { |
|
|
assert(0); |
|
|
} |
|
|
|
|
116 |
void actor_hit(const StoneContact &sc) { |
void actor_hit(const StoneContact &sc) { |
117 |
if (state == IDLE) { |
if (state == IDLE) { |
118 |
maybe_push_stone(sc); |
maybe_push_stone(sc); |
120 |
} |
} |
121 |
|
|
122 |
void change_state(State new_state) { |
void change_state(State new_state) { |
|
// warning("change_state %i -> %i", int(state), int(new_state)); |
|
|
|
|
123 |
switch (new_state) { |
switch (new_state) { |
124 |
case IDLE: set_model("st-pull"); break; |
case IDLE: set_model("st-pull"); break; |
125 |
case WEST_SIDE: set_model("st-pull-l"); break; |
case WEST_SIDE: set_model("st-pull-l"); break; |
433 |
{ |
{ |
434 |
CLONEOBJ(BolderStone); |
CLONEOBJ(BolderStone); |
435 |
public: |
public: |
436 |
BolderStone(Direction dir=NORTH) : Stone("st-bolder"), state(IDLE) |
BolderStone(Direction dir=NORTH) |
437 |
|
: Stone("st-bolder") |
438 |
|
, state(ACTIVE) |
439 |
{ |
{ |
440 |
set_dir(dir); |
set_dir(dir); |
441 |
} |
} |
442 |
private: |
private: |
443 |
enum State { IDLE, MOVING } state; |
enum State { |
444 |
|
ACTIVE, // may send trigger into direction |
445 |
|
IDLE, // already sent trigger w/o success |
446 |
|
MOVING // inside move |
447 |
|
} state; |
448 |
|
|
449 |
Direction get_dir() const |
Direction get_dir() const { |
|
{ |
|
450 |
return static_cast<Direction>(int_attrib("direction")); |
return static_cast<Direction>(int_attrib("direction")); |
451 |
} |
} |
452 |
void set_dir(Direction d) {set_attrib("direction", d);} |
void set_dir(Direction d) { |
453 |
|
if (d != get_dir()) |
454 |
bool is_movable() { return true; } |
state = ACTIVE; // if turned by it-magicwand -> allow triggering |
455 |
|
set_attrib("direction", d); |
456 |
|
} |
457 |
|
|
458 |
void on_creation() { |
void on_creation() { |
459 |
if (state == IDLE) |
if (state != MOVING) |
460 |
g_timer.set_alarm(this, 0.3, true); |
g_timer.set_alarm(this, 0.3, true); |
461 |
Stone::on_creation(); |
Stone::on_creation(); |
462 |
} |
} |
463 |
void on_removal() { |
void on_removal() { |
464 |
if (state == IDLE) |
if (state != MOVING) |
465 |
g_timer.remove_alarm(this); |
g_timer.remove_alarm(this); |
466 |
Stone::on_removal(); |
Stone::on_removal(); |
467 |
} |
} |
468 |
|
|
469 |
void alarm() { |
bool check_blocked(Direction dir) { |
470 |
state = MOVING; |
if (Stone *st = GetStone(move(get_pos(), dir))) { |
471 |
move_stone(get_dir()); |
if (state == ACTIVE) { // allowed to trigger? |
472 |
state = IDLE; |
state = IDLE; |
473 |
|
if (0 == strcmp(st->get_kind(), "st-pull")) { |
474 |
|
send_impulse(st->get_pos(), dir); |
475 |
|
} |
476 |
|
else { |
477 |
|
SendMessage(st, "trigger", Value(dir)); |
478 |
|
} |
479 |
|
} |
480 |
|
return true; |
481 |
|
} |
482 |
|
return false; |
483 |
} |
} |
484 |
|
|
485 |
void on_move() { |
void alarm() { |
|
// send a message to the stone that's blocking our way |
|
486 |
Direction dir = get_dir(); |
Direction dir = get_dir(); |
487 |
|
if (!check_blocked(dir)) { |
488 |
|
state = MOVING; |
489 |
|
if (move_stone(dir)) { |
490 |
|
// if moved -> try to hit obstacle |
491 |
|
state = ACTIVE; |
492 |
|
check_blocked(dir); |
493 |
|
} |
494 |
|
else { |
495 |
|
state = IDLE; |
496 |
|
} |
497 |
|
} |
498 |
|
} |
499 |
|
|
500 |
if (Stone *st = GetStone(move(get_pos(), dir))) { |
void on_move() { |
501 |
SendMessage(st, "trigger", Value(dir)); |
if (state != MOVING) { // moved by impulse etc. |
502 |
|
state = ACTIVE; |
503 |
} |
} |
504 |
} |
} |
505 |
|
|
510 |
set_model(mname); |
set_model(mname); |
511 |
} |
} |
512 |
|
|
513 |
|
bool is_movable() { return true; } |
514 |
|
|
515 |
void actor_hit(const StoneContact &sc) |
void actor_hit(const StoneContact &sc) |
516 |
{ |
{ |
517 |
Actor *a = sc.actor; |
Actor *a = sc.actor; |