diff --git a/main/source/cl_dll/cdll_int.cpp b/main/source/cl_dll/cdll_int.cpp index cfc1fc5..dd018c3 100644 --- a/main/source/cl_dll/cdll_int.cpp +++ b/main/source/cl_dll/cdll_int.cpp @@ -360,7 +360,7 @@ HUD_VoiceStatus void CL_DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking) { RecClVoiceStatus(entindex, bTalking); - + GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking); } diff --git a/main/source/game_shared/voice_status.cpp b/main/source/game_shared/voice_status.cpp index e963802..8295caa 100644 --- a/main/source/game_shared/voice_status.cpp +++ b/main/source/game_shared/voice_status.cpp @@ -333,9 +333,10 @@ void CVoiceStatus::CreateEntities() int iOutModel = 0; for(int i=0; i < VOICE_MAX_PLAYERS; i++) { + if(!m_VoicePlayers[i]) continue; - + cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1); // Don't show an icon if the player is not in our PVS. @@ -360,7 +361,13 @@ void CVoiceStatus::CreateEntities() pEnt->baseline.renderamt = 255; pEnt->curstate.renderfx = kRenderFxNoDissipation; pEnt->curstate.framerate = 1; - pEnt->curstate.frame = 0; + // tankefugl: different sprite for each team + if (pClient->curstate.team <= SPR_Frames(m_VoiceHeadModel)) + pEnt->curstate.frame = pClient->curstate.team; + else + pEnt->curstate.frame = 0; + //pEnt->curstate.frame = 0; + // :tankefugl pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel); pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0; pEnt->curstate.scale = 0.5f; @@ -388,6 +395,7 @@ void CVoiceStatus::UpdateSpeakerStatus(int entindex, qboolean bTalking) gEngfuncs.pfnConsolePrint( msg ); } + gEngfuncs.Con_Printf("\n"); // Is it the local player talking? if( entindex == -1 ) { @@ -726,9 +734,11 @@ void CVoiceStatus::RepositionLabels() y += bgTall + 2; } - if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) ) { + if (m_pParentPanel) { + int z = 3; + } m_pLocalLabel->setParent(*m_pParentPanel); m_pLocalLabel->setVisible( true ); diff --git a/main/source/mod/AvHHud.cpp b/main/source/mod/AvHHud.cpp index 0421c84..0bc8713 100644 --- a/main/source/mod/AvHHud.cpp +++ b/main/source/mod/AvHHud.cpp @@ -646,6 +646,10 @@ void AvHHud::ClearData() this->mCurrentGhostIsValid = false; this->mAmbientSounds.clear(); + + // tankefugl: 0000971 + this->mTeammateOrder.clear(); + // :tankefugl } @@ -2035,32 +2039,42 @@ void AvHHud::OrderNotification(const AvHOrder& inOrder) // Do a switch on the order type AvHOrderType theOrderType = inOrder.GetOrderType(); AvHHUDSound theSound = HUD_SOUND_INVALID; - + + // tankefugl: 0000992 + // popup indicator for order + bool thePopup = false; + // Play HUD sound depending on order switch(theOrderType) { case ORDERTYPEL_MOVE: theSound = HUD_SOUND_ORDER_MOVE; + thePopup = true; break; case ORDERTYPET_ATTACK: theSound = HUD_SOUND_ORDER_ATTACK; + thePopup = true; break; case ORDERTYPET_BUILD: theSound = HUD_SOUND_ORDER_BUILD; + thePopup = true; break; case ORDERTYPET_GUARD: theSound = HUD_SOUND_ORDER_GUARD; + thePopup = true; break; case ORDERTYPET_WELD: theSound = HUD_SOUND_ORDER_WELD; + thePopup = true; break; case ORDERTYPET_GET: theSound = HUD_SOUND_ORDER_GET; + thePopup = true; break; } @@ -2070,6 +2084,13 @@ void AvHHud::OrderNotification(const AvHOrder& inOrder) } this->PlayHUDSound(theSound); + + // tankefugl: 0000992 + if (thePopup) + { + this->SetDisplayOrder(2, this->GetFrameForOrderType(theOrderType), "", "", ""); + } + // :tankefugl } //} } @@ -2289,6 +2310,83 @@ int AvHHud::MiniMap(const char* pszName, int iSize, void* pbuf) return 1; } +// tankefugl: 0000971 +BIND_MESSAGE(IssueOrder); +int AvHHud::IssueOrder(const char* pszName, int iSize, void* pbuf) +{ + int ordertype, ordersource, ordertarget; + NetMsg_IssueOrder( pbuf, iSize, ordertype, ordersource, ordertarget); + + float now = this->GetTimeOfLastUpdate(); + TeammateOrderListType::iterator theIter = this->mTeammateOrder.find(ordersource); + if (theIter == this->mTeammateOrder.end()) + { + this->mTeammateOrder.insert(theIter, pair(ordersource, TeammateOrderType(ordertype, now))); + } + else + { + TeammateOrderType *theOrder = &((*theIter).second); + (*theOrder).first = ordertype; + (*theOrder).second = now; + } + + if (this->GetInTopDownMode() == false) + { + cl_entity_s* theLocalPlayer = gEngfuncs.GetLocalPlayer(); + if (theLocalPlayer->index == ordertarget) + { + hud_player_info_t info; + memset(&info, 0, sizeof(info)); + GetPlayerInfo(ordersource, &info); + + string temp; + string nameFormat; + // TODO: fetch from titles.txt + switch (ordertype) { + case TEAMMATE_MARINE_ORDER_WELD: + nameFormat = "Weld %s"; + break; + case TEAMMATE_MARINE_ORDER_FOLLOW: + nameFormat = "Follow %s"; + break; + case TEAMMATE_MARINE_ORDER_COVER: + nameFormat = "%s is covering"; + break; + case TEAMMATE_MARINE_ORDER_UNKNOWN: + nameFormat = "%s"; + break; + case TEAMMATE_ALIEN_ORDER_HEAL: + nameFormat = "Heal %s"; + break; + case TEAMMATE_ALIEN_ORDER_FOLLOW: + nameFormat = "Follow %s"; + break; + case TEAMMATE_ALIEN_ORDER_COVER: + nameFormat = "%s is covering"; + break; + case TEAMMATE_ALIEN_ORDER_UNKNOWN: + nameFormat = "%s"; + break; + } + sprintf(temp, nameFormat.c_str(), info.name); + + this->SetDisplayOrder(1, ordertype, temp, "", ""); + } + if (theLocalPlayer->index == ordersource) + { + this->mCurrentOrderTarget = ordertarget; + this->mCurrentOrderType = ordertype; + this->mCurrentOrderTime = now; + } + } + +// char temp[255]; +// sprintf(temp, "IssueOrder received - type %d source %d target %d at time %f\n", ordertype, ordersource, ordertarget, now); +// gEngfuncs.Con_Printf(temp); + + return 1; +} +// :tankefugl BIND_MESSAGE(ServerVar); int AvHHud::ServerVar(const char* pszName, int iSize, void* pbuf) @@ -2461,6 +2559,20 @@ void AvHHud::ResetGame(bool inMapChanged) this->mTimeOfLastLevelUp = -1; memset(this->mMenuImpulses, MESSAGE_NULL, sizeof(AvHMessageID)*kNumUpgradeLines); + + // tankefugl: 0000992 & 0000971 + this->mTeammateOrder.clear(); + this->mCurrentOrderTarget = 0; + this->mCurrentOrderType = 0; + this->mCurrentOrderTime = 0.0f; + + this->mDisplayOrderTime = 0.0f; + this->mDisplayOrderType = 0; + this->mDisplayOrderIndex = 0; + this->mDisplayOrderText1 = ""; + this->mDisplayOrderText2 = ""; + this->mDisplayOrderText3 = ""; + // :tankefugl } BIND_MESSAGE(SetGmma); @@ -3475,6 +3587,9 @@ void AvHHud::Init(void) HOOK_MESSAGE(AlienInfo); HOOK_MESSAGE(DebugCSP); HOOK_MESSAGE(TechSlots); + // tankefugl: 0000971 + HOOK_MESSAGE(IssueOrder); + // :tankefugl HOOK_MESSAGE(ServerVar); diff --git a/main/source/mod/AvHHudRender.cpp b/main/source/mod/AvHHudRender.cpp index f053cd1..10619cb 100644 --- a/main/source/mod/AvHHudRender.cpp +++ b/main/source/mod/AvHHudRender.cpp @@ -139,6 +139,7 @@ #include "mod/AvHSpriteAPI.h" #include "mod/AvHParticleEditorHandler.h" #include +#include "common/entity_types.h" void IN_GetMousePos( int *mx, int *my ); @@ -883,7 +884,8 @@ void AvHHud::DrawToolTips() } } -void AvHHud::DrawWorldSprite(int inSpriteHandle, int inRenderMode, vec3_t inWorldPosition, int inFrame, float inWorldSize) +void AvHHud::DrawWorldSprite(int inSpriteHandle, int inRenderMode, vec3_t inWorldPosition, int inFrame, float inWorldSize, float inAlpha) +// tankefugl: added inAlpha { vec3_t theUpperLeft; vec3_t theLowerRight; @@ -968,7 +970,7 @@ void AvHHud::DrawWorldSprite(int inSpriteHandle, int inRenderMode, vec3_t inWorl //DrawScaledHUDSprite(inSpriteHandle, inRenderMode, 1, theScreenX, theScreenY, theWidth, theHeight, inFrame); - AvHSpriteSetColor(1, 1, 1); + AvHSpriteSetColor(1, 1, 1, inAlpha); AvHSpriteSetRenderMode(inRenderMode); AvHSpriteDraw(inSpriteHandle, inFrame, theScreenX, theScreenY, theScreenX + theWidth, theScreenY + theHeight, 0, 0, 1, 1); @@ -1060,6 +1062,14 @@ void AvHHud::DrawOrderText(const AvHOrder& inOrder) string theTranslatedLocation = theLocationOfOrder; LocalizeString(theLocationOfOrder.c_str(), theTranslatedLocation); + // tankefugl: 0000992 + string theFirstLine = theLocalizedTitle; + if(theRangeDisplayString != "") + { + theFirstLine += string(" : ") + theRangeDisplayString; + } + // :tankefugl + Vector theScreenPos; if(AvHCUWorldToScreen((float*)theOrderLocation, (float*)&theScreenPos)) { @@ -1071,12 +1081,6 @@ void AvHHud::DrawOrderText(const AvHOrder& inOrder) int theR, theG, theB; this->GetPrimaryHudColor(theR, theG, theB, false, false); - string theFirstLine = theLocalizedTitle; - if(theRangeDisplayString != "") - { - theFirstLine += string(" : ") + theRangeDisplayString; - } - // Draw order (icon above world position, text below it) int theBaseX = theScreenPos.x; int theBaseY = theScreenPos.y; @@ -1087,8 +1091,181 @@ void AvHHud::DrawOrderText(const AvHOrder& inOrder) this->DrawHudStringCentered(theBaseX, theBaseY + 2*theStringHeight, ScreenWidth(), theTranslatedLocation.c_str(), theR, theG, theB); } } + // tankefugl: 0000992 + if (this->mDisplayOrderType == 2) + { + // this->mDisplayOrderText1 = "The commander issued an order:"; + this->mDisplayOrderText1 = theFirstLine.c_str(); + this->mDisplayOrderText2 = theTranslatedLocation.c_str(); + } + // :tankefugl } +// tankefugl: 0000992 +void AvHHud::SetDisplayOrder(int inOrderType, int inOrderIndex, string inText1, string inText2, string inText3) +{ + this->mDisplayOrderTime = this->mTimeOfLastUpdate; + this->mDisplayOrderType = inOrderType; + this->mDisplayOrderIndex = inOrderIndex; + this->mDisplayOrderText1 = inText1; + this->mDisplayOrderText2 = inText2; + this->mDisplayOrderText3 = inText3; +} + +void AvHHud::DrawDisplayOrder() +{ + const float flashLength = 1.0f; + const float fadeLimit = 6.0f; + const float fadeEnd = 2.0f; + + if ((this->mDisplayOrderType > 0) && (this->mDisplayOrderTime + fadeLimit + fadeEnd) > this->mTimeOfLastUpdate && (this->GetInTopDownMode() == false)) + { + float theFade = 1.0f; + if ((this->mDisplayOrderTime + fadeLimit) < this->mTimeOfLastUpdate) + { + theFade = 1.0f - (this->mTimeOfLastUpdate - (this->mDisplayOrderTime + fadeLimit)) / fadeEnd; + if(theFade < 0.0f) + { + this->mDisplayOrderType = 0; + return; + } + } + + // flash the icon for the first second + if ((this->mDisplayOrderTime + flashLength) > this->mTimeOfLastUpdate) + { + if (((int)((this->mTimeOfLastUpdate - this->mDisplayOrderTime) * 8)) % 2) + { + theFade = 0.0f; + } + } + + // draw the panel +// int sprite = Safe_SPR_Load(kWhiteSprite); + + int r, g, b; + GetPrimaryHudColor(r, g, b, true, false); + + int theStringHeight = this->GetHudStringHeight(); + +// float mSelectionBoxX1 = 0.25f * ScreenWidth(); +// float mSelectionBoxY1 = 0.08f * ScreenHeight(); +// float mSelectionBoxX2 = mSelectionBoxX1 + 0.50f * ScreenWidth(); +// float mSelectionBoxY2 = mSelectionBoxY1 + 0.08f * ScreenWidth(); + +// float mIconX1 = mSelectionBoxX1 + 0.01f * ScreenWidth(); +// float mIconY1 = mSelectionBoxY1 + 0.01f * ScreenWidth(); +// float mIconX2 = mIconX1 + 0.06f * ScreenWidth(); +// float mIconY2 = mIconY1 + 0.06f * ScreenWidth(); + +// AvHSpriteSetRenderMode(kRenderTransAdd); +// AvHSpriteSetColor(r / 255.0, g / 255.0, b / 255.0, 0.3 * theFade); +// AvHSpriteSetDrawMode(kSpriteDrawModeFilled); +// AvHSpriteDraw(sprite, 0, mSelectionBoxX1 + 1, mSelectionBoxY1 + 1, mSelectionBoxX2 - 1, mSelectionBoxY2 - 1, 0, 0, 1, 1); + +// AvHSpriteSetRenderMode(kRenderTransAdd); +// AvHSpriteSetColor(r / 255.0, g / 255.0, b / 255.0, 0.7 * theFade); +// AvHSpriteSetDrawMode(kSpriteDrawModeBorder); +// AvHSpriteDraw(sprite, 0, mSelectionBoxX1, mSelectionBoxY1, mSelectionBoxX2, mSelectionBoxY2, 0, 0, 1, 1); + + float mIconX1 = 0.45f * ScreenWidth(); + float mIconY1 = 0.10f * ScreenHeight(); + float mIconX2 = mIconX1 + 0.10f * ScreenWidth(); + float mIconY2 = mIconY1 + 0.10f * ScreenWidth(); + + float mTextX1 = 0.50f * ScreenWidth(); + + AvHSpriteSetRenderMode(kRenderTransAdd); + AvHSpriteSetDrawMode(kSpriteDrawModeFilled); + AvHSpriteSetColor(1, 1, 1, 1 * theFade); + + if (this->mDisplayOrderType == 1) + { + AvHSpriteDraw(this->mTeammateOrderSprite, this->mDisplayOrderIndex, mIconX1, mIconY1, mIconX2, mIconY2, 0, 0, 1, 1); + this->DrawHudStringCentered(mTextX1, mIconY2, ScreenWidth(), this->mDisplayOrderText1.c_str(), r, g, b); + } + else if (this->mDisplayOrderType == 2) + { + AvHSpriteDraw(this->mOrderSprite, this->mDisplayOrderIndex, mIconX1, mIconY1, mIconX2, mIconY2, 0, 0, 1, 1); + this->DrawHudStringCentered(mTextX1, mIconY2, ScreenWidth(), this->mDisplayOrderText1.c_str(), r, g, b); + this->DrawHudStringCentered(mTextX1, mIconY2 + theStringHeight, ScreenWidth(), this->mDisplayOrderText2.c_str(), r, g, b); + } + + +// float mTextX1 = mIconX2 + 0.02 * ScreenWidth(); +// this->DrawHudString(mTextX1, mIconY1, ScreenWidth(), this->mDisplayOrderText1.c_str(), r, g, b); +// this->DrawHudString(mTextX1, mIconY1 + theStringHeight, ScreenWidth(), this->mDisplayOrderText2.c_str(), r, g, b); +// this->DrawHudString(mTextX1, mIconY1 + theStringHeight * 2, ScreenWidth(), this->mDisplayOrderText3.c_str(), r, g, b); + } +} +// :tankefugl + +// tankefugl: 0000971 +void AvHHud::DrawTeammateOrders() +{ + TeammateOrderListType::iterator toErase = NULL; + cl_entity_s* theLocalPlayer = gEngfuncs.GetLocalPlayer(); + + const float flashLength = 1.0f; + const float fadeLimit = 6.0f; + const float fadeEnd = 2.0f; + + for(TeammateOrderListType::iterator theIter = this->mTeammateOrder.begin(); theIter != this->mTeammateOrder.end(); theIter++) + { + TeammateOrderType theOrder = (*theIter).second; + int theEntIndex = (*theIter).first; + float theFade = 1.0f; + + // remove the order if it has expired + if((theOrder.second + fadeEnd + fadeLimit) < this->mTimeOfLastUpdate) + { + toErase = theIter; + continue; + } + // draw the order fading away + else if((theOrder.second + fadeLimit) < this->mTimeOfLastUpdate) + { + theFade = 1.0f - (this->mTimeOfLastUpdate - (theOrder.second + fadeLimit)) / fadeEnd; + if(theFade < 0.0f) + theFade = 0.0f; + } + // else, draw the order normally + + cl_entity_s* theEntity = gEngfuncs.GetEntityByIndex(theEntIndex); + if (theEntity && (theEntIndex < MAX_PLAYERS && theEntIndex >= 0) && (theEntity->index != theLocalPlayer->index)) + { + if (AvHTraceLineAgainstWorld(theLocalPlayer->origin, theEntity->origin) == 1.0f) + { + vec3_t theVec; + VectorCopy(theEntity->origin, theVec); + theVec[2] += AvHCUGetIconHeightForPlayer((AvHUser3)theEntity->curstate.iuser3); + this->DrawWorldSprite(this->mTeammateOrderSprite, kRenderTransAdd, theVec, theOrder.first, kHelpIconDrawSize, theFade); + } + } + } + + if (toErase != NULL) + this->mTeammateOrder.erase(toErase); + + // flash target player + if (((this->mCurrentOrderTime + flashLength) > this->mTimeOfLastUpdate) && (this->mCurrentOrderTarget > 0)) + { + if (((int)((this->mTimeOfLastUpdate - (this->mCurrentOrderTime + flashLength)) * 8)) % 2) + { + cl_entity_s* theTargetEntity = gEngfuncs.GetEntityByIndex(this->mCurrentOrderTarget); + + vec3_t theVec; + VectorCopy(theTargetEntity->origin, theVec); + theVec[2] += AvHCUGetIconHeightForPlayer((AvHUser3)theTargetEntity->curstate.iuser3); + this->DrawWorldSprite(this->mTeammateOrderSprite, kRenderTransAdd, theVec, this->mCurrentOrderType, kHelpIconDrawSize, 1.0f); + + } + } + + +} +// :tankefugl + void AvHHud::DrawOrders() { if(1/*!this->mIsRenderingSelectionView*/) @@ -2531,6 +2708,11 @@ void AvHHud::RenderCommonUI() this->DrawOrders(); this->DrawHelpIcons(); + // tankefugl: 0000971 + this->DrawTeammateOrders(); + // tankefugl: 0000992 + this->DrawDisplayOrder(); + // :tankefugl if (this->GetIsCombatMode()) { @@ -3988,6 +4170,10 @@ void AvHHud::VidInit(void) string theIconName = string(kHelpIconPrefix) + ".spr"; this->mHelpSprite = Safe_SPR_Load(theIconName.c_str()); + // tankefugl: 0000971 + this->mTeammateOrderSprite = Safe_SPR_Load(kTeammateOrderSprite); + // :tankefugl + this->mEnemyBlips.VidInit(); this->mFriendlyBlips.VidInit(); } diff --git a/main/source/mod/AvHNetworkMessages.cpp b/main/source/mod/AvHNetworkMessages.cpp index 2dbe49a..08198eb 100644 --- a/main/source/mod/AvHNetworkMessages.cpp +++ b/main/source/mod/AvHNetworkMessages.cpp @@ -22,7 +22,7 @@ int g_msgAmmoPickup = 0, g_msgAmmoX, g_msgBattery, g_msgCurWeapon, g_msgDamage, g_msgServerVar, g_msgSetGammaRamp, g_msgSetOrder, g_msgSetParticleTemplates, g_msgSetSelect, g_msgSetRequest, g_msgSetSoundNames, g_msgSetTechNodes, g_msgSetTechSlots, g_msgSetTopDown, g_msgSetupMap, g_msgUpdateCountdown, g_msgUpdateEntityHierarchy, - g_msgProfileInfo, g_msgNexusBytes; + g_msgProfileInfo, g_msgNexusBytes, g_msgIssueOrder; void Net_InitializeMessages(void) { @@ -87,6 +87,9 @@ void Net_InitializeMessages(void) g_msgUpdateEntityHierarchy = REG_USER_MSG( "EntHier", -1 ); g_msgProfileInfo = REG_USER_MSG( "ProfileInfo", 8 ); g_msgNexusBytes = REG_USER_MSG( "NexusBytes", -1 ); + // tankefugl: 0000971 + g_msgIssueOrder = REG_USER_MSG( "IssueOrder", 9); + // :tankefugl } #endif @@ -2023,4 +2026,28 @@ const int kPositionNetworkConstant = 25; short_data = (index << 1) | 0; } } -#endif \ No newline at end of file +#endif + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// tankefugl: 0000971 +#ifndef AVH_SERVER + void NetMsg_IssueOrder( void* const buffer, const int size, int& ordertype, int& ordersource, int& ordertarget ) + { + BEGIN_READ( buffer, size ); + ordertype = READ_BYTE(); + ordersource = READ_LONG(); + ordertarget = READ_LONG(); + END_READ(); + } +#else + void NetMsg_IssueOrder( entvars_t* const pev, const int ordertype, const int ordersource, const int ordertarget) + { + MESSAGE_BEGIN( MSG_ONE, g_msgIssueOrder, NULL, pev ); + WRITE_BYTE( ordertype ); + WRITE_LONG( ordersource ); + WRITE_LONG( ordertarget ); + MESSAGE_END(); + } +#endif +// :tankefugl \ No newline at end of file diff --git a/main/source/mod/AvHPlayer.cpp b/main/source/mod/AvHPlayer.cpp index 0446213..c9b8c4c 100644 --- a/main/source/mod/AvHPlayer.cpp +++ b/main/source/mod/AvHPlayer.cpp @@ -1208,6 +1208,10 @@ bool AvHPlayer::ExecuteMessage(AvHMessageID inMessageID, bool inInstantaneous, b this->PayPurchaseCost(theCost); } + // tankefugl: 0000971 + int theIssuedOrderIcon = -1; + // :tankefugl + if(theIsMarine && !theIsInTopDownMode && !theIsBeingDigested) @@ -1250,6 +1254,21 @@ bool AvHPlayer::ExecuteMessage(AvHMessageID inMessageID, bool inInstantaneous, b { switch(inMessageID) { + // tankefugl: 0000971 + // decides whether icon updates should be sent + case SAYING_1: + theIssuedOrderIcon = TEAMMATE_MARINE_ORDER_FOLLOW; + break; + + case SAYING_2: + theIssuedOrderIcon = TEAMMATE_MARINE_ORDER_COVER; + break; + + case SAYING_8: + theIssuedOrderIcon = TEAMMATE_MARINE_ORDER_WELD; + break; + // :tankefugl + case SAYING_5: theAlertType = ALERT_SOLDIER_NEEDS_AMMO; theMessageID = COMMANDER_NEXTAMMO; @@ -1309,6 +1328,74 @@ bool AvHPlayer::ExecuteMessage(AvHMessageID inMessageID, bool inInstantaneous, b theMessageExecuted = true; break; } + // tankefugl: 0000971 + // decides whether icon updates should be sent + switch (inMessageID) + { + case SAYING_1: + theIssuedOrderIcon = TEAMMATE_ALIEN_ORDER_FOLLOW; + break; + case SAYING_2: + theIssuedOrderIcon = TEAMMATE_ALIEN_ORDER_COVER; + break; + case SAYING_4: + case SAYING_8: + theIssuedOrderIcon = TEAMMATE_ALIEN_ORDER_HEAL; + break; + } + // :tankefugl + } + + // tankefugl: 0000971 and 0000992 + if (theIssuedOrderIcon > -1) + { + int theOrderTarget = 0; + + vec3_t vecDir; + VectorCopy(this->GetAutoaimVector(0.0f), vecDir); + VectorNormalize(vecDir); + + FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*); + float dotResult = 0.0f; + float currentResult = 0.0f; + float theDistance = 0.0f; + vec3_t vecOrigin; + vec3_t vecDistance; + + if (theEntity->GetTeam() == this->GetTeam()) + { + VectorSubtract(theEntity->pev->origin, this->pev->origin, vecDistance); + theDistance = Length(vecDistance); + + VectorNormalize(vecDistance); + dotResult = DotProduct(vecDistance, vecDir); + if ((dotResult > 0.8f) && (dotResult > currentResult)) + { + currentResult = dotResult; + theOrderTarget = theEntity->entindex(); + } + } +// ALERT(at_console, "-------------------\n"); +// ALERT(at_console, UTIL_VarArgs("vecDir %f %f %f\n", vecDir[0], vecDir[1], vecDir[2])); +// ALERT(at_console, UTIL_VarArgs("vecDistance %f %f %f\n", vecDistance[0], vecDistance[1], vecDistance[2])); +// ALERT(at_console, UTIL_VarArgs("dotResult %f\n", dotResult)); +// ALERT(at_console, UTIL_VarArgs("currentResult %f\n", currentResult)); + END_FOR_ALL_ENTITIES(kAvHPlayerClassName); + +// ALERT(at_console, UTIL_VarArgs("theIssuedOrderIcon %d source %d target %d\n", theIssuedOrderIcon, this->entindex(), theOrderTarget)); + + FOR_ALL_ENTITIES(kAvHPlayerClassName, AvHPlayer*); + if(theEntity->GetTeam() == this->GetTeam()) + { + NetMsg_IssueOrder(theEntity->pev, theIssuedOrderIcon, this->entindex(), theOrderTarget); + } + END_FOR_ALL_ENTITIES(kAvHPlayerClassName); + + + // Send icon number only to players on the same team + // TODO 0000992: + // Perform a trace to find nearest player in crosshair + // Send issued order to found player } // Common messages here