diff options
Diffstat (limited to 'engines/dreamweb/object.cpp')
-rw-r--r-- | engines/dreamweb/object.cpp | 1069 |
1 files changed, 954 insertions, 115 deletions
diff --git a/engines/dreamweb/object.cpp b/engines/dreamweb/object.cpp index 53d834e74c..443366561a 100644 --- a/engines/dreamweb/object.cpp +++ b/engines/dreamweb/object.cpp @@ -22,32 +22,46 @@ #include "dreamweb/dreamweb.h" -namespace DreamGen { +namespace DreamWeb { -void DreamGenContext::fillRyan() { - uint8 *inv = getSegment(data.word(kBuffers)).ptr(kRyaninvlist, 60); - findAllRyan(inv); - inv += data.byte(kRyanpage) * 2 * 10; +void DreamWebEngine::showRyanPage() { + showFrame(_icons1, kInventx + 167, kInventy - 12, 12, 0); + showFrame(_icons1, kInventx + 167 + 18 * _vars._ryanPage, kInventy - 12, 13 + _vars._ryanPage, 0); +} + +void DreamWebEngine::findAllRyan() { + memset(_ryanInvList, 0xff, sizeof(_ryanInvList)); + for (size_t i = 0; i < kNumexobjects; ++i) { + const DynObject *extra = getExAd(i); + if (extra->mapad[0] != kExObjectType) + continue; + if (extra->mapad[1] != 0xff) + continue; + uint8 slot = extra->mapad[2]; + assert(slot < 30); + _ryanInvList[slot]._index = i; + _ryanInvList[slot]._type = kExObjectType; + } +} + +void DreamWebEngine::fillRyan() { + ObjectRef *inv = &_ryanInvList[_vars._ryanPage * 10]; + findAllRyan(); for (size_t i = 0; i < 2; ++i) { for (size_t j = 0; j < 5; ++j) { - uint8 objIndex = *inv++; - uint8 objType = *inv++; - obToInv(objIndex, objType, kInventx + j * kItempicsize, kInventy + i * kItempicsize); + obToInv(inv->_index, inv->_type, kInventx + j * kItempicsize, kInventy + i * kItempicsize); + ++inv; } } showRyanPage(); } -void DreamGenContext::isItWorn() { - flags._z = isItWorn((const DynObject *)es.ptr(bx, sizeof(DynObject))); +bool DreamWebEngine::isItWorn(const DynObject *object) { + return (object->objId[0] == 'W'-'A') && (object->objId[1] == 'E'-'A'); } -bool DreamGenContext::isItWorn(const DynObject *object) { - return (object->id[0] == 'W'-'A') && (object->id[1] == 'E'-'A'); -} - -void DreamGenContext::wornError() { - data.byte(kCommandtype) = 255; +void DreamWebEngine::wornError() { + _commandType = 255; delPointer(); printMessage(76, 21, 57, 240, false); workToScreenM(); @@ -55,75 +69,66 @@ void DreamGenContext::wornError() { showPanel(); showMan(); examIcon(); - data.byte(kCommandtype) = 255; + _commandType = 255; workToScreenM(); } -void DreamGenContext::makeWorn() { - makeWorn((DynObject *)es.ptr(bx, sizeof(DynObject))); -} - -void DreamGenContext::makeWorn(DynObject *object) { - object->id[0] = 'W'-'A'; - object->id[1] = 'E'-'A'; -} - -void DreamGenContext::obToInv() { - obToInv(al, ah, di, bx); +void DreamWebEngine::makeWorn(DynObject *object) { + object->objId[0] = 'W'-'A'; + object->objId[1] = 'E'-'A'; } -void DreamGenContext::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { - showFrame(engine->icons1(), x - 2, y - 1, 10, 0); +void DreamWebEngine::obToInv(uint8 index, uint8 flag, uint16 x, uint16 y) { + showFrame(_icons1, x - 2, y - 1, 10, 0); if (index == 0xff) return; - Frame *extras = (Frame *)getSegment(data.word(kExtras)).ptr(0, 0); - Frame *frees = (Frame *)getSegment(data.word(kFreeframes)).ptr(0, 0); - Frame *frames = (flag == 4) ? extras : frees; - showFrame(frames, x + 18, y + 19, 3 * index + 1, 128); + if (flag == kExObjectType) + showFrame(_exFrames, x + 18, y + 19, 3 * index + 1, 128); + else + showFrame(_freeFrames, x + 18, y + 19, 3 * index + 1, 128); + const DynObject *object = (const DynObject *)getAnyAdDir(index, flag); bool worn = isItWorn(object); if (worn) - showFrame(engine->icons1(), x - 3, y - 2, 7, 0); + showFrame(_icons1, x - 3, y - 2, 7, 0); } -void DreamGenContext::obPicture() { - if (data.byte(kObjecttype) == 1) +void DreamWebEngine::obPicture() { + if (_objectType == kSetObjectType1) return; - Frame *frames; - if (data.byte(kObjecttype) == 4) - frames = (Frame *)getSegment(data.word(kExtras)).ptr(0, 0); + uint8 frame = 3 * _command + 1; + if (_objectType == kExObjectType) + showFrame(_exFrames, 160, 68, frame, 0x80); else - frames = (Frame *)getSegment(data.word(kFreeframes)).ptr(0, 0); - uint8 frame = 3 * data.byte(kCommand) + 1; - showFrame(frames, 160, 68, frame, 0x80); + showFrame(_freeFrames, 160, 68, frame, 0x80); } -void DreamBase::obIcons() { - uint8 value1, value2; - getAnyAd(&value1, &value2); - if (value1 != 0xff) { +void DreamWebEngine::obIcons() { + uint8 slotSize, slotCount; + getAnyAd(&slotSize, &slotCount); + if (slotSize != 0xff) { // can open it - showFrame(engine->icons2(), 210, 1, 4, 0); + showFrame(_icons2, 210, 1, 4, 0); } - showFrame(engine->icons2(), 260, 1, 1, 0); + showFrame(_icons2, 260, 1, 1, 0); } -void DreamGenContext::examineOb(bool examineAgain) { - data.byte(kPointermode) = 0; - data.word(kTimecount) = 0; +void DreamWebEngine::examineOb(bool examineAgain) { + _pointerMode = 0; + _timeCount = 0; + while (true) { if (examineAgain) { - data.byte(kInmaparea) = 0; - data.byte(kExamagain) = 0; - data.byte(kOpenedob) = 255; - data.byte(kOpenedtype) = 255; - data.byte(kInvopen) = 0; - al = data.byte(kCommandtype); - data.byte(kObjecttype) = al; - data.byte(kItemframe) = 0; - data.byte(kPointerframe) = 0; + _inMapArea = 0; + _examAgain = 0; + _openedOb = 255; + _openedType = 255; + _invOpen = 0; + _objectType = _commandType; + _itemFrame = 0; + _pointerFrame = 0; createPanel(); showPanel(); showMan(); @@ -132,10 +137,10 @@ void DreamGenContext::examineOb(bool examineAgain) { obPicture(); describeOb(); underTextLine(); - data.byte(kCommandtype) = 255; + _commandType = 255; readMouse(); showPointer(); - workToScreenCPP(); + workToScreen(); delPointer(); examineAgain = false; } @@ -146,30 +151,31 @@ void DreamGenContext::examineOb(bool examineAgain) { dumpPointer(); dumpTextLine(); delPointer(); - data.byte(kGetback) = 0; - switch (data.byte(kInvopen)) { + _getBack = 0; + + switch (_invOpen) { case 0: { RectWithCallback examList[] = { - { 273,320,157,198,&DreamGenContext::getBackFromOb }, - { 260,300,0,44,&DreamGenContext::useObject }, - { 210,254,0,44,&DreamGenContext::selectOpenOb }, - { 144,176,64,96,&DreamGenContext::setPickup }, - { 0,50,50,200,&DreamGenContext::examineInventory }, - { 0,320,0,200,&DreamGenContext::blank }, + { 273,320,157,198,&DreamWebEngine::getBackFromOb }, + { 260,300,0,44,&DreamWebEngine::useObject }, + { 210,254,0,44,&DreamWebEngine::selectOpenOb }, + { 144,176,64,96,&DreamWebEngine::setPickup }, + { 0,50,50,200,&DreamWebEngine::examineInventory }, + { 0,320,0,200,&DreamWebEngine::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(examList); break; } case 1: { - // NB: This table contains the non-constant openChangeSize! + // Note: This table contains the non-constant _openChangeSize! RectWithCallback invList1[] = { - { 273,320,157,198,&DreamGenContext::getBackFromOb }, - { 255,294,0,24,&DreamGenContext::dropObject }, - { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage }, - { kInventx, data.word(offset_openchangesize),kInventy+100,kInventy+100+kItempicsize,&DreamGenContext::useOpened }, - { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::inToInv }, - { 0,320,0,200,&DreamGenContext::blank }, + { 273,320,157,198,&DreamWebEngine::getBackFromOb }, + { 255,294,0,24,&DreamWebEngine::dropObject }, + { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamWebEngine::incRyanPage }, + { kInventx,_openChangeSize,kInventy+100,kInventy+100+kItempicsize,&DreamWebEngine::useOpened }, + { kInventx,kInventx+(5*kItempicsize),kInventy,kInventy+(2*kItempicsize),&DreamWebEngine::inToInv }, + { 0,320,0,200,&DreamWebEngine::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(invList1); @@ -177,55 +183,52 @@ void DreamGenContext::examineOb(bool examineAgain) { } default: { RectWithCallback withList1[] = { - { 273,320,157,198,&DreamGenContext::getBackFromOb }, - { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamGenContext::incRyanPage }, - { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamGenContext::selectOb }, - { 0,320,0,200,&DreamGenContext::blank }, + { 273,320,157,198,&DreamWebEngine::getBackFromOb }, + { kInventx+167,kInventx+167+(18*3),kInventy-18,kInventy-2,&DreamWebEngine::incRyanPage }, + { kInventx,kInventx+(5*kItempicsize), kInventy,kInventy+(2*kItempicsize),&DreamWebEngine::selectOb }, + { 0,320,0,200,&DreamWebEngine::blank }, { 0xFFFF,0,0,0,0 } }; checkCoords(withList1); break; } } - if (data.byte(kQuitrequested) != 0) + + if (_quitRequested) break; - if (data.byte(kExamagain) != 0) + if (_examAgain != 0) examineAgain = true; - else if (data.byte(kGetback) != 0) + else if (_getBack != 0) break; } - data.byte(kPickup) = 0; - if (data.word(kWatchingtime) != 0 || data.byte(kNewlocation) == 255) { + _pickUp = 0; + if (_vars._watchingTime != 0 || _newLocation == 255) { // isWatching makeMainScreen(); } - data.byte(kInvopen) = 0; - data.byte(kOpenedob) = 255; + _invOpen = 0; + _openedOb = 255; } -void DreamGenContext::inventory() { - if (data.byte(kMandead) == 1 || data.word(kWatchingtime) != 0) { +void DreamWebEngine::inventory() { + if (_vars._manDead == 1 || _vars._watchingTime != 0) { blank(); return; } - if (data.byte(kCommandtype) != 239) { - data.byte(kCommandtype) = 239; - al = 32; - commandOnly(); - } + commandOnlyCond(32, 239); - if (data.word(kMousebutton) == data.word(kOldbutton)) + if (_mouseButton == _oldButton) return; - if (!(data.word(kMousebutton) & 1)) // only on left mouse button + if (!(_mouseButton & 1)) // only on left mouse button return; - data.word(kTimecount) = 0; - data.byte(kPointermode) = 0; - data.byte(kInmaparea) = 0; + _timeCount = 0; + _pointerMode = 0; + _inMapArea = 0; animPointer(); createPanel(); showPanel(); @@ -233,34 +236,870 @@ void DreamGenContext::inventory() { showMan(); showExit(); underTextLine(); - data.byte(kPickup) = 0; - data.byte(kInvopen) = 2; + _pickUp = 0; + _invOpen = 2; openInv(); readMouse(); showPointer(); - workToScreenCPP(); + workToScreen(); delPointer(); - data.byte(kOpenedob) = 255; + _openedOb = 255; examineOb(false); } -void DreamGenContext::transferText() { - getSegment(data.word(kExtras)).word(kExtextdat + data.byte(kExpos) * 2) = data.word(kExtextpos); - uint16 freeTextOffset = data.byte(kItemtotran) * 2; - uint16 srcOffset = getSegment(data.word(kFreedesc)).word(kFreetextdat + freeTextOffset); - const char *src = (const char *)getSegment(data.word(kFreedesc)).ptr(kFreetext + srcOffset, 0); - char *dst = (char *)getSegment(data.word(kExtras)).ptr(kExtext + data.word(kExtextpos), 0); +void DreamWebEngine::transferText(uint8 from, uint8 to) { + _exText.setOffset(to, _vars._exTextPos); + const char *src = _freeDesc.getString(from); + char *dst = _exText._text + _vars._exTextPos; size_t len = strlen(src); memcpy(dst, src, len + 1); - data.word(kExtextpos) += len + 1; + _vars._exTextPos += len + 1; } -void DreamGenContext::getBackFromOb() { - if (data.byte(kPickup) != 1) +void DreamWebEngine::getBackFromOb() { + if (_pickUp != 1) getBack1(); else blank(); } -} // End of namespace DreamGen +byte DreamWebEngine::getOpenedSlotCount() { + byte obj = _openedOb; + switch (_openedType) { + case kExObjectType: + return getExAd(obj)->slotCount; + case kFreeObjectType: + return getFreeAd(obj)->slotCount; + default: + return getSetAd(obj)->slotCount; + } +} + +byte DreamWebEngine::getOpenedSlotSize() { + byte obj = _openedOb; + switch (_openedType) { + case kExObjectType: + return getExAd(obj)->slotSize; + case kFreeObjectType: + return getFreeAd(obj)->slotSize; + default: + return getSetAd(obj)->slotSize; + } +} + +void DreamWebEngine::openOb() { + uint8 commandLine[64] = "OBJECT NAME ONE "; + + copyName(_openedType, _openedOb, commandLine); + + printMessage(kInventx, kInventy+86, 62, 240, false); + + printDirect(commandLine, _lastXPos + 5, kInventy+86, 220, false); + + fillOpen(); + _openChangeSize = getOpenedSlotCount() * kItempicsize + kInventx; +} + +void DreamWebEngine::identifyOb() { + if (_vars._watchingTime != 0) { + blank(); + return; + } + + uint16 initialX = _mouseX - _mapAdX; + uint16 initialY = _mouseY - _mapAdY; + + if (initialX >= 22 * 8 || initialY >= 20 * 8) { + blank(); + return; + } + + byte x = initialX & 0xFF; + byte y = initialY & 0xFF; + + _inMapArea = 1; + _pointersPath = findPathOfPoint(x, y); + _pointerFirstPath = findFirstPath(x, y); + + if (checkIfEx(x, y) || checkIfFree(x, y) || + checkIfPerson(x, y) || checkIfSet(x, y)) + return; // finishidentify + + x = (_mouseX - _mapAdX) & 0xFF; + y = (_mouseY - _mapAdY) & 0xFF; + byte flag, flagEx, type, flagX, flagY; + + checkOne(x, y, &flag, &flagEx, &type, &flagX, &flagY); + + if (type != 0 && _vars._manDead != 1) + obName(type, 3); + else + blank(); +} + +ObjectRef DreamWebEngine::findInvPos() { + uint16 x = _mouseX - kInventx; + uint16 y = _mouseY - kInventy; + uint8 pos = (x / kItempicsize) + (y / kItempicsize) * 5; + uint8 invPos = _vars._ryanPage * 10 + pos; + _lastInvPos = invPos; + return _ryanInvList[invPos]; +} + +void DreamWebEngine::selectOb() { + ObjectRef objectId = findInvPos(); + if (objectId._index == 255) { + blank(); + return; + } + + _withObject = objectId._index; + _withType = objectId._type; + + if (objectId != _oldSubject || _commandType != 221) { + if (objectId == _oldSubject) + _commandType = 221; + _oldSubject = objectId; + commandWithOb(0, objectId._type, objectId._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + delPointer(); + _invOpen = 0; + useRoutine(); +} + +void DreamWebEngine::setPickup() { + if (_objectType != kSetObjectType1 && _objectType != kSetObjectType3) { + // Object types 1 and 3 are excluded, so the resulting object is a DynObject + uint8 dummy; + DynObject *object = (DynObject *)getAnyAd(&dummy, &dummy); + if (object->mapad[0] == 4) { + blank(); + return; + } + } else { + blank(); + return; + } + + if (_commandType != 209) { + _commandType = 209; + commandWithOb(33, _objectType, _command); + } + + if (_mouseButton != 1 || _mouseButton == _oldButton) + return; + + createPanel(); + showPanel(); + showMan(); + showExit(); + examIcon(); + _pickUp = 1; + _invOpen = 2; + + if (_objectType != kExObjectType) { + assert(_objectType == kFreeObjectType); + _openedOb = 255; + _itemFrame = transferToEx(_command); + _objectType = kExObjectType; + DynObject *object = getExAd(_itemFrame); + object->mapad[0] = 20; + object->mapad[1] = 255; + } else { + _itemFrame = _command; + _openedOb = 255; + } + + openInv(); + workToScreenM(); +} + +void DreamWebEngine::deleteExFrame(uint8 frameNum) { + Frame *frame = &_exFrames._frames[frameNum]; + + uint16 frameSize = frame->width * frame->height; + // Note: the original asm didn't subtract frameSize from remainder + uint16 remainder = kExframeslen - frame->ptr() - frameSize; + uint16 startOff = frame->ptr(); + uint16 endOff = startOff + frameSize; + + // Shift frame data after this one down + memmove(&_exFrames._data[startOff], &_exFrames._data[endOff], remainder); + + // Combined frame data is now frameSize smaller + _vars._exFramePos -= frameSize; + + // Adjust all frame pointers pointing into the shifted data + for (unsigned int i = 0; i < 3*kNumexobjects; ++i) { + frame = &_exFrames._frames[i]; + if (frame->ptr() >= startOff) + frame->setPtr(frame->ptr() - frameSize); + } +} + +void DreamWebEngine::deleteExText(uint8 textNum) { + uint16 offset = _exText.getOffset(textNum); + + uint16 startOff = offset; + uint16 textSize = strlen(_exText.getString(textNum)) + 1; + uint16 endOff = startOff + textSize; + uint16 remainder = kExtextlen - offset - textSize; + + // Shift text data after this one down + memmove(&_exText._text[startOff], &_exText._text[endOff], remainder); + + // Combined text data is now frameSize smaller + _vars._exTextPos -= textSize; + + // Adjust all text pointers pointing into the shifted data + for (unsigned int i = 0; i < kNumexobjects; ++i) { + uint16 t = _exText.getOffset(i); + if (t >= offset + textSize) + _exText.setOffset(i, t - textSize); + } +} + +void DreamWebEngine::deleteExObject(uint8 index) { + DynObject *obj = getExAd(index); + + memset(obj, 0xFF, sizeof(DynObject)); + + deleteExFrame(3*index); + deleteExFrame(3*index + 1); + + deleteExText(index); + + for (uint8 i = 0; i < kNumexobjects; ++i) { + DynObject *t = getExAd(i); + // Is this object contained in the one we've just deleted? + if (t->mapad[0] == 4 && t->mapad[1] == index) + deleteExObject(i); + } +} + +void DreamWebEngine::removeObFromInv() { + if (_command == 100) + return; // object doesn't exist + + assert(_objectType == kExObjectType); + + deleteExObject(_command); +} + +void DreamWebEngine::inToInv() { + if (!_pickUp) { + outOfInv(); + return; + } + + ObjectRef subject = findInvPos(); + + if (subject._index != 255) { + swapWithInv(); + return; + } + + subject._type = _objectType; + subject._index = _itemFrame; + + if (subject != _oldSubject || _commandType != 220) { + if (subject == _oldSubject) + _commandType = 220; + _oldSubject = subject; + commandWithOb(35, subject._type, subject._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; // notletgo2 + + delPointer(); + DynObject *object = getExAd(_itemFrame); + object->mapad[0] = 4; + object->mapad[1] = 255; + object->mapad[2] = _lastInvPos; + _pickUp = 0; + fillRyan(); + readMouse(); + showPointer(); + outOfInv(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::outOfInv() { + ObjectRef subject = findInvPos(); + + if (subject._index == 255) { + blank(); + return; + } + + if (_mouseButton == 2) { + reExFromInv(); + return; + } + + if (subject != _oldSubject || _commandType != 221) { + if (subject == _oldSubject) + _commandType = 221; + _oldSubject = subject; + commandWithOb(36, subject._type, subject._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + delPointer(); + _pickUp = 1; + subject = findInvPos(); + _objectType = subject._type; + _itemFrame = subject._index; + assert(subject._type == kExObjectType); + DynObject *object = getExAd(subject._index); + object->mapad[0] = 20; + object->mapad[1] = 255; + fillRyan(); + readMouse(); + showPointer(); + inToInv(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::purgeALocation(uint8 index) { + // index == al + for (uint8 i = 0; i < kNumexobjects; ++i) { + DynObject *t = getExAd(i); + if (t->currentLocation == index && t->mapad[0] == 0) { + deleteExObject(i); + } + } +} + +const uint8 *DreamWebEngine::getObTextStart() { + const uint8 *textBase = 0; + const uint8 *text; + uint16 textOff = 0; + if (_objectType == kFreeObjectType) { + text = (const uint8 *)_freeDesc.getString(_command); + } else if (_objectType == kSetObjectType1) { + textBase = (const uint8 *)_setDesc._text; + textOff = kNumSetTexts * 2; + text = (const uint8 *)_setDesc.getString(_command); + } else { + text = (const uint8 *)_exText.getString(_command); + } + + if (_objectType != kSetObjectType1) + return text; + + const uint8 *obname = text; + while (true) { + const uint8 *start = text; + findNextColon(&text); + + // Not an empty description string? + if (*text != 0 && *text != ':') + return start; + + // If the description string (of a SetObjectType1 object) is empty, + // look for an object with the same name. + // Example: Eden's garage door outside has two parts. The right part + // has no description of its own but uses that of the left part. + + bool found = false; + do { + text++; + uint8 c = *obname; + + // scan for matching first character + while (*text != c) { + text++; + + // arbitrary give-up counter + // FIXME: Make this more precise to avoid reading out of bounds + if (text - (textBase - textOff) >= 8000) { + warning("Object description for %d/%d not found", _objectType, _command); + return obname; + } + } + + // found matching first character, so match the rest + const uint8 *s1 = obname; + const uint8 *s2 = text; + do { + s1++; + s2++; + } while (*s1 != ':' && *s1 != 0 && *s1 == *s2); + + if (*s1 == ':' || *s1 == 0) + found = true; // (prefix) matched the entire object name + } while (!found); + + // We found an object with the same name. The next loop iteration + // will check if this one again has an empty description. + } +} + +void DreamWebEngine::dropObject() { + if (_commandType != 223) { + _commandType = 223; + if (!_pickUp) { + blank(); + return; + } + commandWithOb(37, _objectType, _itemFrame); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + if (isItWorn(getEitherAd())) { + wornError(); + return; + } + + if (_realLocation != 47) { + byte flag, flagEx, type, flagX, flagY; + checkOne(_ryanX + 12, _ryanY + 12, &flag, &flagEx, &type, &flagX, &flagY); + + if (flag >= 2) { + dropError(); + return; + } + } else { + dropError(); + return; + } + + if (_mapXSize == 64 && _mapYSize == 64) { + // Inside lift + dropError(); + return; + } + + if (compare(_itemFrame, kExObjectType, "GUNA") || compare(_itemFrame, kExObjectType, "SHLD")) { + cantDrop(); + return; + } + + _objectType = kExObjectType; + DynObject *object = getExAd(_itemFrame); + object->mapad[0] = 0; + object->mapad[1] = ((_ryanX + 4) >> 4) + _mapX; + object->mapad[2] = (_ryanX + 4) & 0xF; + object->mapad[3] = ((_ryanY + 8) >> 4) + _mapY; + object->mapad[4] = (_ryanY + 8) & 0xF; + _pickUp = 0; + object->currentLocation = _realLocation; +} + +bool DreamWebEngine::checkObjectSize() { + byte containerSize = getOpenedSlotSize(); + DynObject *object = getEitherAd(); + // If there is no size defined for the object in the editor, set its size + // to 6. This could be a bad idea, according to the original source. + byte objectSize = (object->objectSize != 255) ? object->objectSize : 6; + + if (containerSize >= 100) { + // Special type of container: only objects of the same special type fit. + if (containerSize == objectSize) + return true; + + errorMessage3(); + return false; + } + + if (objectSize >= 100) { + // Special type of object, but a regular container. + // Subtract 100 from the size to get its regular size. + objectSize -= 100; + } + + if (containerSize >= objectSize) + return true; + + errorMessage2(); + return false; +} + +void DreamWebEngine::selectOpenOb() { + uint8 slotSize, slotCount; + getAnyAd(&slotSize, &slotCount); + if (slotCount == 255) { + // Can't open the object + blank(); + return; + } + + if (_commandType != 224) { + _commandType = 224; + commandWithOb(38, _objectType, _command); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + _openedOb = _command; + _openedType = _objectType; + createPanel(); + showPanel(); + showMan(); + examIcon(); + showExit(); + openInv(); + openOb(); + underTextLine(); + readMouse(); + showPointer(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::reExFromInv() { + ObjectRef objectId = findInvPos(); + _commandType = objectId._type; + _command = objectId._index; + _examAgain = 1; + _pointerMode = 0; +} + +void DreamWebEngine::swapWithInv() { + ObjectRef subject; + subject._type = _objectType; + subject._index = _itemFrame; + if (subject != _oldSubject || _commandType != 243) { + if (subject == _oldSubject) + _commandType = 243; + _oldSubject = subject; + commandWithOb(34, subject._type, subject._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + byte prevType = _objectType; + byte prevFrame = _itemFrame; + ObjectRef objectId = findInvPos(); + _itemFrame = objectId._index; + _objectType = objectId._type; + DynObject *object = getEitherAd(); + object->mapad[0] = 20; + object->mapad[1] = 255; + byte prevType2 = _objectType; + byte prevFrame2 = _itemFrame; + _objectType = prevType; + _itemFrame = prevFrame; + delPointer(); + object = getEitherAd(); + object->mapad[0] = 4; + object->mapad[1] = 255; + object->mapad[2] = _lastInvPos; + _objectType = prevType2; + _itemFrame = prevFrame2; + fillRyan(); + readMouse(); + showPointer(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::useOpened() { + if (_openedOb == 255) + return; // cannot use opened object + + if (!_pickUp) { + outOfOpen(); + return; + } + + ObjectRef objectId = findOpenPos(); + + if (objectId._index != 255) { + swapWithOpen(); + return; + } + + if (_pickUp != 1) { + blank(); + return; + } + + objectId._type = _objectType; + objectId._index = _itemFrame; + if (objectId != _oldSubject || _commandType != 227) { + if (objectId == _oldSubject) + _commandType = 227; + _oldSubject = objectId; + commandWithOb(35, objectId._type, objectId._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + if (isItWorn(getEitherAd())) { + wornError(); + return; + } + + delPointer(); + + if (_itemFrame == _openedOb && + _objectType == _openedType) { + errorMessage1(); + return; + } + + if (!checkObjectSize()) + return; + + _pickUp = 0; + DynObject *object = getEitherAd(); + object->mapad[0] = _openedType; + object->mapad[1] = _openedOb; + object->mapad[2] = _lastInvPos; + object->mapad[3] = _realLocation; + fillOpen(); + underTextLine(); + readMouse(); + useOpened(); + showPointer(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::outOfOpen() { + if (_openedOb == 255) + return; // cannot use opened object + + ObjectRef objectId = findOpenPos(); + + if (objectId._index == 255) { + blank(); + return; + } + + if (objectId != _oldSubject || _commandType != 228) { + if (objectId == _oldSubject) + _commandType = 228; + _oldSubject = objectId; + commandWithOb(36, objectId._type, objectId._index); + } + + if (_mouseButton == _oldButton) + return; // notletgo4 + + if (_mouseButton != 1) { + if (_mouseButton == 2) + reExFromOpen(); + return; + } + + delPointer(); + _pickUp = 1; + objectId = findOpenPos(); + _objectType = objectId._type; + _itemFrame = objectId._index; + + if (_objectType != kExObjectType) { + assert(objectId._type == kFreeObjectType); + _itemFrame = transferToEx(objectId._index); + _objectType = kExObjectType; + } + + DynObject *object = getEitherAd(); + object->mapad[0] = 20; + object->mapad[1] = 255; + + fillOpen(); + underTextLine(); + readMouse(); + useOpened(); + showPointer(); + workToScreen(); + delPointer(); +} + +void DreamWebEngine::swapWithOpen() { + ObjectRef subject; + subject._type = _objectType; + subject._index = _itemFrame; + if (subject != _oldSubject || _commandType != 242) { + if (subject == _oldSubject) + _commandType = 242; + _oldSubject = subject; + commandWithOb(34, subject._type, subject._index); + } + + if (_mouseButton == _oldButton || !(_mouseButton & 1)) + return; + + if (isItWorn(getEitherAd())) { + wornError(); + return; + } + + delPointer(); + + if (_itemFrame == _openedOb && + _objectType == _openedType) { + errorMessage1(); + return; + } + + if (!checkObjectSize()) + return; + + byte prevType = _objectType; + byte prevFrame = _itemFrame; + ObjectRef objectId = findOpenPos(); + _objectType = objectId._type; + _itemFrame = objectId._index; + + if (_objectType != kExObjectType) { + assert(objectId._type == kFreeObjectType); + _itemFrame = transferToEx(objectId._index); + _objectType = kExObjectType; + } + + DynObject *object = getEitherAd(); + object->mapad[0] = 20; + object->mapad[1] = 255; + + byte prevType2 = _objectType; + byte prevFrame2 = _itemFrame; + _objectType = prevType; + _itemFrame = prevFrame; + object = getEitherAd(); + object->mapad[0] = _openedType; + object->mapad[1] = _openedOb; + object->mapad[2] = _lastInvPos; + object->mapad[3] = _realLocation; + _objectType = prevType2; + _itemFrame = prevFrame2; + fillOpen(); + fillRyan(); + underTextLine(); + readMouse(); + useOpened(); + showPointer(); + workToScreen(); + delPointer(); +} + +ObjectRef DreamWebEngine::findOpenPos() { + uint8 pos = (_mouseX - kInventx) / kItempicsize; + _lastInvPos = pos; + + return _openInvList[pos]; +} + +byte DreamWebEngine::transferToEx(uint8 from) { + emergencyPurge(); + + byte pos = getExPos(); + DynObject *exObject = getExAd(pos); + + DynObject *freeObject = getFreeAd(from); + + memcpy(exObject, freeObject, sizeof(DynObject)); + + exObject->currentLocation = _realLocation; + exObject->initialLocation = _realLocation; + exObject->index = from; + exObject->mapad[0] = 4; + exObject->mapad[1] = 255; + exObject->mapad[2] = _lastInvPos; + + transferFrame(from, pos, 0); + transferFrame(from, pos, 1); + transferText(from, pos); + + freeObject->mapad[0] = 254; + + pickupConts(from, pos); + + return pos; +} + +void DreamWebEngine::fillOpen() { + delTextLine(); + uint8 size = getOpenedSlotCount(); + if (size > 4) + size = 4; + findAllOpen(); + for (uint8 i = 0; i < size; ++i) { + uint8 index = _openInvList[i]._index; + uint8 type = _openInvList[i]._type; + obToInv(index, type, kInventx + i * kItempicsize, kInventy + 96); + } + underTextLine(); +} + +void DreamWebEngine::findAllOpen() { + memset(_openInvList, 0xFF, 32); + + for (uint8 i = 0; i < kNumexobjects; ++i) { + const DynObject *obj = getExAd(i); + if (obj->mapad[1] != _openedOb) + continue; + if (obj->mapad[0] != _openedType) + continue; + if (_openedType != kExObjectType && obj->mapad[3] != _realLocation) + continue; + uint8 slot = obj->mapad[2]; + assert(slot < 16); + _openInvList[slot]._index = i; + _openInvList[slot]._type = kExObjectType; + } + + for (uint8 i = 0; i < 80; ++i) { + const DynObject *obj = getFreeAd(i); + if (obj->mapad[1] != _openedOb) + continue; + if (obj->mapad[0] != _openedType) + continue; + uint8 slot = obj->mapad[2]; + _openInvList[slot]._index = i; + _openInvList[slot]._type = kFreeObjectType; + } +} + +void DreamWebEngine::pickupConts(uint8 from, uint8 containerEx) { + const DynObject *obj = getFreeAd(from); + + if (obj->slotCount == 255) + return; // not openable + + for (uint8 index = 0; index < 80; ++index) { + DynObject *freeObj = getFreeAd(index); + + if (freeObj->mapad[0] != kFreeObjectType) + continue; + if (freeObj->mapad[1] != from) + continue; + + uint8 pos = getExPos(); + DynObject *exObj = getExAd(pos); + + memcpy(exObj, freeObj, sizeof(DynObject)); + exObj->currentLocation = _realLocation; + exObj->initialLocation = _realLocation; + exObj->index = index; + exObj->mapad[0] = 4; // kExObjectType? + exObj->mapad[1] = containerEx; + + transferFrame(index, pos, 0); + transferFrame(index, pos, 1); + transferText(index, pos); + + freeObj->mapad[0] = 0xFF; + } +} + +} // End of namespace DreamWeb |