212 |
Floor *fl; |
Floor *fl; |
213 |
|
|
214 |
if( name == 0) { |
if( name == 0) { |
215 |
fprintf(stderr, "Unknown floor %X\n",code); |
// fprintf(stderr, "Unknown floor %X\n",code); |
216 |
fl = MakeFloor("fl-dummy"); |
fl = MakeFloor("fl-dummy"); |
217 |
fl->set_attrib("code", code); |
fl->set_attrib("code", code); |
218 |
} |
} |
247 |
{ |
{ |
248 |
const char *name = m_mapping.itemName(type); |
const char *name = m_mapping.itemName(type); |
249 |
if( name == 0) { |
if( name == 0) { |
250 |
fprintf(stderr, "Unknown item %X\n",type); |
// fprintf(stderr, "Unknown item %X\n",type); |
251 |
it = MakeItem ("it-dummy"); |
it = MakeItem ("it-dummy"); |
252 |
it->set_attrib("code", type); |
it->set_attrib("code", type); |
253 |
} |
} |
330 |
// No special case -> get Stone from map |
// No special case -> get Stone from map |
331 |
const char *name = m_mapping.stoneName(type); |
const char *name = m_mapping.stoneName(type); |
332 |
if (name == 0) { |
if (name == 0) { |
333 |
fprintf (stderr, "Unknown stone %X\n", type); |
// fprintf (stderr, "Unknown stone %X\n", type); |
334 |
st = MakeStone ("st-dummy"); |
st = MakeStone ("st-dummy"); |
335 |
st->set_attrib("code", type); |
st->set_attrib("code", type); |
336 |
} |
} |
355 |
} |
} |
356 |
} |
} |
357 |
|
|
358 |
|
namespace { |
359 |
|
void dumpUnknownObjects(const Level& level) { |
360 |
|
set<int> stones, items, floors; |
361 |
|
|
362 |
|
const Grid &sgrid = level.getGrid (GridType_Pieces); |
363 |
|
for (unsigned y=0; y<sgrid.getHeight(); ++y) |
364 |
|
for (unsigned x=0; x<sgrid.getWidth(); ++x) |
365 |
|
if (Stone *st = world::GetStone(GridPos(x, y))) |
366 |
|
if (int code = st->int_attrib("code")) |
367 |
|
stones.insert(code); |
368 |
|
|
369 |
|
const Grid &igrid = level.getGrid (GridType_Objects); |
370 |
|
for (unsigned y=0; y<igrid.getHeight(); ++y) |
371 |
|
for (unsigned x=0; x<igrid.getWidth(); ++x) |
372 |
|
if (Item *it = world::GetItem(GridPos(x, y))) |
373 |
|
if (int code = it->int_attrib("code")) |
374 |
|
items.insert(code); |
375 |
|
|
376 |
|
const Grid &fgrid = level.getGrid (GridType_Objects); |
377 |
|
for (unsigned y=0; y<fgrid.getHeight(); ++y) |
378 |
|
for (unsigned x=0; x<fgrid.getWidth(); ++x) |
379 |
|
if (world::Floor *fl = world::GetFloor(GridPos(x, y))) |
380 |
|
if (int code = fl->int_attrib("code")) |
381 |
|
floors.insert(code); |
382 |
|
|
383 |
|
if (!stones.empty()) { |
384 |
|
fprintf(stderr, "Unknown stones:"); |
385 |
|
for (set<int>::iterator i = stones.begin(); i != stones.end(); ++i) |
386 |
|
fprintf(stderr, " %i", *i); |
387 |
|
fprintf(stderr, "\n"); |
388 |
|
} |
389 |
|
if (!items.empty()) { |
390 |
|
fprintf(stderr, "Unknown items:"); |
391 |
|
for (set<int>::iterator i = items.begin(); i != items.end(); ++i) |
392 |
|
fprintf(stderr, " %i", *i); |
393 |
|
fprintf(stderr, "\n"); |
394 |
|
} |
395 |
|
if (!floors.empty()) { |
396 |
|
fprintf(stderr, "Unknown floors:"); |
397 |
|
for (set<int>::iterator i = floors.begin(); i != floors.end(); ++i) |
398 |
|
fprintf(stderr, " %i", *i); |
399 |
|
fprintf(stderr, "\n"); |
400 |
|
} |
401 |
|
} |
402 |
|
} |
403 |
|
|
404 |
|
namespace { |
405 |
|
|
406 |
|
#define MAX_MARBLE_INFO_FIELDS 11 |
407 |
|
#define DEFAULT_VALUE (-1) |
408 |
|
#define TRACE_MARBLE_INFO // check for uninterpreted fields |
409 |
|
|
410 |
|
enum MarbleInfoIndices { |
411 |
|
// valid for all actor types: |
412 |
|
MI_FORCE = 0, |
413 |
|
|
414 |
|
// marbles only: |
415 |
|
|
416 |
|
// Jack/Rotor only: |
417 |
|
MI_RANGE = 1, |
418 |
|
}; |
419 |
|
|
420 |
|
class MarbleInfo { |
421 |
|
int value[MAX_MARBLE_INFO_FIELDS]; |
422 |
|
#if defined(TRACE_MARBLE_INFO) |
423 |
|
bool interpreted[MAX_MARBLE_INFO_FIELDS]; |
424 |
|
#endif // TRACE_MARBLE_INFO |
425 |
|
|
426 |
|
public: |
427 |
|
MarbleInfo(const Marble& marble); |
428 |
|
~MarbleInfo(); |
429 |
|
|
430 |
|
bool is_default(int idx) { |
431 |
|
assert(idx >= 0 && idx<MAX_MARBLE_INFO_FIELDS); |
432 |
|
return value[idx] == DEFAULT_VALUE; |
433 |
|
} |
434 |
|
|
435 |
|
int get_value(int idx) { |
436 |
|
assert(!is_default(idx)); // you cannot ask for default value (not stored here) |
437 |
|
#if defined(TRACE_MARBLE_INFO) |
438 |
|
interpreted[idx] = true; |
439 |
|
#endif // TRACE_MARBLE_INFO |
440 |
|
return value[idx]; |
441 |
|
} |
442 |
|
}; |
443 |
|
|
444 |
|
MarbleInfo::MarbleInfo(const Marble& marble) { |
445 |
|
const string& data = marble.getData(options::Difficulty == DIFFICULTY_EASY ? GameMode_Easy : GameMode_Hard); |
446 |
|
size_t from = 0; |
447 |
|
int idx = 0; |
448 |
|
|
449 |
|
while (from != string::npos) { |
450 |
|
size_t par_open = data.find('(', from); |
451 |
|
from = string::npos; |
452 |
|
|
453 |
|
if (par_open != string::npos) { |
454 |
|
size_t par_close = data.find(')', par_open); |
455 |
|
if (par_close != string::npos) { |
456 |
|
from = par_close; |
457 |
|
if (par_close == par_open+1) { |
458 |
|
value[idx++] = DEFAULT_VALUE; |
459 |
|
} |
460 |
|
else { |
461 |
|
value[idx++] = atoi(data.substr(par_open+1, par_close-par_open-1).c_str()); |
462 |
|
} |
463 |
|
} |
464 |
|
else { |
465 |
|
fprintf(stderr, "Error in MarbleInfo: missing closing parenthesis\n"); |
466 |
|
} |
467 |
|
} |
468 |
|
} |
469 |
|
for (; idx<MAX_MARBLE_INFO_FIELDS; ++idx) |
470 |
|
value[idx] = DEFAULT_VALUE; |
471 |
|
|
472 |
|
for (idx = 0; idx<MAX_MARBLE_INFO_FIELDS; ++idx) |
473 |
|
interpreted[idx] = false; |
474 |
|
} |
475 |
|
|
476 |
|
MarbleInfo::~MarbleInfo() { |
477 |
|
#if defined(TRACE_MARBLE_INFO) |
478 |
|
for (int idx = 0; idx<MAX_MARBLE_INFO_FIELDS; ++idx) { |
479 |
|
if (!interpreted[idx] && !is_default(idx)) { |
480 |
|
fprintf(stderr, "MarbleInfo[%i]=%i is not used yet.\n", idx, get_value(idx)); |
481 |
|
} |
482 |
|
} |
483 |
|
#endif // TRACE_MARBLE_INFO |
484 |
|
} |
485 |
|
|
486 |
|
#undef DEFAULT_VALUE |
487 |
|
#undef MAX_MARBLE_INFO_FIELDS |
488 |
|
}; |
489 |
|
|
490 |
void |
void |
491 |
LevelPack_Oxyd::load_actors (const Level &level) |
LevelPack_Oxyd::load_actors (const Level &level) |
492 |
{ |
{ |
496 |
|
|
497 |
for (int i=0; i<nmarbles; ++i) { |
for (int i=0; i<nmarbles; ++i) { |
498 |
const Marble &marble = level.getMarble(i); |
const Marble &marble = level.getMarble(i); |
499 |
double x = marble.getX()/32.0; |
double x = marble.getX()/32.0; |
500 |
double y = marble.getY()/32.0; |
double y = marble.getY()/32.0; |
501 |
Actor *ac = 0; |
Actor *ac = 0; |
502 |
|
|
503 |
|
MarbleInfo minfo(marble); |
504 |
|
|
505 |
switch (marble.getMarbleType()) { |
switch (marble.getMarbleType()) { |
506 |
case MarbleType_Black: |
case MarbleType_Black: |
514 |
case MarbleType_Meditation: |
case MarbleType_Meditation: |
515 |
ac = MakeActor ("ac-whiteball-small"); |
ac = MakeActor ("ac-whiteball-small"); |
516 |
ac->set_attrib ("player", Value(0.0)); |
ac->set_attrib ("player", Value(0.0)); |
517 |
ac->set_attrib ("mouseforce", Value(1.0)); |
|
518 |
|
if (minfo.is_default(MI_FORCE)) { |
519 |
|
ac->set_attrib("mouseforce", Value(1.0)); |
520 |
|
} |
521 |
|
else { |
522 |
|
ac->set_attrib("mouseforce", Value(minfo.get_value(MI_FORCE) / 32.0)); // just a guess |
523 |
|
} |
524 |
|
break; |
525 |
|
case MarbleType_Jack: |
526 |
|
ac = MakeActor ("ac-top"); |
527 |
|
if (!minfo.is_default(MI_FORCE)) { |
528 |
|
double force = minfo.get_value(MI_FORCE) / 10.0 * 2.0; // just a guess |
529 |
|
ac->set_attrib("force", Value(force) ); |
530 |
|
fprintf(stderr, "Set jack force to %f\n", force); |
531 |
|
} |
532 |
|
if (!minfo.is_default(MI_RANGE)) { |
533 |
|
double range = minfo.get_value(MI_RANGE) / 32.0; // value seems to contain distance in pixels |
534 |
|
ac->set_attrib("range", Value(range) ); |
535 |
|
fprintf(stderr, "Set jack range to %f\n", range); |
536 |
|
} |
537 |
|
break; |
538 |
|
case MarbleType_Rotor: |
539 |
|
ac = MakeActor ("ac-rotor"); |
540 |
|
if (!minfo.is_default(MI_FORCE)) { |
541 |
|
double force = minfo.get_value(MI_FORCE) / 10.0 * 2.0; // just a guess |
542 |
|
ac->set_attrib("force", Value(force) ); |
543 |
|
fprintf(stderr, "Set rotor force to %f\n", force); |
544 |
|
} |
545 |
|
if (!minfo.is_default(MI_RANGE)) { |
546 |
|
double range = minfo.get_value(MI_RANGE) / 32.0; // value seems to contain distance in pixels |
547 |
|
ac->set_attrib("range", Value(range) ); |
548 |
|
fprintf(stderr, "Set rotor range to %f\n", range); |
549 |
|
} |
550 |
break; |
break; |
|
case MarbleType_Jack: ac = MakeActor ("ac-top"); break; |
|
|
case MarbleType_Horse: ac = MakeActor("ac-horse"); break; |
|
|
case MarbleType_Rotor: ac = MakeActor ("ac-rotor"); break; |
|
|
case MarbleType_Bug: ac = MakeActor ("ac-bug"); break; |
|
551 |
|
|
552 |
case MarbleType_LifeSpitter: |
case MarbleType_Horse: |
553 |
case MarbleType_DynamiteHolder: |
ac = MakeActor("ac-horse"); |
554 |
|
break; |
555 |
|
case MarbleType_Bug: |
556 |
|
ac = MakeActor ("ac-bug"); |
557 |
break; |
break; |
558 |
default: |
default: |
559 |
|
fprintf(stderr, "Unhandled actor type %i\n", int(marble.getMarbleType())); |
560 |
break; |
break; |
561 |
|
// case MarbleType_LifeSpitter: |
562 |
|
// case MarbleType_DynamiteHolder: |
563 |
|
// break; |
564 |
} |
} |
565 |
|
|
566 |
if (ac) { |
if (ac) { |
567 |
AddActor (x, y, ac); |
AddActor (x, y, ac); |
568 |
} |
} |
569 |
} |
} |
|
|
|
570 |
} |
} |
571 |
|
|
572 |
GridLoc to_gridloc (const SignalLocation &a) |
GridLoc to_gridloc (const SignalLocation &a) |
622 |
load_floor (level); |
load_floor (level); |
623 |
load_items (level); |
load_items (level); |
624 |
load_stones (level); |
load_stones (level); |
625 |
|
|
626 |
|
dumpUnknownObjects(level); |
627 |
|
|
628 |
scramble_puzzles(level); |
scramble_puzzles(level); |
629 |
load_actors (level); |
load_actors (level); |
630 |
connect_signals (level); |
connect_signals (level); |