| 1132 | } |
| 1133 | |
| 1134 | void MainInterface::renderMonsterHealthBar() { |
| 1135 | auto assets = Root::singleton().assets(); |
| 1136 | auto imgMetadata = Root::singleton().imageMetadataDatabase(); |
| 1137 | if (m_lastMouseoverTarget != NullEntityId && !m_stickyTargetingTimer.ready()) { |
| 1138 | auto world = m_client->worldClient(); |
| 1139 | |
| 1140 | auto entity = world->entity(m_lastMouseoverTarget); |
| 1141 | auto showDamageEntity = as<DamageBarEntity>(entity); |
| 1142 | |
| 1143 | if (!showDamageEntity) { |
| 1144 | m_lastMouseoverTarget = NullEntityId; |
| 1145 | return; |
| 1146 | } |
| 1147 | |
| 1148 | Vec2F backgroundCenterPos = Vec2F(windowWidth() / 2.0f, windowHeight()); |
| 1149 | |
| 1150 | auto container = assets->json("/interface.config:monsterHealth.container").toString(); |
| 1151 | auto offset = jsonToVec2F(assets->json("/interface.config:monsterHealth.offset")) * interfaceScale(); |
| 1152 | m_guiContext->drawQuad(container, RectF::withCenter(backgroundCenterPos + offset, Vec2F(imgMetadata->imageSize(container) * interfaceScale()))); |
| 1153 | |
| 1154 | auto nameTextOffset = jsonToVec2F(assets->json("/interface.config:monsterHealth.nameTextOffset")) * interfaceScale(); |
| 1155 | m_guiContext->setTextStyle(m_config->textStyle); |
| 1156 | m_guiContext->renderText(showDamageEntity->name(), backgroundCenterPos + nameTextOffset); |
| 1157 | |
| 1158 | auto empty = assets->json("/interface.config:monsterHealth.progressEmpty").toString(); |
| 1159 | auto filled = assets->json("/interface.config:monsterHealth.progressFilled").toString(); |
| 1160 | auto progressBarOffset = jsonToVec2F(assets->json("/interface.config:monsterHealth.progressBarOffset")) * interfaceScale(); |
| 1161 | auto chunks = assets->json("/interface.config:monsterHealth.progressChunks").toInt(); |
| 1162 | int blocks = round(showDamageEntity->health() / showDamageEntity->maxHealth() * chunks); |
| 1163 | Vec2F barPos = backgroundCenterPos + progressBarOffset; |
| 1164 | Vec2F barItemOffset = Vec2F(imgMetadata->imageSize(filled)) * interfaceScale(); |
| 1165 | barItemOffset[1] = 0; |
| 1166 | |
| 1167 | m_guiContext->drawQuad(empty, RectF::withSize(backgroundCenterPos + barPos, Vec2F(imgMetadata->imageSize(empty) * interfaceScale()))); |
| 1168 | |
| 1169 | for (int i = 0; i < blocks; i++) |
| 1170 | m_guiContext->drawQuad(filled, barPos + barItemOffset * i, interfaceScale()); |
| 1171 | |
| 1172 | auto portraitOffset = jsonToVec2F(assets->json("/interface.config:monsterHealth.portraitOffset")) * interfaceScale(); |
| 1173 | auto portraitScale = assets->json("/interface.config:monsterHealth.portraitScale").toFloat() * interfaceScale(); |
| 1174 | |
| 1175 | auto portraitScissorRect = jsonToRectF(assets->json("/interface.config:monsterHealth.portraitScissorRect")).scaled(interfaceScale()); |
| 1176 | auto rect = portraitScissorRect.translated(backgroundCenterPos + portraitOffset); |
| 1177 | m_guiContext->setInterfaceScissorRect(RectI(RectF(rect).scaled(1.0f / interfaceScale()))); |
| 1178 | auto portraitMaxSize = jsonToVec2I(assets->json("/interface.config:monsterHealth.portraitMaxSize")); |
| 1179 | List<Drawable> portrait = showDamageEntity->portrait(PortraitMode::Full); |
| 1180 | |
| 1181 | auto bounds = Drawable::boundBoxAll(portrait, true); |
| 1182 | if (m_portraitScale == 0) |
| 1183 | m_portraitScale = max<int>(1, ceil(max(bounds.size().x() / portraitMaxSize.x(), bounds.size().y() / portraitMaxSize.y()))); |
| 1184 | Drawable::translateAll(portrait, {-bounds.xMin() - (bounds.width() * 0.5f), -bounds.yMin() }); // crop out whitespace, align bottom center |
| 1185 | Drawable::scaleAll(portrait, 1.0f / m_portraitScale); |
| 1186 | |
| 1187 | for (auto drawable : portrait) |
| 1188 | m_guiContext->drawDrawable(std::move(drawable), backgroundCenterPos + portraitOffset, portraitScale); |
| 1189 | |
| 1190 | m_guiContext->resetInterfaceScissorRect(); |
| 1191 | } |
nothing calls this directly
no test coverage detected