📄 map.cpp
字号:
glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glDisable( GL_CULL_FACE ); // draw circle double w = (double)creature->getShape()->getWidth() / GLShape::DIV; double s = 0.35f / GLShape::DIV; float xpos2, ypos2, zpos2; GLint t = SDL_GetTicks(); if(t - lastTick > 45) { // initialize target width if(targetWidth == 0.0f) { targetWidth = s; targetWidthDelta *= -1.0f; } // targetwidth oscillation targetWidth += targetWidthDelta; if((targetWidthDelta < 0 && targetWidth < s) || (targetWidthDelta > 0 && targetWidth >= s + (5 * targetWidthDelta))) targetWidthDelta *= -1.0f; lastTick = t; } if(player && creature->getSelX() > -1 && !creature->getTargetCreature() && !(creature->getSelX() == creature->getX() && creature->getSelY() == creature->getY()) ) { // draw target glColor4f(1.0f, 0.75f, 0.0f, 0.5f); xpos2 = ((float)(creature->getSelX() - getX()) / GLShape::DIV); ypos2 = ((float)(creature->getSelY() - getY()) / GLShape::DIV); zpos2 = 0.0f / GLShape::DIV; glPushMatrix(); glTranslatef( xpos2 + w / 2.0f, ypos2 - w, zpos2 + 5); gluDisk(creature->getQuadric(), w / 1.8f - targetWidth, w / 1.8f, 12, 1); glPopMatrix(); } if(player && creature->getTargetCreature()) { glColor4f(1.0f, 0.15f, 0.0f, 0.5f); xpos2 = ((float)(creature->getTargetCreature()->getX() - getX()) / GLShape::DIV); ypos2 = ((float)(creature->getTargetCreature()->getY() - getY()) / GLShape::DIV); zpos2 = 0.0f / GLShape::DIV; glPushMatrix(); glTranslatef( xpos2 + w / 2.0f, ypos2 - w, zpos2 + 5); gluDisk(creature->getQuadric(), w / 1.8f - targetWidth, w / 1.8f, 12, 1); glPopMatrix(); } xpos2 = ((float)(creature->getX() - getX()) / GLShape::DIV); ypos2 = ((float)(creature->getY() - getY()) / GLShape::DIV); zpos2 = (float)(creature->getZ()) / GLShape::DIV; if(creature->getAction() != Constants::ACTION_NO_ACTION) { glColor4f(0, 0.7, 1, 0.5f); } else if(selected) { glColor4f(0, 1, 1, 0.5f); } else if(player) { glColor4f(0.0f, 1.0f, 0.0f, 0.5f); } else { glColor4f(0.7f, 0.7f, 0.7f, 0.25f); } // draw state mods if(groupMode || player) { glEnable(GL_TEXTURE_2D); int n = 16; //float x = 0.0f; //float y = 0.0f; int on = 0; for(int i = 0; i < Constants::STATE_MOD_COUNT; i++) { if(creature->getStateMod(i) && i != Constants::dead) { on++; } } int count = 0; for(int i = 0; i < Constants::STATE_MOD_COUNT; i++) { if(creature->getStateMod(i) && i != Constants::dead) { glPushMatrix(); glTranslatef( xpos2 + w / 2.0f, ypos2 - w, zpos2 + 5); // glRotatef( count * (360.0f / Constants::STATE_MOD_COUNT), 0, 0, 1 ); // glRotatef( count * (360.0f / on), 0, 0, 1 ); float angle = -(count * 30) - (zrot + 180); glRotatef( angle, 0, 0, 1 ); glTranslatef( w / 2.0f + 15, 0, 0 ); glRotatef( (count * 30) + 180, 0, 0, 1 ); glTranslatef( -7, -7, 0 ); // drawStateMod(i); //glColor4f( 1, 1, 1, 1 ); GLuint icon = scourge->getShapePalette()->getStatModIcon(i); if(icon) { glBindTexture( GL_TEXTURE_2D, icon ); } glBegin( GL_QUADS ); glNormal3f( 0, 0, 1 ); if(icon) glTexCoord2f( 0, 0 ); glVertex3f( 0, 0, 0 ); if(icon) glTexCoord2f( 0, 1 ); glVertex3f( 0, n, 0 ); if(icon) glTexCoord2f( 1, 1 ); glVertex3f( n, n, 0 ); if(icon) glTexCoord2f( 1, 0 ); glVertex3f( n, 0, 0 ); glEnd(); glPopMatrix(); count++; } } glDisable(GL_TEXTURE_2D); } glTranslatef( xpos2 + w / 2.0f, ypos2 - w, zpos2 + 5); if(groupMode || player) gluDisk(creature->getQuadric(), w / 1.8f - s, w / 1.8f, 12, 1); glEnable( GL_CULL_FACE ); glDisable( GL_BLEND ); glDisable( GL_DEPTH_TEST ); glDepthMask(GL_TRUE); // draw name glTranslatef( 0, 0, 100); scourge->getSDLHandler()->texPrint(0, 0, "%s", creature->getName()); glPopMatrix();}/** * Initialize the map view (translater, rotate) */void Map::initMapView(bool ignoreRot) { glLoadIdentity(); // adjust for screen size float adjust = (float)scourge->getSDLHandler()->getScreen()->w / 800.0f; glScalef(adjust, adjust, adjust); glScalef(zoom, zoom, zoom); // translate the camera and rotate // the offsets ensure that the center of rotation is under the player glTranslatef( this->xpos, this->ypos, 0); glRotatef( xrot, 0.0f, 1.0f, 0.0f ); if(!ignoreRot) { glRotatef( yrot, 1.0f, 0.0f, 0.0f ); } glRotatef( zrot, 0.0f, 0.0f, 1.0f ); glTranslatef( 0, 0, this->zpos); // float startx = -(((float)MAP_VIEW_WIDTH + (mapx - (float)x)) / 2.0) / GLShape::DIV; // float starty = -(((float)MAP_VIEW_DEPTH + (mapy - (float)y)) / 2.0) / GLShape::DIV; float startx = -((float)MAP_VIEW_WIDTH / 2.0 + (mapx - (float)x)) / GLShape::DIV; float starty = -((float)MAP_VIEW_DEPTH / 2.0 + (mapy - (float)y)) / GLShape::DIV; //float startz = -(float)(MAP_VIEW_HEIGHT) / GLShape::DIV; float startz = 0.0; glTranslatef( startx, starty, startz );}Location *Map::moveCreature(Sint16 x, Sint16 y, Sint16 z, Uint16 dir,Creature *newCreature) { Sint16 nx = x; Sint16 ny = y; Sint16 nz = z; switch(dir) { case Constants::MOVE_UP: ny--; break; case Constants::MOVE_DOWN: ny++; break; case Constants::MOVE_LEFT: nx--; break; case Constants::MOVE_RIGHT: nx++; break; } return moveCreature(x, y, z, nx, ny, nz, newCreature);}Location *Map::moveCreature(Sint16 x, Sint16 y, Sint16 z, Sint16 nx, Sint16 ny, Sint16 nz, Creature *newCreature) { //float interX, interY; Location *position = isBlocked(nx, ny, nz, x, y, z, newCreature->getShape()); if(position) return position; // move position removeCreature(x, y, z); //interX = (x + nx) / 2.0f; //interY = (y + ny) / 2.0f; //cout << "old : " << x << ", " << y << ", " << z << endl; //cout << "new : " << nx << ", " << ny << ", " << nz << endl; setCreature(nx, ny, nz, newCreature); return NULL;}void Map::setFloorPosition(Sint16 x, Sint16 y, Shape *shape) { floorPositions[x][y] = shape; for(int xp = 0; xp < shape->getWidth(); xp++) { for(int yp = 0; yp < shape->getDepth(); yp++) { scourge->getMiniMap()->colorMiniMapPoint(x + xp, y - yp, shape); } }}Shape *Map::removeFloorPosition(Sint16 x, Sint16 y) { Shape *shape = NULL; if(floorPositions[x][y]) { shape = floorPositions[x][y]; floorPositions[x][y] = 0; for(int xp = 0; xp < shape->getWidth(); xp++) { for(int yp = 0; yp < shape->getDepth(); yp++) { // fixme : is it good or not to erase the minimap too ??? scourge->getMiniMap()->eraseMiniMapPoint(x, y); } } } return shape;}Location *Map::isBlocked(Sint16 x, Sint16 y, Sint16 z, Sint16 shapeX, Sint16 shapeY, Sint16 shapeZ, Shape *s, int *newz) { int zz = z; for(int sx = 0; sx < s->getWidth(); sx++) { for(int sy = 0; sy < s->getDepth(); sy++) { // find the lowest location where this item fits int sz = z; while(sz < zz + s->getHeight()) { Location *loc = pos[x + sx][y - sy][z + sz]; if(loc && loc->shape && !(loc->x == shapeX && loc->y == shapeY && loc->z == shapeZ)) { if(newz && (loc->item || loc->creature)) { int tz = loc->z + loc->shape->getHeight(); if(tz > zz) zz = tz; if(zz + s->getHeight() >= MAP_VIEW_HEIGHT) { return pos[x + sx][y - sy][z + sz]; } if(zz > sz) sz = zz; else break; } else if(newz && loc) { return pos[x + sx][y - sy][z + sz]; } else if(!newz && !(loc && loc->item && !loc->item->isBlocking())) { return pos[x + sx][y - sy][z + sz]; } else { sz++; } } else { sz++; } } } } if(newz) *newz = zz; return NULL;}void Map::switchPlaces(Sint16 x1, Sint16 y1, Sint16 z1, Sint16 x2, Sint16 y2, Sint16 z2) { Shape *shape1 = removePosition(x1, y1, z1); Shape *shape2 = removePosition(x2, y2, z2); Location *position = isBlocked(x2, y2, z2, x1, y1, z1, shape1); if(position) { // can't do it setPosition(x1, y1, z1, shape1); setPosition(x2, y2, z2, shape2); return; } // move it setPosition(x2, y2, z2, shape1); position = isBlocked(x1, y1, z1, x2, y2, z2, shape2); if(position) { // can't do it removePosition(x2, y2, z2); // undo previous step setPosition(x1, y1, z1, shape1); setPosition(x2, y2, z2, shape2); return; } // move it setPosition(x1, y1, z1, shape2); }Location *Map::getPosition(Sint16 x, Sint16 y, Sint16 z) { if(pos[x][y][z] && ((pos[x][y][z]->shape && pos[x][y][z]->x == x && pos[x][y][z]->y == y && pos[x][y][z]->z == z))) return pos[x][y][z]; return NULL;}void Map::addDescription(char *desc, float r, float g, float b) { if(descriptionCount > 0) { int last = descriptionCount; if(last >= MAX_DESCRIPTION_COUNT) last--; for(int i = last; i >= 1; i--) { strcpy(descriptions[i], descriptions[i - 1]); descriptionsColor[i].r = descriptionsColor[i - 1].r; descriptionsColor[i].g = descriptionsColor[i - 1].g; descriptionsColor[i].b = descriptionsColor[i - 1].b; } } if(descriptionCount < MAX_DESCRIPTION_COUNT) descriptionCount++; // only copy as much as the buffer can hold strncpy(descriptions[0], desc, 120); // zero terminate just in case desc.length > 120 descriptions[0][119] = 0; descriptionsColor[0].r = r; descriptionsColor[0].g = g; descriptionsColor[0].b = b; descriptionsChanged = true;}void Map::drawDescriptions(ScrollingList *list) { if(descriptionsChanged) { descriptionsChanged = false; list->setLines(descriptionCount, (const char**)descriptions, descriptionsColor); } /* glPushMatrix(); glLoadIdentity(); //glColor4f(1.0f, 1.0f, 0.4f, 1.0f); int y = TOP_GUI_HEIGHT - 5; if(descriptionCount <= 5) y = descriptionCount * 15; int index = 0; while(y > 5 && index < descriptionCount) { glColor4f(descriptions[index].r, descriptions[index].g, descriptions[index].b, 1.0f); glRasterPos2f( (float)5, (float)y ); scourge->getSDLHandler()->texPrint(5, y, "%s", descriptions[index].text); y -= 15; index++; } glPopMatrix(); */}void Map::handleMouseClick(Uint16 mapx, Uint16 mapy, Uint16 mapz, Uint8 button) { char s[300]; if(mapx < MAP_WIDTH) { if(button == SDL_BUTTON_RIGHT) { //fprintf(stderr, "\tclicked map coordinates: x=%u y=%u z=%u\n", mapx, mapy, mapz); Location *loc = getPosition(mapx, mapy, mapz); if(loc) { char *description = NULL; Creature *creature = loc->creature; //fprintf(stderr, "\tcreature?%s\n", (creature ? "yes" : "no")); if(creature) { creature->getDetailedDescription(s); description = s; } else { Item *item = loc->item; //fprintf(stderr, "\titem?%s\n", (item ? "yes" : "no")); if( item ) { item->getDetailedDescription(s, false); description = s; } else { Shape *shape = loc->shape; //fprintf(stderr, "\tshape?%s\n", (shape ? "yes" : "no")); if(shape) { description = scourge->getShapePalette()->getRandomDescription(shape->getDescriptionGroup()); } } } if(description) { addDescription(description); } } } }}void Map::handleMouseMove(Uint16 mapx, Uint16 mapy, Uint16 mapz) { if(mapx < MAP_WIDTH) { selX = mapx; selY = mapy; selZ = mapz; }} void Map::startEffect(Sint16 x, Sint16 y, Sint16 z, int effect_type, int duration, int width, int height) { // show an effect if(effect[x][y][z]) { if(effect[x][y][z]->isEffectOn() && effect[x][y][z]->effectType == effect_type) { return; } else { removeEffect(x, y, z); } } if(!effect[x][y][z]) { effect[x][y][z] = new EffectLocation(); } effect[x][y][z]->effect = new Effect(scourge, scourge->getShapePalette(), width, height); effect[x][y][z]->effect->deleteParticles(); effect[x][y][z]->resetDamageEffect(); effect[x][y][z]->effectType = effect_type; effect[x][y][z]->effectDuration = duration; effect[x][y][z]->x = x; effect[x][y][z]->y = y; effect[x][y][z]->z = z; currentEffects.push_back(effect[x][y][z]); // need to do this to make sure effect shows up mapChanged = true;}void Map::removeEffect(Sint16 x, Sint16 y, Sint16 z) { if(effect[x][y][z]) { delete effect[x][y][z]; effect[x][y][z] = NULL; }}void Map::setPosition(Sint16 x, Sint16 y, Sint16 z, Shape *shape) { if(shape) { mapChanged = true; for(int xp = 0; xp < shape->getWidth(); xp++) { for(int yp = 0; yp < shape->getDepth(); yp++) { scourge->getMiniMap()->colorMiniMapPoint(x + xp, y - yp, shape); for(int zp = 0; zp < shape->getHeight(); zp++) { if(!pos[x + xp][y - yp][z + zp]) { pos[x + xp][y - yp][z + zp] = new Location(); } pos[x + xp][y - yp][z + zp]->shape = shape; pos[x + xp][y - yp][z + zp]->item = NULL; pos[x + xp][y - yp][z + zp]->creature = NULL; pos[x + xp][y - yp][z + zp]->x = x; pos[x + xp][y - yp][z + zp]->y = y; pos[x + xp][y - yp][z + zp]->z = z; } } } }}Shape *Map::removePosition(Sint16 x, Sint16 y, Sint16 z) { Shape *shape = NULL; if(pos[x][y][z] && pos[x][y][z]->shape && pos[x][y][z]->x == x && pos[x][y][z]->y == y && pos[x][y][z]->z == z) { mapChanged = true; shape = pos[x][y][z]->shape; for(int xp = 0; xp < shape->getWidth(); xp++) { for(int yp = 0; yp < shape->getDepth(); yp++) { // fixme : is it good or not to erase the minimap too ??? scourge->getMiniMap()->eraseMiniMapPoint(x + xp, y - yp); for(int zp = 0; zp < shape->getHeight(); zp++) { //cerr <<"remove pos " << x + xp << "," << y - yp << "," << z + zp<<endl; delete pos[x + xp][y - yp][z + zp];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -