bool Pony::tryWearItem(quint8 invSlot) { //win.logMessage("Invslot is "+QString().setNum(invSlot)); uint32_t id = -1; uint32_t itemSlots; for (int i=0; i<inv.size(); i++) { if (inv[i].index == invSlot) { id = inv[i].id; itemSlots = win.wearablePositionsMap[id]; if (wornSlots & itemSlots) { win.logMessage("Can't wear item: slots occupied", udpTag); return false; } sendDeleteItemRPC(owner,inv[i].index,1); if (inv[i].amount>1) inv[i].amount--; else inv.removeAt(i); break; } } if (id == (uint32_t)-1) { // wtf? win.logMessage("Index not found", sysTag); return false; } wornSlots |= itemSlots; WearableItem item; item.id = id; item.index = wearablePositionsToSlot(itemSlots); //win.logMessage("Wearing at slot "+QString().setNum(item.index)); worn << item; sendWearItemRPC(owner, item); Scene* scene = findScene(sceneName); if (scene->name.isEmpty()) win.logMessage("UDP: Can't find the scene for wearItem RPC, aborting", udpTag); else { for (Player* dest : scene->players) if (dest->pony.netviewId != netviewId) sendWearItemRPC(this, dest, item); } return true; }
Quest::Quest(QString path, Player *Owner) { QFile file(path); if (!file.open(QFile::ReadOnly)) { app.logError(QObject::tr("Error reading quest DB")); app.stopGameServer(); throw std::exception(); } QList<QString> lines = QString(file.readAll().replace('\r',"")).split('\n'); owner = Owner; commands = new QList<QList<QString> >; name = new QString(); descr = new QString(); npc = new Pony(nullptr); // A NPC doesn't have an owner player ! npc->id = 0; npc->netviewId = 0; id = 0; state = 0; eip = 0; // Parse the metadata, add everything else as quest commands for (int i=0; i<lines.size(); i++) { QList<QString> line = lines[i].split(" ", QString::SkipEmptyParts); if (!line.size() || lines[i][0]=='#') continue; if (line[0] == "name") if (line.size()>=2) npc->name = lines[i].mid(line[0].size()+1); else throw QString(QObject::tr("Quest::Quest: Error reading name, quest %1").arg(path)); else if (line[0] == "scene") if (line.size()>=2) npc->sceneName = lines[i].mid(line[0].size()+1).toLower(); else throw QString(QObject::tr("Quest::Quest: Error reading scene, quest %1").arg(path)); else if (line[0] == "ponyData") { if (line.size()==2) { QByteArray ponyData = QByteArray::fromBase64(line[1].toLatin1()); // Read the ponyData unsigned strlen; unsigned lensize=0; { unsigned char num3; int num=0, num2=0; do { num3 = ponyData[lensize]; lensize++; num |= (num3 & 0x7f) << num2; num2 += 7; } while ((num3 & 0x80) != 0); strlen = (uint) num; } int nameSize = strlen + lensize; int ponyDataSize = ponyData.size() - nameSize; if (ponyDataSize == 43) { app.logMessage(QString("Quest::Quest: PonyData of quest %1 is in old format, converting") .arg(path)); ponyData += uint32ToData(0); // Member ID ponyData.insert(nameSize+17+3,ponyData.mid(nameSize+17,3)); // Hair color 2 (copy of color 1) } npc->ponyData = ponyData; } else throw QString(QObject::tr("Quest::Quest: Error reading ponyData, quest %1").arg(path)); } else if (line[0] == "pos") if (line.size()==4) { bool ok1, ok2, ok3; npc->pos = UVector(line[1].toFloat(&ok1), line[2].toFloat(&ok2), line[3].toFloat(&ok3)); if (!(ok1 && ok2 && ok3)) throw QString(QObject::tr("Quest::Quest: Error reading pos, quest %1").arg(path)); } else throw QString(QObject::tr("Quest::Quest: Error reading pos, quest %1").arg(path)); else if (line[0] == "rot") if (line.size()==5) { bool ok1, ok2, ok3, ok4; npc->rot = UQuaternion(line[1].toFloat(&ok1), line[2].toFloat(&ok2), line[3].toFloat(&ok3), line[4].toFloat(&ok4)); if (!(ok1 && ok2 && ok3 && ok4)) throw QString(QObject::tr("Quest::Quest: Error reading rot, quest %1").arg(path)); } else throw QString(QObject::tr("Quest::Quest: Error reading rot, quest %1").arg(path)); else if (line[0] == "wear") { for (int i=1; i<line.size(); i++) { bool ok; int itemId = line[i].toInt(&ok); if (!ok) throw QString(QObject::tr("Quest::Quest: Error reading wear, quest %1").arg(path)); WearableItem item; item.id = itemId; item.index = wearablePositionsToSlot(wearablePositionsMap[itemId]); npc->worn << item; } } else if (line[0] == "shop") { for (int i=1; i<line.size(); i++) { bool ok; int itemId = line[i].toInt(&ok); if (!ok) throw QString(QObject::tr("Quest::Quest: Error reading shop, quest %1").arg(path)); InventoryItem item; item.id = itemId; item.index = i-1; item.amount = (quint32)-1; npc->inv << item; } } else if (line[0] == "questId") if (line.size()==2) { id = line[1].toInt(); SceneEntity::lastIdMutex.lock(); npc->id = 0; npc->netviewId = id; SceneEntity::lastIdMutex.unlock(); } else throw QString(QObject::tr("Quest::Quest: Error reading questId, quest %1").arg(path)); else if (line[0] == "questName") if (line.size()>=2) *name = lines[i].mid(line[0].size()+1); else throw QString(QObject::tr("Quest::Quest: Error reading questName, quest %1").arg(path)); else if (line[0] == "questDescr") if (line.size()>=2) *descr = lines[i].mid(line[0].size()+1); else throw QString(QObject::tr("Quest::Quest: Error reading questDescr, quest %1").arg(path)); else commands->append(line); } }
Quest::Quest(QString path, Player *Owner) { QFile file(path); if (!file.open(QFile::ReadOnly)) { win.logMessage("Error reading quest DB.", sysTag); win.stopServer(); throw std::exception(); } QList<QString> lines = QString(file.readAll().replace('\r',"")).split('\n'); owner = Owner; commands = new QList<QList<QString> >; name = new QString(); descr = new QString(); npc = new Pony(nullptr); // A NPC doesn't have an owner player ! npc->id = 0; npc->netviewId = 0; id = 0; state = 0; eip = 0; try { // Parse the metadata, add everything else as quest commands for (int i=0; i<lines.size(); i++) { QList<QString> line = lines[i].split(" ", QString::SkipEmptyParts); if (!line.size() || lines[i][0]=='#') continue; if (line[0] == "name") if (line.size()>=2) npc->name = lines[i].mid(line[0].size()+1); else throw QString("Quest::Quest: Error reading name, quest "+path); else if (line[0] == "scene") if (line.size()>=2) npc->sceneName = lines[i].mid(line[0].size()+1).toLower(); else throw QString("Quest::Quest: Error reading scene, quest "+path); else if (line[0] == "ponyData") if (line.size()==2) npc->ponyData = QByteArray::fromBase64(line[1].toLatin1()); else throw QString("Quest::Quest: Error reading ponyData, quest "+path); else if (line[0] == "pos") if (line.size()==4) { bool ok1, ok2, ok3; npc->pos = UVector(line[1].toFloat(&ok1), line[2].toFloat(&ok2), line[3].toFloat(&ok3)); if (!(ok1 && ok2 && ok3)) throw QString("Quest::Quest: Error reading pos, quest "+path); } else throw QString("Quest::Quest: Error reading pos, quest "+path); else if (line[0] == "rot") if (line.size()==5) { bool ok1, ok2, ok3, ok4; npc->rot = UQuaternion(line[1].toFloat(&ok1), line[2].toFloat(&ok2), line[3].toFloat(&ok3), line[4].toFloat(&ok4)); if (!(ok1 && ok2 && ok3 && ok4)) throw QString("Quest::Quest: Error reading rot, quest "+path); } else throw QString("Quest::Quest: Error reading rot, quest "+path); else if (line[0] == "wear") { for (int i=1; i<line.size(); i++) { bool ok; int itemId = line[i].toInt(&ok); if (!ok) throw QString("Quest::Quest: Error reading wear, quest "+path); WearableItem item; item.id = itemId; item.index = wearablePositionsToSlot(win.wearablePositionsMap[itemId]); npc->worn << item; } } else if (line[0] == "questId") if (line.size()==2) { id = line[1].toInt(); win.lastIdMutex.lock(); npc->id = 0; npc->netviewId = id; win.lastIdMutex.unlock(); } else throw QString("Quest::Quest: Error reading questId, quest "+path); else if (line[0] == "questName") if (line.size()>=2) *name = lines[i].mid(line[0].size()+1); else throw QString("Quest::Quest: Error reading questName, quest "+path); else if (line[0] == "questDescr") if (line.size()>=2) *descr = lines[i].mid(line[0].size()+1); else throw QString("Quest::Quest: Error reading questDescr, quest "+path); else commands->append(line); } } catch (QString& error) { win.logMessage(error, sysTag); win.stopServer(); } }