208 |
SHATTERING, |
SHATTERING, |
209 |
SINKING, |
SINKING, |
210 |
DROWNING, |
DROWNING, |
211 |
|
BUBBLING, |
212 |
FALLING, |
FALLING, |
213 |
JUMPING, |
JUMPING, |
214 |
DEAD, // marble is dead |
DEAD, // marble is dead |
218 |
}; |
}; |
219 |
State state; |
State state; |
220 |
|
|
221 |
|
double sinkDepth; // how deep actor has sunk |
222 |
|
static const int minSinkDepth = 0; // normal level |
223 |
|
static const int maxSinkDepth = 10; // at that level he dies |
224 |
|
int sinkModel; // current model |
225 |
|
|
226 |
|
|
227 |
void set_model_cb(const string &m) { |
void set_model_cb(const string &m) { |
228 |
set_model(m.c_str()); |
set_model(m.c_str()); |
229 |
get_sprite().set_callback (this); |
get_sprite().set_callback (this); |
230 |
} |
} |
231 |
|
|
232 |
|
void set_sink_model(const string &m) { |
233 |
|
int modelnum = static_cast<int>(sinkDepth); |
234 |
|
|
235 |
|
if (modelnum != sinkModel) { |
236 |
|
assert(modelnum >= minSinkDepth && modelnum < maxSinkDepth); |
237 |
|
|
238 |
|
string img = m+"-sink"; |
239 |
|
img.append(1, static_cast<char>('0'+modelnum)); |
240 |
|
set_model(img); |
241 |
|
|
242 |
|
sinkModel = modelnum; |
243 |
|
} |
244 |
|
} |
245 |
|
|
246 |
|
void think (double dtime); |
247 |
|
|
248 |
void change_state(State newstate); |
void change_state(State newstate); |
249 |
|
|
250 |
// ModelCallback interface. |
// ModelCallback interface. |
305 |
} |
} |
306 |
} |
} |
307 |
|
|
308 |
|
void BasicBall::think(double dtime) { |
309 |
|
if (state == SINKING) { |
310 |
|
ActorInfo *ai = get_actorinfo(); |
311 |
|
|
312 |
|
const double defaultSinkSpeed = 10.0; // 10.0 means : sink in 1 second (if absVelocity == 0) |
313 |
|
const double nonSinkVelocity = 8.0; // at this velocity don't sink; above: raise |
314 |
|
|
315 |
|
double absVelocity = sqrt(ai->vel[0]*ai->vel[0] + ai->vel[1]*ai->vel[1]); |
316 |
|
double sinkSpeed = absVelocity * -(defaultSinkSpeed/nonSinkVelocity) + defaultSinkSpeed; |
317 |
|
|
318 |
|
sinkDepth += sinkSpeed*dtime; |
319 |
|
|
320 |
|
// fprintf(stderr, "dtime=%f absVelocity=%f sinkSpeed=%f sinkDepth=%f\n", |
321 |
|
// dtime, absVelocity, sinkSpeed, sinkDepth); |
322 |
|
|
323 |
|
if (sinkDepth >= maxSinkDepth) { |
324 |
|
// sound::PlaySound("shatter"); |
325 |
|
set_model(string(get_kind())+"-sunk"); |
326 |
|
ai->vel = V2(); // stop! |
327 |
|
change_state(BUBBLING); |
328 |
|
} |
329 |
|
else { |
330 |
|
if (sinkDepth < minSinkDepth) sinkDepth = minSinkDepth; |
331 |
|
set_sink_model(get_kind()); |
332 |
|
} |
333 |
|
} |
334 |
|
} |
335 |
|
|
336 |
void BasicBall::animcb() |
void BasicBall::animcb() |
337 |
{ |
{ |
338 |
string kind=get_kind(); |
string kind=get_kind(); |
344 |
set_model(kind+"-shattered"); |
set_model(kind+"-shattered"); |
345 |
change_state(DEAD); |
change_state(DEAD); |
346 |
break; |
break; |
|
case SINKING: |
|
|
// sound::PlaySound("groan"); |
|
|
sound::PlaySound("shatter"); |
|
|
set_model(kind+"-sunk"); |
|
|
change_state(DEAD); |
|
|
break; |
|
347 |
case DROWNING: |
case DROWNING: |
348 |
|
case BUBBLING: |
349 |
// sound::PlaySound("groan"); |
// sound::PlaySound("groan"); |
350 |
set_model("invisible"); |
set_model("invisible"); |
351 |
change_state(DEAD); |
change_state(DEAD); |
388 |
ai->forceacc = V2(); |
ai->forceacc = V2(); |
389 |
} |
} |
390 |
else if (oldstate == SINKING) { |
else if (oldstate == SINKING) { |
391 |
set_model_cb(kind); |
set_model(kind); |
392 |
} |
} |
393 |
world::ReleaseActor(this); |
world::ReleaseActor(this); |
394 |
break; |
break; |
400 |
case SINKING: |
case SINKING: |
401 |
if (oldstate != SINKING) { |
if (oldstate != SINKING) { |
402 |
world::ReleaseActor(this); |
world::ReleaseActor(this); |
403 |
set_model_cb(kind+"-sink"); |
sinkDepth = minSinkDepth; |
404 |
|
set_sink_model(kind); |
405 |
} |
} |
406 |
break; |
break; |
407 |
case DROWNING: |
case DROWNING: |
408 |
|
// @@@ FIXME: use same animation as SINKING ? |
409 |
|
world::GrabActor(this); |
410 |
|
sound::PlaySound("drown"); |
411 |
|
// set_model_cb("ring-anim"); |
412 |
|
set_model_cb("ac-drowned"); |
413 |
|
break; |
414 |
|
case BUBBLING: |
415 |
world::GrabActor(this); |
world::GrabActor(this); |
416 |
sound::PlaySound("drown"); |
sound::PlaySound("drown"); |
417 |
set_model_cb("ring-anim"); |
set_model_cb("ac-drowned"); |
418 |
break; |
break; |
419 |
case FALLING: |
case FALLING: |
420 |
world::GrabActor(this); |
world::GrabActor(this); |