Marine UI updates

This commit is contained in:
pierow 2021-10-29 12:20:37 -04:00
parent 22a171f4b5
commit 039f01e42c
8 changed files with 202 additions and 34 deletions

View file

@ -117,7 +117,7 @@ entity_state_t gamedll Entity_Encode
DEFINE_DELTA( playerclass, DT_INTEGER, 1, 1.0 ),
//DEFINE_DELTA( iuser2, DT_INTEGER, 32, 1.0 ), // NS custom code (used for entity ids for research)
DEFINE_DELTA( iuser2, DT_INTEGER, 8, 1.0 ), // NS custom code (used for entity ids for research)
DEFINE_DELTA( iuser3, DT_INTEGER, 6, 1.0 ), // NS custom code
DEFINE_DELTA( iuser4, DT_INTEGER, 32, 1.0 ), // NS custom parameter (needs 32 for AvHSpecialSound)
DEFINE_DELTA( fuser1, DT_FLOAT, 32, 1.0 ) // Use 32-bits because two values fit in here sometimes

View file

@ -151,8 +151,9 @@ void ActionButton::Localize(const AvHTechTree& inTechNodes)
// Localize help string
this->mHelpText = "";
string theCostAndTimeText;
if(gHUD.GetHelpForMessage(this->mMessageID, this->mHelpText))
if(gHUD.GetHelpForMessage(this->mMessageID, this->mHelpText, theCostAndTimeText))
{
// Add hotkey accelerator
if(this->mButtonIndex >= 0)
@ -167,6 +168,8 @@ void ActionButton::Localize(const AvHTechTree& inTechNodes)
string theHotkeyText = string("(") + theHotkeyChar + string(")");
this->mHelpText += string(" ");
this->mHelpText += theHotkeyText;
if (theCostAndTimeText != "")
this->mHelpText += string("\n") + theCostAndTimeText;
}
}

View file

@ -89,6 +89,7 @@
#include "AvHPlayerUpgrade.h"
#include "../dlls/animation.h"
#include "AvHMovementUtil.h"
#include "AvHNetworkMessages.h"
const int kBaseBuildableSpawnAnimation = 0;
const int kBaseBuildableDeployAnimation = 1;
@ -702,6 +703,25 @@ AvHTeamNumber AvHBaseBuildable::GetTeamNumber() const
void AvHBaseBuildable::Killed(entvars_t* pevAttacker, int iGib)
{
bool theInReset = GetGameRules()->GetIsGameInReset();
// Send a Cancel notification so any research can be removed from the research tracker.
if (GetGameRules()->GetGameStarted())
{
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
bool theShowNotification = false;
// Show to friendlies...
if (theEntity->pev->team == this->pev->team)
{
theShowNotification = true;
}
if (theShowNotification)
{
NetMsg_PlayHUDNotification(theEntity->pev, 1, MESSAGE_CANCEL, this->pev->origin.x, this->pev->origin.y);
}
END_FOR_ALL_ENTITIES(kAvHPlayerClassName);
}
AvHBaseBuildable::SetHasBeenKilled();
GetGameRules()->RemoveEntityUnderAttack( this->entindex() );

View file

@ -257,12 +257,52 @@ void AvHCommanderModeHandler::RecalculateBuildResearchText()
LocalizeString(kResearchingPrefix, theHelpPrefix);
}
//iuser2 gets set when research starts so it doesn't work for building.
string theHelpText;
AvHMessageID theResearchID = (AvHMessageID)(theEntity->curstate.iuser2);
if(theResearchID != MESSAGE_NULL)
{
if(ActionButton::GetLabelForMessage(theResearchID, theHelpText))
{
//Research timer and refund UI. Assumes no cheats or combat mode. Building timer would need to check the number of people building or its build rate.
if (theIsResearching)
{
bool theResearchable;
float timeToBuild;
int researchCost;
gHUD.GetResearchInfo(theResearchID, theResearchable, researchCost, timeToBuild);
//Display time to completion.
int timeLeft = (1 - thePercentage) * timeToBuild;
int theMinutesLeft = timeLeft / 60;
int theSecondsLeft = timeLeft % 60;
if (theMinutesLeft)
theHelpText += " (" + MakeStringFromInt(theMinutesLeft) + "m " + MakeStringFromInt(theSecondsLeft) + "s)";
else
theHelpText += " (" + MakeStringFromInt(theSecondsLeft) + "s)";
//Display amount refunded if canceled.
if (researchCost)
{
int theRefund = round((1 - thePercentage) * researchCost);
//Some lazy centering that's good enough. Should be making a new UI label for this or matching width.
string theRefundText = "Cancellation refund: " + MakeStringFromInt(theRefund);
int helpLength = theHelpPrefix.length() + theHelpText.length();
int refundLength = theRefundText.length();
//int padNumber = ((helpLength - refundLength) / 2);
int padNumber = (helpLength - refundLength) - 1;
if (padNumber > 0)
{
theHelpText += "\n\n" + string(padNumber, ' ') + theRefundText;
}
else
theHelpText += "\n\n" + theRefundText;
}
}
string theFinalMessage = theHelpPrefix + theHelpText;
this->mBuildResearchText = theFinalMessage;
}

View file

@ -4813,7 +4813,7 @@ void AvHHud::InitExploitPrevention() {
ForceCvar("gl_d3dflip", gl_d3dflip, 1.0f);
ForceCvar("s_show", s_show, 0.0f);
ForceCvar("r_detailtextures", r_detailtextures, 0.0f);
ForceCvar("gl_max_size", gl_max_size, 256.0f);
ForceCvar("gl_max_size", gl_max_size, 512.0f);
RemoveAlias("lightgamma");
if(lightgamma && lightgamma->value < 2.0) {
@ -4845,7 +4845,7 @@ void AvHHud::UpdateExploitPrevention()
ForceCvar("gl_d3dflip", gl_d3dflip, 1.0f);
ForceCvar("s_show", s_show, 0.0f);
ForceCvar("r_detailtextures", r_detailtextures, 0.0f);
ForceCvar("gl_max_size", gl_max_size, 256.0f);
ForceCvar("gl_max_size", gl_max_size, 512.0f);
if(lightgamma && lightgamma->value < 2.0) {
ForceCvar("lightgamma", lightgamma, 2.0f);
@ -5231,7 +5231,7 @@ bool AvHHud::GetDoesPlayerHaveOrder() const
}
bool AvHHud::GetHelpForMessage(int inMessageID, string& outHelpText) const
bool AvHHud::GetHelpForMessage(int inMessageID, string& outHelpText, string& outCostAndTimeText) const
{
bool theSuccess = false;
@ -5262,20 +5262,32 @@ bool AvHHud::GetHelpForMessage(int inMessageID, string& outHelpText) const
if(AvHSHUGetDoesTechCostEnergy((AvHMessageID)inMessageID))
{
LocalizeString(kEnergyPrefix, theCostString);
outCostAndTimeText = theCostString + " " + MakeStringFromInt(theCost);
}
else
{
LocalizeString(kMessageButtonCost, theCostString);
//Research or build time. TODO: localize.
string theResearchOrBuildString;
theResearchOrBuildString = AvHSHUGetIsBuilding((AvHMessageID)inMessageID) ? string("Build") : string("Research");
outCostAndTimeText = theCostString + " " + MakeStringFromInt(theCost);
if (theTime > 0)
{
int timeToFinish = theTime;
int theMinutes = timeToFinish / 60;
int theSeconds = timeToFinish % 60;
if (theMinutes)
outCostAndTimeText += "\n" + theResearchOrBuildString + " time " + MakeStringFromInt(theMinutes) + "m " + MakeStringFromInt(theSeconds) + "s";
else
outCostAndTimeText += "\n" + theResearchOrBuildString + " time " + MakeStringFromInt(theSeconds) + "s";
}
}
outHelpText += " ";
outHelpText += theCostString;
outHelpText += " ";
outHelpText += MakeStringFromInt(theCost);
// Draw description below
//outHelpText += "\n";
//outHelpText += theTechNodeHelp;
//outCostAndTimeText += "\n";
//outCostAndTimeText += theTechNodeHelp;
}
}
}
@ -5634,6 +5646,11 @@ const AvHTechTree& AvHHud::GetTechNodes() const
return this->mTechNodes;
}
bool AvHHud::GetResearchInfo(AvHMessageID inMessageID, bool& outIsResearchable, int& outCost, float& outTime) const
{
return this->mTechNodes.GetResearchInfo(inMessageID, outIsResearchable, outCost, outTime);
}
void AvHHud::GetTooltipDrawingInfo(float& outNormX, float& outNormY) const
{
outNormX = kHelpMessageLeftEdgeInset;
@ -5832,12 +5849,41 @@ void AvHHud::UpdateTooltips(float inCurrentTime)
void AvHHud::UpdateStructureNotification(float inCurrentTime)
{
const float kTimeToDisplayIcon = 6.0f;
const int kMaxIcons = 5;
Vector cancelLocation;
AvHTeamNumber theCurrentTeam = this->GetHUDTeam();
// Reset on a team change
if (this->mLastTeamNumber != theCurrentTeam)
this->mStructureNotificationList.clear();
for(StructureHUDNotificationListType::iterator theIter = this->mStructureNotificationList.begin(); theIter != this->mStructureNotificationList.end(); /* no inc */)
{
if((inCurrentTime > (theIter->mTime + kTimeToDisplayIcon)) || (this->mStructureNotificationList.size() > kMaxIcons))
int theCost;
bool theResearchable;
float theBuildOrResearchTime;
AvHMessageID theTech = theIter->mStructureID;
this->mTechNodes.GetResearchInfo(theTech, theResearchable, theCost, theBuildOrResearchTime);
bool isResearch = AvHSHUGetIsResearchTech(theTech);
float timeToDisplayIcon = 6.0f;
if (isResearch)
{
theIter->mResearchTimer = max(0, theBuildOrResearchTime - (inCurrentTime - theIter->mTime));
timeToDisplayIcon = theBuildOrResearchTime;
}
else
{
theIter->mResearchTimer = 0;
}
if (theTech == MESSAGE_CANCEL)
{
cancelLocation = theIter->mLocation;
this->mStructureNotificationList.erase(theIter);
theIter = this->mStructureNotificationList.begin();
}
else if ((inCurrentTime > (theIter->mTime + timeToDisplayIcon)) || (!(theIter->mResearchTimer > 0) && this->mStructureNotificationList.size() > kMaxIcons ) || (theIter->mLocation == cancelLocation))
{
theIter = this->mStructureNotificationList.erase(theIter);
}
@ -6316,29 +6362,38 @@ void AvHHud::UpdateBuildResearchText()
if(this->GetHUDUser3() == AVH_USER3_COMMANDER_PLAYER)
{
Label* theHelpTextLabel = NULL;
if(this->GetManager().GetVGUIComponentNamed(kTechHelpText, theHelpTextLabel))
//Label* theRefundTextLabel = NULL;
if(this->GetManager().GetVGUIComponentNamed(kTechHelpText, theHelpTextLabel)/* && this->GetManager().GetVGUIComponentNamed(kTechHelpText, theRefundTextLabel)*/)
{
gCommanderHandler.RecalculateBuildResearchText();
// Display build/research text
string theBuildResearchText = gCommanderHandler.GetBuildResearchText();
theHelpTextLabel->setText(theBuildResearchText.c_str());
//string theBuildRefundText = gCommanderHandler.GetBuildRefundText();
//theRefundTextLabel->setText(theBuildRefundText.c_str());
// Center it
int theWidth, theHeight;
int theWidth, theHeight/*, theWidth2, theHeight2*/;
theHelpTextLabel->getTextSize(theWidth, theHeight);
//theRefundTextLabel->getTextSize(theWidth2, theHeight2);
int theX, theY;
int theX, theY/*, theX2, theY2*/;
theHelpTextLabel->getPos(theX, theY);
//theRefundTextLabel->getPos(theX2, theY2);
int theScreenWidth = ScreenWidth();
theHelpTextLabel->setPos(theScreenWidth/2 - theWidth/2, theY);
//theRefundTextLabel->setPos(theScreenWidth / 2 - theWidth2 / 2, theY2);
//gEngfuncs.Con_Printf("y2:%d\n", theY2);
// Vanish if no text (but keep build/research text visible)
theHelpTextLabel->setVisible(true);
//theRefundTextLabel->setVisible(true);
if(theBuildResearchText.length() == 0)// || ((this->mTimeLastHelpTextChanged != -1) && (this->mTimeLastHelpTextChanged + kHelpTextInterval < this->mTimeOfLastUpdate)))
{
theHelpTextLabel->setVisible(false);
//theRefundTextLabel->setVisible(false);
}
// Display action button tool tip

View file

@ -241,7 +241,7 @@ public:
AvHPlayMode GetPlayMode(void) const;
bool GetAlienHelpForMessage(int inMessageID, string& outHelpText, int& outPointCost) const;
bool GetDoesPlayerHaveOrder() const;
bool GetHelpForMessage(int inMessageID, string& outHelpText) const;
bool GetHelpForMessage(int inMessageID, string& outHelpText, string& outCostAndTimeText) const;
bool GetInTopDownMode() const;
bool GetIsSelecting() const;
OrderListType GetOrderList() const;
@ -334,6 +334,7 @@ public:
int GetLocalUpgrades() const;
string GetNameOfLocation(vec3_t inLocation) const;
const AvHTechTree& GetTechNodes() const;
bool GetResearchInfo(AvHMessageID inMessageID, bool& outIsResearchable, int& outCost, float& outTime) const;
UIMode GetUIMode() const;
bool SwitchUIMode(UIMode inNewMode);
@ -843,6 +844,7 @@ private:
{
AvHMessageID mStructureID;
float mTime;
float mResearchTimer;
int mPlayerIndex;
Vector mLocation;
} HUDNotificationType;

View file

@ -1458,13 +1458,14 @@ void AvHHud::DrawHelpIcons()
// inDrawMode determines if we're drawing text or sprites
void AvHHud::DrawHUDStructureNotification()
{
const float kHUDStructureNotificationStartX = .02f;
const float kHUDStructureNotificationStartY = .11f;
const float kHUDStructureNotificationStartX = .01f;
const float kHUDStructureNotificationStartY = .08f;
const float kHUDStructureNotificationIconWidth = .03f;
const float kHUDStructureNotificationIconHeight = kHUDStructureNotificationIconWidth*1.333f;
const float kHUDStructureNotificationIconHorizontalSpacing = .01f;
const float kHUDStructureNotificationIconVerticalSpacing = kHUDStructureNotificationIconHorizontalSpacing*1.333f;
const float kHUDStructureNotificationMaxTextWidth = .2f;
//const float kHUDStructureNotificationMaxTextWidth = .2f;
const float kTextHeightCenteringFactor = 0.25f;
// Draw them all in order
if(this->GetIsAlive() && CVAR_GET_FLOAT(kvBuildMessages))
@ -1473,23 +1474,65 @@ void AvHHud::DrawHUDStructureNotification()
float theCurrentX = kHUDStructureNotificationStartX;
float theCurrentY = kHUDStructureNotificationStartY;
//bool inTopDown = GetInTopDownMode();
AvHTeamNumber theCurrentTeam = this->GetHUDTeam();
float kSmallScaleFactor;
//Don't make building icons smaller if alien.
(theCurrentTeam == TEAM_TWO) ? kSmallScaleFactor = 1.0f : kSmallScaleFactor = 0.75f;
const float kIconWidthSmall = kHUDStructureNotificationIconWidth * kSmallScaleFactor;
const float kIconHeightSmall = kHUDStructureNotificationIconHeight * kSmallScaleFactor;
for(StructureHUDNotificationListType::iterator theIter = this->mStructureNotificationList.begin(); theIter != this->mStructureNotificationList.end(); theIter++)
{
// Draw icon
AvHMessageID theIconTech = theIter->mStructureID;
int theFrame = 0;
this->DrawTechTreeSprite(theIconTech, theCurrentX*ScreenWidth(), theCurrentY*ScreenHeight(), kHUDStructureNotificationIconWidth*ScreenWidth(), kHUDStructureNotificationIconHeight*ScreenHeight(), theFrame);
string theLocationName = this->GetNameOfLocation(theIter->mLocation);
if(theLocationName != "")
int theStartX = (theCurrentX + kHUDStructureNotificationIconWidth + kHUDStructureNotificationIconHorizontalSpacing)*ScreenWidth();
bool isResearch = AvHSHUGetIsResearchTech(theIconTech);
//Don't draw cancel notifications. Still getting sent them in UpdateStructureNotification so they can be read to remove research.
if (theIconTech != MESSAGE_CANCEL)
{
int theStartX = (theCurrentX + kHUDStructureNotificationIconWidth + kHUDStructureNotificationIconHorizontalSpacing)*ScreenWidth();
this->DrawTranslatedString(theStartX, theCurrentY*ScreenHeight(), theLocationName.c_str(), false, true);
if (isResearch)
{
string theResearchTimerText;
ActionButton::GetLabelForMessage(theIter->mStructureID, theResearchTimerText);
int timeLeft = theIter->mResearchTimer;
int theMinutesLeft = timeLeft / 60;
int theSecondsLeft = timeLeft % 60;
if (theMinutesLeft)
theResearchTimerText += " - " + MakeStringFromInt(theMinutesLeft) + "m " + MakeStringFromInt(theSecondsLeft) + "s";
else
theResearchTimerText += " - " + MakeStringFromInt(theSecondsLeft) + "s";
int theR, theG, theB;
this->GetPrimaryHudColor(theR, theG, theB, true, false);
char theCharBuffer[512];
sprintf(theCharBuffer, "%s", theResearchTimerText.c_str());
float theCurrentTextY = theCurrentY + (kHUDStructureNotificationIconHeight * kTextHeightCenteringFactor);
this->DrawTechTreeSprite(theIconTech, theCurrentX*ScreenWidth(), theCurrentY*ScreenHeight(), kHUDStructureNotificationIconWidth*ScreenWidth(), kHUDStructureNotificationIconHeight*ScreenHeight(), theFrame);
this->DrawHudString(theStartX, theCurrentTextY*ScreenHeight(), ScreenWidth(), theCharBuffer, theR, theG, theB);
}
else
{
this->DrawTechTreeSprite(theIconTech, theCurrentX*ScreenWidth(), theCurrentY*ScreenHeight(), kIconWidthSmall*ScreenWidth(), kIconHeightSmall*ScreenHeight(), theFrame);
int theStartXsmall = theStartX * kSmallScaleFactor;
float theCurrentTextY = theCurrentY + (kIconHeightSmall * kTextHeightCenteringFactor);
if (theLocationName != "")
this->DrawTranslatedString(theStartXsmall, theCurrentTextY*ScreenHeight(), theLocationName.c_str(), false, true);
}
// Increment coords
theCurrentY += (kHUDStructureNotificationIconHeight + kHUDStructureNotificationIconVerticalSpacing);
}
// Increment coords
theCurrentY += (kHUDStructureNotificationIconHeight + kHUDStructureNotificationIconVerticalSpacing);
}
}
@ -2493,6 +2536,9 @@ void AvHHud::DrawBuildHealthEffectsForEntity(int inEntityIndex, float inAlpha)
// It's a friendly entity and we're a builder OR
(theIsOnOurTeam && (this->GetHUDUser3() == AVH_USER3_ALIEN_PLAYER2)) ||
// It's a friendly player with <95% armor and we have a welder in our inventory OR
(theIsOnOurTeam && theEntityIsPlayer && theHealthPercentage < 0.95f && this->mHasWelder) ||
// welder/healing spray is selected
(this->mCurrentWeaponID == 18 || this->mCurrentWeaponID == 27)

View file

@ -4958,11 +4958,11 @@ void AvHPlayer::PlayHUDStructureNotification(AvHMessageID inMessageID, const Vec
// This player built a structure. Tell all his teammates
FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*)
if(theEntity->GetIsRelevant() && !theEntity->GetIsBeingDigested())
{
//if(theEntity->GetIsRelevant() && !theEntity->GetIsBeingDigested())
//{
// Don't send our own messages to ourself unless cheats are enabled
if(GetGameRules()->GetCheatsEnabled() || (this != theEntity))
{
//if(GetGameRules()->GetCheatsEnabled() || (this != theEntity))
//{
bool theShowNotification = false;
// Show to friendlies...
@ -4975,8 +4975,8 @@ void AvHPlayer::PlayHUDStructureNotification(AvHMessageID inMessageID, const Vec
{
NetMsg_PlayHUDNotification( theEntity->pev, 1, inMessageID, inLocation.x, inLocation.y );
}
}
}
// }
//}
END_FOR_ALL_ENTITIES(kAvHPlayerClassName);
}
}
@ -5354,6 +5354,8 @@ void AvHPlayer::Research(AvHMessageID inUpgrade, int inEntityIndex)
theRefund = min(theRefund, (float)theResearchCost);
this->SetResources(this->GetResources() + theRefund);
}
//Tell team about cancel so it can update research notifications
this->PlayHUDStructureNotification(inUpgrade, theEntity->pev->origin);
char* theResearchName = NULL;
if(AvHSHUGetResearchTechName(inUpgrade, theResearchName))