167 |
return false; |
return false; |
168 |
} |
} |
169 |
|
|
170 |
|
namespace { |
171 |
|
const char *vstrf(const char *format, va_list argPtr) { |
172 |
|
static size_t buf_size = 256; |
173 |
|
static char *buffer = new char[buf_size]; |
174 |
|
|
175 |
|
size_t length; |
176 |
|
while (1) { |
177 |
|
if (!buffer) { |
178 |
|
assert(buffer); // to stop when debugging |
179 |
|
throw std::bad_alloc(); |
180 |
|
} |
181 |
|
|
182 |
|
length = vsnprintf(buffer, buf_size, format, argPtr); |
183 |
|
if (length < buf_size) break; // string fits into current buffer |
184 |
|
|
185 |
|
// otherwise resize buffer : |
186 |
|
buf_size += buf_size/2; |
187 |
|
delete [] buffer; |
188 |
|
buffer = new char[buf_size]; |
189 |
|
} |
190 |
|
|
191 |
|
return buffer; |
192 |
|
} |
193 |
|
}; |
194 |
|
|
195 |
void |
void |
196 |
Object::log(const char *format, ...) const { |
Object::log(const char *format, ...) const { |
197 |
va_list arg_ptr; |
va_list arg_ptr; |
198 |
|
|
199 |
va_start(arg_ptr, format); |
va_start(arg_ptr, format); |
200 |
fprintf(stderr, "non-grid-\"%s\": ", get_kind()); |
cerr << "non-grid-\"" << get_kind() << "\": " |
201 |
vfprintf(stderr, format, arg_ptr); |
<< vstrf(format, arg_ptr) << '\n'; |
|
fputc('\n', stderr); |
|
|
fflush(stderr); |
|
202 |
va_end(arg_ptr); |
va_end(arg_ptr); |
203 |
} |
} |
204 |
|
|
217 |
const GridPos& pos = get_pos(); |
const GridPos& pos = get_pos(); |
218 |
|
|
219 |
va_start(arg_ptr, format); |
va_start(arg_ptr, format); |
220 |
fprintf(stderr, "\"%s\" at %i/%i: ", get_kind(), pos.x, pos.y); |
cerr << "\"" << get_kind() << "\" at " << pos.x << '/' << pos.y << ": " |
221 |
vfprintf(stderr, format, arg_ptr); |
<< vstrf(format, arg_ptr) << '\n'; |
|
fputc('\n', stderr); |
|
|
fflush(stderr); |
|
222 |
va_end(arg_ptr); |
va_end(arg_ptr); |
223 |
} |
} |
224 |
|
|
1631 |
Stone *st = GetStone(next_pos); |
Stone *st = GetStone(next_pos); |
1632 |
|
|
1633 |
if (st) { |
if (st) { |
1634 |
log("BolderStone sends 'trigger'"); |
// log("BolderStone sends 'trigger'"); |
1635 |
SendMessage(st, "trigger", Value(dir)); |
SendMessage(st, "trigger", Value(dir)); |
1636 |
} |
} |
|
|
|
|
// send a message to items that were below the BolderStone |
|
|
// before it moved (e.g. Blocker items) |
|
|
|
|
|
Item *it = GetItem(last_pos); |
|
|
if (it) { |
|
|
log("BolderStone sends 'grow'"); |
|
|
SendMessage(it, "grow"); |
|
|
} |
|
1637 |
} |
} |
1638 |
state = IDLE; |
state = IDLE; |
1639 |
} |
} |
1945 |
// If the floor at the cluster's new position consists exclusively |
// If the floor at the cluster's new position consists exclusively |
1946 |
// of abyss or water, create a bridge instead of moving the |
// of abyss or water, create a bridge instead of moving the |
1947 |
// cluster. |
// cluster. |
1948 |
bool create_bridge=false; |
bool create_bridge = false; |
1949 |
|
|
1950 |
|
#if 0 // oxyd creates bridges of partial clusters (at least per.oxyd) |
1951 |
if (is_complete) { |
if (is_complete) { |
1952 |
create_bridge=true; |
#endif |
1953 |
|
create_bridge = true; |
1954 |
for (unsigned i=0; i<mc.size(); ++i) { |
for (unsigned i=0; i<mc.size(); ++i) { |
1955 |
if (Floor *fl = GetFloor(mc[i])) { |
if (Floor *fl = GetFloor(mc[i])) { |
1956 |
const string &k = fl->get_kind(); |
const string &k = fl->get_kind(); |
1960 |
} |
} |
1961 |
} |
} |
1962 |
} |
} |
1963 |
|
#if 0 |
1964 |
} |
} |
1965 |
|
#endif |
1966 |
|
|
1967 |
// Finally, either move the whole cluster or create a bridge |
// Finally, either move the whole cluster or create a bridge |
1968 |
play_sound("st-move"); |
play_sound("st-move"); |
2033 |
maybe_move_cluster(c, is_complete, dir); |
maybe_move_cluster(c, is_complete, dir); |
2034 |
} |
} |
2035 |
|
|
2036 |
|
|
2037 |
|
|
2038 |
void |
void |
2039 |
PuzzleStone::actor_hit(const StoneContact &sc) |
PuzzleStone::actor_hit(const StoneContact &sc) |
2040 |
{ |
{ |
2041 |
if (get_connections() == NODIRBIT) |
if (get_connections() == NODIRBIT) |
2042 |
return; |
return; |
2043 |
|
|
2044 |
Actor *a = sc.actor; |
Actor *a = sc.actor; |
2045 |
|
Direction hit_dir = reverse(contact_face(sc)); |
2046 |
|
|
2047 |
bool move_impulse= (a->get_vel()*sc.normal < -4); |
if (hit_dir != NODIR) { |
2048 |
Direction hit_dir=reverse(contact_face(sc)); |
if (wielded_item_is(a, "it-magicwand")) { |
|
|
|
|
if (wielded_item_is(a, "it-magicwand")) { |
|
|
if (cluster_complete()) { |
|
|
// make all cluster stones explode |
|
|
return; |
|
|
} |
|
|
else if (hit_dir != NODIR) { |
|
2049 |
Cluster c; |
Cluster c; |
2050 |
find_row_or_column_cluster(c, get_pos(), hit_dir); |
find_row_or_column_cluster(c, get_pos(), hit_dir); |
2051 |
|
if (c.size() == 1) { |
2052 |
bool is_complete = false; |
maybe_move_cluster(c, false, hit_dir); |
2053 |
|
} |
2054 |
if (move_impulse) |
else { |
|
maybe_move_cluster(c, is_complete, hit_dir); |
|
|
else |
|
2055 |
rotate_cluster(c); |
rotate_cluster(c); |
2056 |
|
} |
2057 |
|
} |
2058 |
|
else { |
2059 |
|
if (a->get_vel()*sc.normal < -4) { |
2060 |
|
SendImpulse(get_pos(), hit_dir, a); |
2061 |
|
} |
2062 |
} |
} |
|
} |
|
|
else if (move_impulse && hit_dir != NODIR) { |
|
|
SendImpulse(get_pos(), hit_dir, a); |
|
2063 |
} |
} |
2064 |
} |
} |
2065 |
|
|
3126 |
|
|
3127 |
// Stone interface: |
// Stone interface: |
3128 |
|
|
|
void on_impulse(Direction dir) { |
|
|
if (move_stone(dir)) { |
|
|
// on_move changes state to PULSING |
|
|
incoming = dir; |
|
|
} |
|
|
else { |
|
|
StoneImpulse_Base::on_impulse(dir); |
|
|
} |
|
|
} |
|
|
|
|
3129 |
void actor_hit(const StoneContact &sc) { |
void actor_hit(const StoneContact &sc) { |
3130 |
ActorInfo *ai = sc.actor->get_actorinfo(); |
ActorInfo *ai = sc.actor->get_actorinfo(); |
3131 |
Direction dir = contact_face(sc); |
Direction dir = contact_face(sc); |
3137 |
SendImpulse(get_pos(), reverse(dir), sc.actor); |
SendImpulse(get_pos(), reverse(dir), sc.actor); |
3138 |
} |
} |
3139 |
else { |
else { |
3140 |
incoming = NODIR; // @@@ problem! |
incoming = NODIR; // bad, but no real problem! |
3141 |
change_state(PULSING); |
change_state(PULSING); |
3142 |
} |
} |
3143 |
} |
} |
3144 |
|
|
3145 |
|
void on_impulse(Direction dir) { |
3146 |
|
if (move_stone(dir)) { |
3147 |
|
// on_move changes state to PULSING |
3148 |
|
incoming = dir; |
3149 |
|
} |
3150 |
|
else { |
3151 |
|
StoneImpulse_Base::on_impulse(dir); |
3152 |
|
} |
3153 |
|
} |
3154 |
|
|
3155 |
void on_move() { |
void on_move() { |
3156 |
|
Actor *hitman = dynamic_cast<Actor*>(ImpulseSender()); |
3157 |
|
if (hitman && wielded_item_is(hitman, "it-magicwand")) { |
3158 |
|
// move was initiated by actor with magicwand |
3159 |
|
return; // dont pulse! |
3160 |
|
} |
3161 |
|
|
3162 |
if (state != IDLE) change_state(IDLE); |
if (state != IDLE) change_state(IDLE); |
3163 |
if (state == IDLE) change_state(PULSING); |
change_state(PULSING); |
3164 |
} |
} |
3165 |
|
|
3166 |
bool is_movable() { |
bool is_movable() { |
3167 |
if (state != IDLE) { |
if (state != IDLE) change_state(IDLE); |
|
change_state(IDLE); |
|
|
} |
|
3168 |
return state == IDLE; |
return state == IDLE; |
3169 |
} |
} |
3170 |
|
|