/** * Return the position of an object. * Returns X, Y and direction in angles */ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { int idx = getObjectIndex(object); assert(idx >= 0); ObjectData &od = _objs[idx]; int state; const byte *ptr; const ImageHeader *imhd; if (_game.version >= 6) { state = getState(object) - 1; if (state < 0) state = 0; ptr = getOBIMFromObjectData(od); if (!ptr) { // FIXME: We used to assert here, but it seems that in the nexus // in The Dig, this can happen, at least with old savegames, and // it's safe to continue... debug(0, "getObjectXYPos: Can't find object %d", object); return; } imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr); assert(imhd); if (_game.version == 8) { switch (FROM_LE_32(imhd->v8.version)) { case 800: x = od.x_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x44); y = od.y_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x48); break; case 801: x = od.x_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].x); y = od.y_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].y); break; default: error("Unsupported image header version %d", FROM_LE_32(imhd->v8.version)); } } else if (_game.version == 7) { x = od.x_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].x); y = od.y_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].y); } else { x = od.x_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].x); y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y); } } else if (_game.version <= 2) { x = od.walk_x; y = od.walk_y; // Adjust x, y when no actor direction is set, but only perform this // adjustment for V0 games (e.g. MM C64), otherwise certain scenes in // newer games are affected as well (e.g. the interior of the Shuttle // Bus scene in Zak V2, where no actor is present). Refer to bug #3526089. if (!od.actordir && _game.version == 0) { x = od.x_pos + od.width / 2; y = od.y_pos + od.height / 2; } x = x >> V12_X_SHIFT; y = y >> V12_Y_SHIFT; } else {
MObject3d * MScene::getObjectByName(const char * name) { unsigned int id; if(getObjectIndex(name, &id)){ return m_objects[id]; } return NULL; }
void View::removeObject(const QString &name, ObjectType obj_type) { try { removeObject(getObjectIndex(name, obj_type), obj_type); } catch(Exception &e) { throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
void View::removeObject(BaseObject *obj) { try { removeObject(getObjectIndex(obj), obj->getObjectType()); } catch(Exception &e) { throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
void objlink::makeNode(HWND hwnd, const char *heading, int level, int index) { if (index == -1) index = getObjectIndex(obj); char dataString[20]; sprintf(dataString, "%s %i", heading, index+1); HTREEITEM item_parent = parent ? parent->treeitem : 0; HTREEITEM item_prev = prev ? prev->treeitem : 0; treeitem = AddItemToTreeAfter(hwnd, dataString, level, obj, item_parent, item_prev); }
void View::addObject(BaseObject *obj, int obj_idx) { if(!obj) throw Exception(ERR_ASG_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__); else { try { vector<TableObject *> *obj_list = getObjectList(obj->getObjectType()); TableObject *tab_obj=dynamic_cast<TableObject *>(obj); //Raises an error if already exists a object with the same name and type if(getObjectIndex(obj->getName(), tab_obj->getObjectType()) >= 0) { throw Exception(QString(Exception::getErrorMessage(ERR_ASG_DUPLIC_OBJECT)) .arg(obj->getName(true)) .arg(obj->getTypeName()) .arg(this->getName(true)) .arg(this->getTypeName()), ERR_ASG_DUPLIC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__); } //Validates the object definition tab_obj->setParentTable(this); tab_obj->getCodeDefinition(SchemaParser::SQL_DEFINITION); //Make a additional validation if the object is a trigger if(tab_obj->getObjectType()==OBJ_TRIGGER) dynamic_cast<Trigger *>(tab_obj)->validateTrigger(); //Inserts the object at specified position if(obj_idx < 0 || obj_idx >= static_cast<int>(obj_list->size())) obj_list->push_back(tab_obj); else obj_list->insert(obj_list->begin() + obj_idx, tab_obj); setCodeInvalidated(true); } catch(Exception &e) { if(e.getErrorType()==ERR_UNDEF_ATTRIB_VALUE) throw Exception(Exception::getErrorMessage(ERR_ASG_OBJ_INV_DEFINITION) .arg(obj->getName()) .arg(obj->getTypeName()), ERR_ASG_OBJ_INV_DEFINITION,__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); else throw Exception(e.getErrorMessage(),e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } } }
TableObject *View::getObject(const QString &name, ObjectType obj_type) { try { int idx=getObjectIndex(name, obj_type); if(idx >= 0) return(getObject(idx, obj_type)); else return(nullptr); } catch(Exception &e) { throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
QString Table::getInitialDataCommands(void) { QStringList buffer=initial_data.split(DATA_LINE_BREAK); if(!buffer.isEmpty() && !buffer.at(0).isEmpty()) { QStringList col_names, col_values, commands, selected_cols; int curr_col=0; QList<int> ignored_cols; col_names=(buffer.at(0)).split(DATA_SEPARATOR); col_names.removeDuplicates(); buffer.removeFirst(); //Separating valid columns (selected) from the invalids (ignored) for(QString col_name : col_names) { if(getObjectIndex(col_name, OBJ_COLUMN) >= 0) selected_cols.append(col_name); else ignored_cols.append(curr_col); curr_col++; } for(QString buf_row : buffer) { curr_col=0; //Filtering the invalid columns' values for(QString value : buf_row.split(DATA_SEPARATOR)) { if(ignored_cols.contains(curr_col)) continue; col_values.append(value); } commands.append(createInsertCommand(selected_cols, col_values)); col_values.clear(); } return(commands.join('\n')); } return(QString()); }
/** * Return the position of an object. * Returns X, Y and direction in angles */ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { int idx = (_v0ObjectIndex) ? object : getObjectIndex(object); assert(idx >= 0); ObjectData &od = _objs[idx]; int state; const byte *ptr; const ImageHeader *imhd; if (_game.version >= 6) { state = getState(object) - 1; if (state < 0) state = 0; ptr = getOBIMFromObjectData(od); if (!ptr) { // FIXME: We used to assert here, but it seems that in the nexus // in The Dig, this can happen, at least with old savegames, and // it's safe to continue... debug(0, "getObjectXYPos: Can't find object %d", object); return; } imhd = (const ImageHeader *)findResourceData(MKTAG('I','M','H','D'), ptr); assert(imhd); if (_game.version == 8) { switch (FROM_LE_32(imhd->v8.version)) { case 800: x = od.x_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x44); y = od.y_pos + (int32)READ_LE_UINT32((const byte *)imhd + 8 * state + 0x48); break; case 801: x = od.x_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].x); y = od.y_pos + (int32)READ_LE_UINT32(&imhd->v8.hotspot[state].y); break; default: error("Unsupported image header version %d", FROM_LE_32(imhd->v8.version)); } } else if (_game.version == 7) { x = od.x_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].x); y = od.y_pos + (int16)READ_LE_UINT16(&imhd->v7.hotspot[state].y); } else { x = od.x_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].x); y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y); } } else if (_game.version <= 2) { x = od.walk_x >> V12_X_SHIFT; y = od.walk_y >> V12_Y_SHIFT; } else {
void Table::removeObject(BaseObject *obj) { try { if(obj) { TableObject *tab_obj=dynamic_cast<TableObject *>(obj); if(tab_obj) removeObject(getObjectIndex(tab_obj), obj->getObjectType()); else removeObject(obj->getName(true), OBJ_TABLE); } } catch(Exception &e) { throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
void Table::moveObjectToIndex(TableObject *tab_obj, unsigned idx) { unsigned curr_idx; try { if(!tab_obj) throw Exception(ERR_OPR_NOT_ALOC_OBJECT,__PRETTY_FUNCTION__,__FILE__,__LINE__); curr_idx=getObjectIndex(tab_obj); if(curr_idx!=idx) swapObjectsIndexes(tab_obj->getObjectType(), curr_idx, idx); } catch(Exception &e) { throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); } }
void ScummEngine_v4::o4_pickupObject() { int obj = getVarOrDirectWord(PARAM_1); if (obj < 1) { error("pickupObjectOld received invalid index %d (script %d)", obj, vm.slot[_currentScript].number); } if (getObjectIndex(obj) == -1) return; if (whereIsObject(obj) == WIO_INVENTORY) // Don't take an object twice return; // debug(0, "adding %d from %d to inventoryOld", obj, _currentRoom); addObjectToInventory(obj, _roomResource); markObjectRectAsDirty(obj); putOwner(obj, VAR(VAR_EGO)); putClass(obj, kObjectClassUntouchable, 1); putState(obj, 1); clearDrawObjectQueue(); runInventoryScript(1); }
void ScummEngine_v70he::o70_resourceRoutines() { int objidx, resid; byte subOp = fetchScriptByte(); switch (subOp) { case 100: // SO_LOAD_SCRIPT resid = pop(); ensureResourceLoaded(rtScript, resid); break; case 101: // SO_LOAD_SOUND resid = pop(); ensureResourceLoaded(rtSound, resid); break; case 102: // SO_LOAD_COSTUME resid = pop(); ensureResourceLoaded(rtCostume, resid); break; case 103: // SO_LOAD_ROOM resid = pop(); ensureResourceLoaded(rtRoomImage, resid); ensureResourceLoaded(rtRoom, resid); break; case 104: // SO_NUKE_SCRIPT resid = pop(); _res->nukeResource(rtScript, resid); break; case 105: // SO_NUKE_SOUND resid = pop(); _res->nukeResource(rtSound, resid); break; case 106: // SO_NUKE_COSTUME resid = pop(); _res->nukeResource(rtCostume, resid); break; case 107: // SO_NUKE_ROOM resid = pop(); _res->nukeResource(rtRoom, resid); _res->nukeResource(rtRoomImage, resid); break; case 108: // SO_LOCK_SCRIPT resid = pop(); if (resid >= _numGlobalScripts) break; _res->lock(rtScript, resid); break; case 109: // SO_LOCK_SOUND resid = pop(); _res->lock(rtSound, resid); break; case 110: // SO_LOCK_COSTUME resid = pop(); _res->lock(rtCostume, resid); break; case 111: // SO_LOCK_ROOM resid = pop(); if (_game.heversion <= 71 && resid > 0x7F) resid = _resourceMapper[resid & 0x7F]; _res->lock(rtRoom, resid); _res->lock(rtRoomImage, resid); break; case 112: // SO_UNLOCK_SCRIPT resid = pop(); if (resid >= _numGlobalScripts) break; _res->unlock(rtScript, resid); break; case 113: // SO_UNLOCK_SOUND resid = pop(); _res->unlock(rtSound, resid); break; case 114: // SO_UNLOCK_COSTUME resid = pop(); _res->unlock(rtCostume, resid); break; case 115: // SO_UNLOCK_ROOM resid = pop(); if (_game.heversion <= 71 && resid > 0x7F) resid = _resourceMapper[resid & 0x7F]; _res->unlock(rtRoom, resid); _res->unlock(rtRoomImage, resid); break; case 116: // TODO: Clear Heap break; case 117: // SO_LOAD_CHARSET resid = pop(); loadCharset(resid); break; case 118: // SO_NUKE_CHARSET resid = pop(); nukeCharset(resid); break; case 119: // SO_LOAD_OBJECT { int obj = pop(); int room = getObjectRoom(obj); loadFlObject(obj, room); break; } case 120: resid = pop(); if (resid >= _numGlobalScripts) break; //queueLoadResource(rtScript, resid); break; case 121: resid = pop(); //queueLoadResource(rtSound, resid); break; case 122: resid = pop(); //queueLoadResource(rtCostume, resid); break; case 123: resid = pop(); //queueLoadResource(rtRoomImage, resid); break; case 159: resid = pop(); _res->unlock(rtImage, resid); break; case 192: resid = pop(); _res->nukeResource(rtImage, resid); break; case 201: resid = pop(); ensureResourceLoaded(rtImage, resid); break; case 202: resid = pop(); _res->lock(rtImage, resid); break; case 203: resid = pop(); //queueLoadResource(rtImage, resid); break; case 233: resid = pop(); objidx = getObjectIndex(resid); if (objidx == -1) break; _res->lock(rtFlObject, _objs[objidx].fl_object_index); break; case 235: resid = pop(); objidx = getObjectIndex(resid); if (objidx == -1) break; _res->unlock(rtFlObject, _objs[objidx].fl_object_index); break; case 239: // Used in airport break; default: error("o70_resourceRoutines: default case %d", subOp); } }