1855 |
for (unsigned i=0; i<c.size(); ++i) |
for (unsigned i=0; i<c.size(); ++i) |
1856 |
SetStone(mc[i], clusterstones[i]); |
SetStone(mc[i], clusterstones[i]); |
1857 |
} |
} |
1858 |
|
|
1859 |
|
display::GetStatusBar()->set_counter(player::IncMoveCounter(c.size())); |
1860 |
} |
} |
1861 |
|
|
1862 |
bool |
bool |
3952 |
set_model("st-turnstile"); |
set_model("st-turnstile"); |
3953 |
} |
} |
3954 |
|
|
3955 |
void warpItemsInRange(bool clockwise); |
void warpActorsInRange(bool clockwise); |
3956 |
}; |
}; |
3957 |
|
|
3958 |
/* |
/* |
4025 |
#if defined(USE_IMPULSES) |
#if defined(USE_IMPULSES) |
4026 |
|
|
4027 |
void |
void |
4028 |
Turnstile_Pivot::warpItemsInRange(bool clockwise) { |
Turnstile_Pivot::warpActorsInRange(bool clockwise) { |
4029 |
|
// the turnstile itself already has been rotated |
4030 |
|
// now handle all actors in Range |
4031 |
|
|
4032 |
GridPos pv_pos = get_pos(); |
GridPos pv_pos = get_pos(); |
4033 |
V2 pv_center(pv_pos.x+.5, pv_pos.y+.5); |
V2 pv_center(pv_pos.x+.5, pv_pos.y+.5); |
4034 |
vector<Actor*> actorsInRange; |
vector<Actor*> actorsInRange; |
4035 |
|
|
4036 |
if (GetActorsInRange(pv_center, 2.0, actorsInRange)) { |
// tested range is sqrt(sqr(1.5)+sqr(0.5)) ( = radius hit by turnstile) + 19/64 ( = max. actor radius) |
4037 |
|
if (GetActorsInRange(pv_center, 1.879, actorsInRange)) { |
4038 |
for (vector<Actor*>::iterator ac = actorsInRange.begin(); ac != actorsInRange.end(); ++ac) { |
for (vector<Actor*>::iterator ac = actorsInRange.begin(); ac != actorsInRange.end(); ++ac) { |
4039 |
const V2& ac_center = (*ac)->get_pos(); |
const V2& ac_center = (*ac)->get_pos(); |
4040 |
GridPos ac_pos(ac_center); |
GridPos ac_pos(ac_center); |
4041 |
|
int dx = ac_pos.x-pv_pos.x; |
4042 |
|
int dy = ac_pos.y-pv_pos.y; |
4043 |
|
|
4044 |
|
if (dx<-1 || dx>1 || dy<-1 || dy>1) { // actor is outside of turnstile |
4045 |
|
// @@@ FIXME: test if actor was hit by turnstile -> set actor speed |
4046 |
|
} |
4047 |
|
else { // actor is inside the turnstile |
4048 |
|
const int to_index[3][3] = { |
4049 |
|
{ 0, 7, 6 }, // x == 0 |
4050 |
|
{ 1,-1, 5 }, // x == 1 |
4051 |
|
{ 2, 3, 4 } // x == 2 |
4052 |
|
}; |
4053 |
|
// const int rot_index[2][8] = { |
4054 |
|
// { 6, 7, 0, 1, 2, 3, 4, 5 }, // anticlockwise |
4055 |
|
// { 2, 3, 4, 5, 6, 7, 0, 1 } // clockwise |
4056 |
|
// }; |
4057 |
|
const int rot_index[2][8] = { |
4058 |
|
{ 6, 0, 0, 2, 2, 4, 4, 6 }, // anticlockwise |
4059 |
|
{ 2, 2, 4, 4, 6, 6, 0, 0 } // clockwise |
4060 |
|
}; |
4061 |
|
const int to_x[8] = { -1, 0, 1, 1, 1, 0, -1, -1 }; |
4062 |
|
const int to_y[8] = { -1, -1, -1, 0, 1, 1, 1, 0 }; |
4063 |
|
|
4064 |
|
const DirectionBits neededArm[2][8] = { |
4065 |
|
{ WESTBIT, NORTHBIT, NORTHBIT, EASTBIT, EASTBIT, SOUTHBIT, SOUTHBIT, WESTBIT }, // anticlockwise |
4066 |
|
{ NORTHBIT, NORTHBIT, EASTBIT, EASTBIT, SOUTHBIT, SOUTHBIT, WESTBIT, WESTBIT } // clockwise |
4067 |
|
}; |
4068 |
|
|
4069 |
|
DirectionBits arms = arms_present(); // already rotated |
4070 |
|
|
4071 |
|
int idx_source = to_index[dx+1][dy+1]; |
4072 |
|
if (idx_source == -1) continue; |
4073 |
|
|
4074 |
|
if (arms & neededArm[clockwise][idx_source]) { // does the arm exist ? |
4075 |
|
int idx_target = rot_index[clockwise][idx_source]; |
4076 |
|
assert(idx_target >= 0 && idx_target < 8); |
4077 |
|
|
4078 |
|
GridPos ac_target_pos(pv_pos.x+to_x[idx_target], pv_pos.y+to_y[idx_target]); |
4079 |
|
world::WarpActor(*ac, ac_target_pos.x+.5, ac_target_pos.y+.5); |
4080 |
|
|
4081 |
|
if (Stone *st = GetStone(ac_target_pos)) { // destination is blocked |
4082 |
|
|
4083 |
V2 to_actor = ac_center-pv_center; |
// @@@ FIXME: if stone is turnstile arm -> hit it ? |
4084 |
V2 to_newactor = clockwise |
SendMessage(*ac, "shatter"); |
4085 |
? V2(-to_actor[1], to_actor[0]) |
} |
4086 |
: V2(to_actor[1], -to_actor[0]); |
} |
4087 |
|
|
4088 |
|
// @@@ FIXME: it's possible that two actors are moved to the same destination field. |
4089 |
|
// In that case the second actor is put on top of the first actor |
4090 |
|
// (happens only with three balls or pullers/impulsestones) |
4091 |
|
// Note: If one of the actors has been moving, it's not a real problem. |
4092 |
|
|
|
V2 new_actor = pv_center+to_newactor; |
|
4093 |
|
|
4094 |
world::WarpActor(*ac, new_actor[0], new_actor[1]); |
// @@@ FIXME: shattered actors are warped |
4095 |
|
} |
4096 |
} |
} |
4097 |
} |
} |
4098 |
|
|
4099 |
// @@@ FIXME: warp items ? |
// @@@ FIXME: should some items warp ? |
4100 |
} |
} |
4101 |
|
|
4102 |
void |
void |
4103 |
Turnstile_Arm::on_impulse(Direction dir) { |
Turnstile_Arm::on_impulse(Direction dir) { |
4104 |
enum Action { ROTL, ROTR, NOTHING }; |
enum Action { ROTL, ROTR, stay }; |
4105 |
static Action actions[4][4] = { |
static Action actions[4][4] = { |
4106 |
{ NOTHING, ROTL, NOTHING, ROTR }, // west arm |
{ stay, ROTL, stay, ROTR }, // west arm |
4107 |
{ ROTR, NOTHING, ROTL, NOTHING }, // south arm |
{ ROTR, stay, ROTL, stay }, // south arm |
4108 |
{ NOTHING, ROTR, NOTHING, ROTL }, // east arm |
{ stay, ROTR, stay, ROTL }, // east arm |
4109 |
{ ROTL, NOTHING, ROTR, NOTHING } // north arm |
{ ROTL, stay, ROTR, stay } // north arm |
4110 |
}; |
}; |
4111 |
|
|
4112 |
Turnstile_Pivot *pivot = get_pivot(); |
Turnstile_Pivot *pivot = get_pivot(); |
4141 |
{ |
{ |
4142 |
Turnstile_Pivot *pivot = get_pivot(); |
Turnstile_Pivot *pivot = get_pivot(); |
4143 |
|
|
4144 |
enum Action { ROTL, ROTR, NOTHING }; |
enum Action { ROTL, ROTR, stay }; |
4145 |
static Action actions[4][4] = { |
static Action actions[4][4] = { |
4146 |
{ NOTHING, ROTL, NOTHING, ROTR }, // west arm |
{ stay, ROTL, stay, ROTR }, // west arm |
4147 |
{ ROTR, NOTHING, ROTL, NOTHING }, // south arm |
{ ROTR, stay, ROTL, stay }, // south arm |
4148 |
{ NOTHING, ROTR, NOTHING, ROTL }, // east arm |
{ stay, ROTR, stay, ROTL }, // east arm |
4149 |
{ ROTL, NOTHING, ROTR, NOTHING } // north arm |
{ ROTL, stay, ROTR, stay } // north arm |
4150 |
}; |
}; |
4151 |
|
|
4152 |
ActorInfo *ai = sc.actor->get_actorinfo(); |
ActorInfo *ai = sc.actor->get_actorinfo(); |
4271 |
if (arms & WESTBIT) set_arm (SOUTH); |
if (arms & WESTBIT) set_arm (SOUTH); |
4272 |
|
|
4273 |
#if defined(USE_IMPULSES) |
#if defined(USE_IMPULSES) |
4274 |
warpItemsInRange(false); |
warpActorsInRange(false); |
4275 |
#endif // USE_IMPULSES |
#endif // USE_IMPULSES |
4276 |
|
|
4277 |
|
display::GetStatusBar()->set_counter(player::IncMoveCounter()); |
4278 |
} |
} |
4279 |
return can_rotate; |
return can_rotate; |
4280 |
} |
} |
4317 |
if (arms & WESTBIT) set_arm (NORTH); |
if (arms & WESTBIT) set_arm (NORTH); |
4318 |
|
|
4319 |
#if defined(USE_IMPULSES) |
#if defined(USE_IMPULSES) |
4320 |
warpItemsInRange(true); |
warpActorsInRange(true); |
4321 |
#endif // USE_IMPULSES |
#endif // USE_IMPULSES |
4322 |
|
|
4323 |
|
display::GetStatusBar()->set_counter(player::IncMoveCounter()); |
4324 |
} |
} |
4325 |
return can_rotate; |
return can_rotate; |
4326 |
} |
} |