📄 scourge.cpp
字号:
double win_y = (double)sdlHandler->getScreen()->h - y - 1; double win_z = 0.0; double projection[16]; double modelview[16]; GLint viewport[4]; glGetDoublev(GL_PROJECTION_MATRIX, projection); glGetDoublev(GL_MODELVIEW_MATRIX, modelview); glGetIntegerv(GL_VIEWPORT, viewport); int res = gluUnProject(win_x, win_y, win_z, modelview, projection, viewport, &obj_x, &obj_y, &obj_z); if(res) { /*char buff[255]; sprintf(buff, "avant: x %2.2f, y %2.2f, z %2.2f, getX %d, getY %d", obj_x, obj_y, obj_z, map->getX(), map->getY()); map->addDescription(buff, 1.0f, 1.0f, 0.5f); sprintf(buff, "avant op : yrot = %2.2f, sin(yrot) = %2.2f, obj_x * sin(yrot) = %2.2f", map->getYRot(), sin(map->getYRot()), obj_x * sin(map->getYRot())); map->addDescription(buff, 1.0f, 1.0f, 0.5f); float radians; radians = map->getYRot() * 3.1415926 / 180.0f; obj_x += (obj_x * sin(radians)); obj_y += (obj_y * sin(radians)); sprintf(buff, "avant 2: x %2.2f, y %2.2f, z %2.2f", obj_x, obj_y, obj_z); map->addDescription(buff, 1.0f, 1.0f, 0.5f);*/ *mapx = map->getX() + (Uint16)(((obj_x) * GLShape::DIV)) - 1; *mapy = map->getY() + (Uint16)(((obj_y) * GLShape::DIV)) + 2; //*mapz = (Uint16)0; //*mapz = (Uint16)(obj_z * GLShape::DIV); map->debugX = *mapx; map->debugY = *mapy; map->debugZ = 0; //map->debgTextMouse= true; //map->debugZ = obj_z; } else { //*mapx = *mapy = *mapz = MAP_WIDTH + 1; *mapx = *mapy = MAP_WIDTH + 1; } glPopMatrix();}void Scourge::getMapXYZAtScreenXY(Uint16 x, Uint16 y, Uint16 *mapx, Uint16 *mapy, Uint16 *mapz) { // only do this if the mouse has moved some (optimization) if(abs(lastX - x) < POSITION_SAMPLE_DELTA && abs(lastY - y) < POSITION_SAMPLE_DELTA) { *mapx = lastMapX; *mapy = lastMapY; *mapz = lastMapZ; return; } GLuint buffer[512]; GLint hits, viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); glSelectBuffer(512, buffer); glRenderMode(GL_SELECT); glInitNames(); glPushName(0); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPickMatrix(x, viewport[3]-y, 1, 1, viewport); sdlHandler->setOrthoView(); glMatrixMode(GL_MODELVIEW); map->selectMode = true; map->draw(); map->selectMode = false; glFlush(); hits = glRenderMode(GL_RENDER); //cerr << "hits=" << hits << endl; if (hits > 0) { // If There Were More Than 0 Hits int choose = buffer[4]; // Make Our Selection The First Object int depth = buffer[1]; // Store How Far Away It Is for (int loop = 0; loop < hits; loop++) { // Loop Through All The Detected Hits // fprintf(stderr, "\tloop=%d 0=%u 1=%u 2=%u 3=%u 4=%u \n", loop, // buffer[loop*5+0], buffer[loop*5+1], buffer[loop*5+2], // buffer[loop*5+3], buffer[loop*5+4]); if (buffer[loop*5+4] > 0) { decodeName(buffer[loop*5+4], mapx, mapy, mapz); } // If This Object Is Closer To Us Than The One We Have Selected if (buffer[loop*5+1] < GLuint(depth)) { choose = buffer[loop*5+4]; // Select The Closer Object depth = buffer[loop*5+1]; // Store How Far Away It Is } } //cerr << "choose=" << choose << endl; decodeName(choose, mapx, mapy, mapz); } else { *mapx = *mapy = MAP_WIDTH + 1; } // Restore the projection matrix glMatrixMode(GL_PROJECTION); glPopMatrix(); // Go back to modelview for normal rendering glMatrixMode(GL_MODELVIEW); lastMapX = *mapx; lastMapY = *mapy; lastMapZ = *mapz; lastX = x; lastY = y;}void Scourge::decodeName(int name, Uint16* mapx, Uint16* mapy, Uint16* mapz) { char *s; if(name > 0) { // decode the encoded map coordinates *mapz = name / (MAP_WIDTH * MAP_DEPTH); if(*mapz > 0) name %= (MAP_WIDTH * MAP_DEPTH); *mapx = name % MAP_WIDTH; *mapy = name / MAP_WIDTH; Location *pos = map->getPosition(*mapx, *mapy, 0); if(pos) { if(pos->shape) s = pos->shape->getName(); else if(pos->item && pos->item->getShape()) { s = pos->item->getShape()->getName(); } } else s = NULL; // fprintf(stderr, "\tmap coordinates: pos null=%s shape null=%s item null=%s %u,%u,%u name=%s\n", // (pos ? "no" : "yes"), (pos && pos->shape ? "no" : "yes"), (pos && pos->item ? "no" : "yes"), *mapx, *mapy, *mapz, (s ? s : "NULL")); } else { *mapx = MAP_WIDTH + 1; *mapy = 0; *mapz = 0; // fprintf(stderr, "\t---\n"); }}void Scourge::startItemDragFromGui(Item *item) { movingX = -1; movingY = -1; movingZ = -1; movingItem = item;}bool Scourge::startItemDrag(int x, int y, int z) { if(movingItem) return false; Location *pos = map->getPosition(x, y, z); if(pos) { if(getItem(pos)) { dragStartTime = SDL_GetTicks(); return true; } } return false;}void Scourge::endItemDrag() { // item move is over movingItem = NULL; movingX = movingY = movingZ = MAP_WIDTH + 1; }bool Scourge::useItem() { for(int x = party->getPlayer()->getX() - 2; x < party->getPlayer()->getX() + party->getPlayer()->getShape()->getWidth() + 2; x++) { for(int y = party->getPlayer()->getY() + 2; y > party->getPlayer()->getY() - party->getPlayer()->getShape()->getDepth() - 2; y--) { if(useItem(x, y, 0)) return true; } } return false;}bool Scourge::useItem(int x, int y, int z) { if(movingItem) { // a quick click opens a container GLint delta = SDL_GetTicks() - dragStartTime; if(delta < ACTION_CLICK_TIME && movingItem->getRpgItem()->getType() == RpgItem::CONTAINER) { openContainerGui(movingItem); } dropItem(map->getSelX(), map->getSelY()); return true; } Location *pos = map->getPosition(x, y, z); if(pos) { Shape *shape = (pos->item ? pos->item->getShape() : pos->shape); if(map->isWallBetweenShapes(party->getPlayer()->getX(), party->getPlayer()->getY(), party->getPlayer()->getZ(), party->getPlayer()->getShape(), x, y, z, shape)) { map->addDescription(Constants::getMessage(Constants::ITEM_OUT_OF_REACH)); return true; } else { // make sure the selected action can target a creature Creature *c = getTargetSelectionFor(); if(c && pos->item) { char msg[80]; if(c->getAction() == Constants::ACTION_CAST_SPELL && c->getActionSpell() && c->getActionSpell()->isItemTargetAllowed()) { // assign this creature c->setTargetItem(x, y, z, pos->item); sprintf(msg, "%s targeted %s.", c->getName(), shape->getName()); map->addDescription(msg); } else { sprintf(msg, "%s cancelled a pending action.", c->getName()); map->addDescription(msg); } // turn off selection mode setTargetSelectionFor(NULL); return true; } if(useDoor(pos)) { map->updateLightMap(); return true; } else if(useGate(pos)) { return true; } else if(useBoard(pos)) { return true; } else if(useTeleporter(pos)) { return true; } } } return false;}bool Scourge::getItem(Location *pos) { if(pos->item) { if(map->isWallBetween(pos->x, pos->y, pos->z, party->getPlayer()->getX(), party->getPlayer()->getY(), 0)) { map->addDescription(Constants::getMessage(Constants::ITEM_OUT_OF_REACH)); } else { movingX = pos->x; movingY = pos->y; movingZ = pos->z; movingItem = pos->item; int x = pos->x; int y = pos->y; int z = pos->z; map->removeItem(pos->x, pos->y, pos->z); map->dropItemsAbove(x, y, z, movingItem); // draw the item as 'selected' map->setSelectedDropTarget(NULL); map->handleMouseMove(movingX, movingY, movingZ); } return true; } return false;}// drop an item from the inventoryvoid Scourge::setMovingItem(Item *item, int x, int y, int z) { movingX = x; movingY = y; movingZ = z; movingItem = item;}void Scourge::dropItem(int x, int y) { int z; bool replace = false; if(map->getSelectedDropTarget()) { char message[120]; Creature *c = map->getSelectedDropTarget()->creature; if(c) { c->addInventory(movingItem); sprintf(message, "%s picks up %s.", c->getName(), movingItem->getItemName()); map->addDescription(message); // if the inventory is open, update it if(inventory->isVisible()) inventory->refresh(); } else if(map->getSelectedDropTarget()->item && map->getSelectedDropTarget()->item->getRpgItem()->getType() == RpgItem::CONTAINER) { map->getSelectedDropTarget()->item->addContainedItem(movingItem); sprintf(message, "%s is placed in %s.", movingItem->getItemName(), map->getSelectedDropTarget()->item->getItemName()); map->addDescription(message); // if this container's gui is open, update it refreshContainerGui(map->getSelectedDropTarget()->item); } else { replace = true; } } else { // see if it's blocked and get the value of z (stacking items) Location *pos = map->isBlocked(x, y, 0, movingX, movingY, movingZ, movingItem->getShape(), &z); if(!pos && !map->isWallBetween(party->getPlayer()->getX(), party->getPlayer()->getY(), party->getPlayer()->getZ(), x, y, z)) { map->setItem(x, y, z, movingItem); } else { replace = true; } } // failed to drop item; put it back to where we got it from if(replace) { if(movingX <= -1 || movingX >= MAP_WIDTH) { // the item drag originated from the gui... what to do? // for now don't end the drag return; } else { map->isBlocked(movingX, movingY, movingZ, -1, -1, -1, movingItem->getShape(), &z); map->setItem(movingX, movingY, z, movingItem); } } endItemDrag();}bool Scourge::useGate(Location *pos) { for(int i = 0; i < 4; i++) { if(!party->getParty(i)->getStateMod(Constants::dead)) { if(pos->shape == shapePal->findShapeByName("GATE_UP")) { oldStory = currentStory; currentStory--; changingStory = true; return true; } else if(pos->shape == shapePal->findShapeByName("GATE_DOWN")) { oldStory = currentStory; currentStory++; changingStory = true; return true; } } } return false;}bool Scourge::useBoard(Location *pos) { if(pos->shape == shapePal->findShapeByName("BOARD")) { board->boardWin->setVisible(true); return true; } return false;}bool Scourge::useTeleporter(Location *pos) { if(pos->shape == shapePal->findShapeByName("TELEPORTER") || pos->shape == shapePal->findShapeByName("TELEPORTER_BASE")) { // able to teleport if any party member is alive for(int i = 0; i < 4; i++) { if(!party->getParty(i)->getStateMod(Constants::dead)) { teleporting = true; return true; } } } return false;}bool Scourge::useDoor(Location *pos) { Shape *newDoorShape = NULL; if(pos->shape == shapePal->findShapeByName("EW_DOOR")) { newDoorShape = shapePal->findShapeByName("NS_DOOR"); } else if(pos->shape == shapePal->findShapeByName("NS_DOOR")) { newDoorShape = shapePal->findShapeByName("EW_DOOR"); } if(newDoorShape) { // switch door Sint16 ox = pos->x; Sint16 oy = pos->y; Sint16 nx = pos->x; Sint16 ny = (pos->y - pos->shape->getDepth()) + newDoorShape->getDepth(); Shape *oldDoorShape = map->removePosition(ox, oy, party->getPlayer()->getZ()); if(!map->isBlocked(nx, ny, party->getPlayer()->getZ(), ox, oy, party->getPlayer()->getZ(), newDoorShape)) { map->setPosition(nx, ny, party->getPlayer()->getZ(), newDoorShape); return true; } else { // rollback map->setPosition(ox, oy, party->getPlayer()->getZ(), oldDoorShape); map->addDescription(Constants::getMessage(Constants::DOOR_BLOCKED)); return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -