⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scourge.cpp

📁 S.C.O.U.R.G.E.是一款类似Rogue的游戏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -