static void drawDebugEntities() { for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); Entity * entity = entities[handle]; if(!entity) { continue; } Color color = Color::white; bool visible = true; switch(entity->show) { case SHOW_FLAG_DESTROYED: continue; // Don't even display the name case SHOW_FLAG_IN_INVENTORY: continue; case SHOW_FLAG_ON_PLAYER: continue; case SHOW_FLAG_LINKED: continue; case SHOW_FLAG_NOT_DRAWN: color = Color::magenta; visible = false; break; case SHOW_FLAG_HIDDEN: color = Color::yellow; visible = false; break; case SHOW_FLAG_MEGAHIDE: color = Color::green; visible = false; break; case SHOW_FLAG_KILLED: color = Color::red; visible = false; break; case SHOW_FLAG_IN_SCENE: color = Color::white; visible = true; break; case SHOW_FLAG_TELEPORTING: color = Color::blue; visible = true; break; } if((entity->ioflags & IO_CAMERA) || (entity->ioflags & IO_MARKER)) { color = Color::gray(0.7f), visible = false; } if(DRAGINTER == entity) { color = Color::white, visible = true; } if(visible) { drawDebugBoundingBox(entity->bbox2D, Color::blue); } if(closerThan(entity->pos, player.pos, DebugTextMaxDistance)) { if(visible && entity->bbox2D.valid()) { int x = (entity->bbox2D.min.x + entity->bbox2D.max.x) / 2; int y = entity->bbox2D.min.y - hFontDebug->getLineHeight() - 2; UNICODE_ARXDrawTextCenter(hFontDebug, Vec2f(x, y), entity->idString(), color); } else { drawTextAt(hFontDebug, entity->pos, entity->idString(), color); } if(entity->obj) { for(size_t j = 0; j < entity->obj->linked.size(); j++) { Vec3f pos = actionPointPosition(entity->obj, entity->obj->linked[j].lidx); Entity * other = entity->obj->linked[j].io; drawTextAt(hFontDebug, pos, other->idString(), Color::cyan); } } } } }
void MessageQueue::Render() { RECT rect = {0, 0, 256, 300}; drawTextAt(bigMessageString.c_str(), &rect); }
static void drawDebugPaths() { GRenderer->SetRenderState(Renderer::DepthTest, false); for(long i = 0; i < nbARXpaths; i++) { ARX_PATH * path = ARXpaths[i]; if(!path) { continue; } Vec3f center = Vec3f_ZERO; int n = 0; std::vector<Vec3f> points; for(long i = 0; i < path->nb_pathways; i++) { const ARX_PATHWAY & node = path->pathways[i]; Vec3f pos = path->pos + node.rpos; points.push_back(pos); center += pos, n++; if(node.flag == PATHWAY_BEZIER) { // Interpolate bezier curve by creating linear segments if(i + 2 >= path->nb_pathways) { break; } const size_t nsegments = 20; for(size_t j = 0; j < nsegments; j++) { points.push_back(path->interpolateCurve(i, float(j) / nsegments)); } i++; // Skip the control point } } // Zones only check the bounding box for the y coordinate - adjust display for that if(path->height > 0) { for(size_t i = 0; i < points.size(); i++) { points[i].y = path->bbmin.y; } } if(path->height != 0 || ((path->flags & PATH_LOOP) && points.size() > 0)) { points.push_back(points[0]); } Color color = (path->height != 0) ? Color::green : Color::red; for(size_t i = 0; i + 1 < points.size(); i++) { drawLine(points[i], points[i + 1], color); } if(path->height > 0) { Vec3f offset(0.f, (path->bbmax.y - path->bbmin.y), 0.f); for(size_t i = 0; i + 1 < points.size(); i++) { drawLine(points[i] + offset, points[i + 1] + offset, color); } for(size_t i = 0; i < points.size(); i++) { drawLine(points[i], points[i] + offset, color); } } // Display the name and controlling entity for close zones if(!path->name.empty() || !path->controled.empty()) { if(path->height > 0) { center = (path->bbmin + path->bbmax) / 2.f; } else if(n != 0) { center /= float(n); } else { center = path->pos; } if(closerThan(center, player.pos, DebugTextMaxDistance)) { std::string controlledby; if(!path->controled.empty()) { controlledby = "Controlled by: " + path->controled; } Color textcolor = color * 0.5f + Color::gray(0.5f); drawTextAt(hFontDebug, center, path->name, textcolor, controlledby); } } } GRenderer->SetRenderState(Renderer::DepthTest, true); }
static void drawDebugPathFinding() { if(!ACTIVEBKG || !ACTIVEBKG->anchors) { return; } const float zbias = 0.00001f; for(long i = 0; i < ACTIVEBKG->nbanchors; i++) { const ANCHOR_DATA & node = ACTIVEBKG->anchors[i]; Color color1 = (node.flags & ANCHOR_FLAG_BLOCKED) ? Color::blue : Color::green; for(long j = 0; j < node.nblinked; j++) { long k = node.linked[j]; if(k >= 0 && k < ACTIVEBKG->nbanchors && i < k) { const ANCHOR_DATA & other = ACTIVEBKG->anchors[k]; Color color2 = (other.flags & ANCHOR_FLAG_BLOCKED) ? Color::blue : Color::green; drawLine(node.pos, other.pos, color1, color2, zbias); } } if(node.height != 0.f) { Vec3f toppos = node.pos + Vec3f(0.f, node.height, 0.f); drawLine(node.pos, toppos, Color::blue, zbias); } } // Highlight active paths for(size_t i = 1; i < entities.size(); i++) { const EntityHandle handle = EntityHandle(i); const Entity * entity = entities[handle]; if(!entity || !(entity->ioflags & IO_NPC)) { continue; } const IO_PATHFIND & pathfind = entity->_npcdata->pathfind; if(pathfind.listnb <= 0 || !pathfind.list) { continue; } // Draw visited nodes yellow and target nodes as red for(long j = 1; j < pathfind.listnb; j++) { short k0 = pathfind.list[j - 1], k1 = pathfind.list[j]; if(k0 >= 0 && k0 < ACTIVEBKG->nbanchors && k1 >= 0 && k1 < ACTIVEBKG->nbanchors) { const ANCHOR_DATA & n0 = ACTIVEBKG->anchors[k0], & n1 = ACTIVEBKG->anchors[k1]; Color color0 = (j <= pathfind.listpos) ? Color::yellow : Color::red; Color color1 = (j + 1 <= pathfind.listpos) ? Color::yellow : Color::red; drawLine(n0.pos, n1.pos, color0, color1, 2.f * zbias); } } // Highlight end nodes short k0 = pathfind.list[pathfind.listnb - 1]; if(k0 >= 0 && k0 < ACTIVEBKG->nbanchors) { Anglef angle(0.f, 0.f, 0.f); Vec3f scale(0.5f); RenderMaterial mat; mat.setBlendType(RenderMaterial::Opaque); mat.setDepthTest(true); Draw3DObject(g_nodeObject, angle, ACTIVEBKG->anchors[k0].pos, scale, Color3f::white, mat); } // Show entity ID at the active node if(pathfind.listpos < pathfind.listnb) { short k1 = pathfind.list[pathfind.listpos]; if(k1 >= 0 && k1 < ACTIVEBKG->nbanchors) { if(closerThan(ACTIVEBKG->anchors[k1].pos, player.pos, DebugTextMaxDistance)) { drawTextAt(hFontDebug, ACTIVEBKG->anchors[k1].pos, entity->idString()); GRenderer->SetRenderState(Renderer::DepthTest, true); } } } } }
float GiGraphics::drawTextAt(int argb, const char* text, const Point2d& pnt, float h, int align, float angle) { return drawTextAt((GiTextWidthCallback *)0, argb, text, pnt, h, align, angle); }