mirror of
https://github.com/ENSL/NS.git
synced 2024-11-26 06:20:57 +00:00
4f13237895
Change CRLF to LF in repo.
650 lines
16 KiB
C++
650 lines
16 KiB
C++
//======== (C) Copyright 2001 Charles G. Cleveland All rights reserved. =========
|
|
//
|
|
// The copyright to the contents herein is the property of Charles G. Cleveland.
|
|
// The contents may be used and/or copied only with the written permission of
|
|
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
|
|
// the agreement/contract under which the contents have been supplied.
|
|
//
|
|
// Purpose: Pop-up context sensitive help ("there's an active hive nearby...destroy it!")
|
|
//
|
|
// $Workfile: AvHHelp.cpp $
|
|
// $Date: 2002/10/24 21:25:58 $
|
|
//
|
|
//-------------------------------------------------------------------------------
|
|
// $Log: AvHHelp.cpp,v $
|
|
// Revision 1.17 2002/10/24 21:25:58 Flayra
|
|
// - Completely reworked help to be client-side
|
|
//
|
|
// Revision 1.16 2002/10/03 18:49:57 Flayra
|
|
// - Play game objective hints
|
|
//
|
|
// Revision 1.15 2002/09/25 20:45:02 Flayra
|
|
// - Only emit phase gate message when built
|
|
// - Removed use order
|
|
// - Frame-rate independent updating
|
|
//
|
|
// Revision 1.14 2002/08/31 18:01:01 Flayra
|
|
// - Work at VALVe
|
|
//
|
|
// Revision 1.13 2002/08/02 22:51:17 Flayra
|
|
// - Don't show pop-up menu help for commander
|
|
//
|
|
// Revision 1.12 2002/08/02 21:59:55 Flayra
|
|
// - Tons of new help messages for new tooltip system
|
|
//
|
|
// Revision 1.11 2002/07/25 16:57:59 flayra
|
|
// - Linux changes
|
|
//
|
|
// Revision 1.10 2002/07/24 18:45:41 Flayra
|
|
// - Linux and scripting changes
|
|
//
|
|
// Revision 1.9 2002/06/25 17:59:39 Flayra
|
|
// - Removed help for building gun, renamed arsenal to armory
|
|
//
|
|
// Revision 1.8 2002/06/03 16:46:02 Flayra
|
|
// - Help for arsenal, help for alien building secondary functions (help me, I need to be rewritten!)
|
|
//
|
|
// Revision 1.7 2002/05/23 02:33:42 Flayra
|
|
// - Post-crash checkin. Restored @Backup from around 4/16. Contains changes for last four weeks of development.
|
|
//
|
|
// Revision 1.8 2002/05/14 19:24:16 Charlie
|
|
//===============================================================================
|
|
#include "AvHHud.h"
|
|
#include "AvHTitles.h"
|
|
#include "AvHBasePlayerWeaponConstants.h"
|
|
#include "AvHClientVariables.h"
|
|
#include "AvHServerVariables.h"
|
|
|
|
#include "../common/const.h"
|
|
#include "../common/event_api.h"
|
|
#include "../pm_shared/pm_defs.h"
|
|
#include "../pm_shared/pm_shared.h"
|
|
#include "../pm_shared/pm_movevars.h"
|
|
#include "cl_dll/cl_util.h"
|
|
|
|
bool AvHHud::ProcessEntityHelp()
|
|
{
|
|
bool theDisplayedTooltip = false;
|
|
|
|
int theNumCommandersOnTeam = (this->GetCommanderIndex() > 0) ? 1 : 0;
|
|
bool theIsCommander = (this->GetHUDUser3() == AVH_USER3_COMMANDER_PLAYER);
|
|
bool theIsInTrainingMode = false;
|
|
|
|
if(this->GetIsCombatMode())
|
|
{
|
|
// TODO: Add combat mode tooltips
|
|
}
|
|
else if(!theIsInTrainingMode)
|
|
{
|
|
for(EntityListType::iterator theHelpIter = this->mHelpEnts.begin(); (theHelpIter != this->mHelpEnts.end()) && !theDisplayedTooltip ; theHelpIter++)
|
|
{
|
|
bool theEntityIsFriendly = false;
|
|
bool theEntityIsEnemy = false;
|
|
|
|
physent_t* theEntity = gEngfuncs.pEventAPI->EV_GetPhysent(*theHelpIter);
|
|
if(theEntity)
|
|
{
|
|
bool theIsBuildable = GetHasUpgrade(theEntity->iuser4, MASK_BUILDABLE);
|
|
bool theIsBuilt = !theIsBuildable;
|
|
|
|
int theUser3 = theEntity->iuser3;
|
|
|
|
if(theEntity->team == this->GetHUDTeam())
|
|
{
|
|
theEntityIsFriendly = true;
|
|
}
|
|
else if(theEntity->team != 0)
|
|
{
|
|
theEntityIsEnemy = true;
|
|
}
|
|
|
|
// Handle commander separately
|
|
if(theIsCommander)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
// TODO: Make sure we're facing it?
|
|
|
|
// If the team has no commander, and this player is near his team's command station
|
|
if(theUser3 == AVH_USER3_COMMANDER_STATION)
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
if(theNumCommandersOnTeam == 0)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextCSAttractMode))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextAttackNearbyStation))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Check if there are any non fully built buildings on our team (this gets turrets and siege turrets of course)
|
|
if((theUser3 == AVH_USER3_TURRET) || (theUser3 == AVH_USER3_SIEGETURRET))
|
|
{
|
|
if(theIsBuildable && theEntityIsFriendly)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextBuildTurret))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Near an armory? Tell player about getting ammo from it.
|
|
if(theUser3 == AVH_USER3_ARMORY)
|
|
{
|
|
if(!theIsBuildable && theEntityIsFriendly)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextArmoryResupply))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if(theUser3 == AVH_USER3_RESTOWER)
|
|
{
|
|
if(!theEntityIsFriendly)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextAttackTower))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
else if(theIsBuildable)
|
|
{
|
|
this->AddTooltip(kHelpTextBuildTower);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextExplainTower))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Near a phase gate?
|
|
if((theUser3 == AVH_USER3_PHASEGATE) && theIsBuilt)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextPhaseGate))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Hive?
|
|
if((theUser3 == AVH_USER3_HIVE) && (theEntity->team != 0))
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
}
|
|
else if(theEntityIsEnemy)
|
|
{
|
|
this->AddTooltip(kHelpTextAttackNearbyHive);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// If we're near an unbuilt alien structure, tell the player how to build it
|
|
if((this->GetHUDUser3() == AVH_USER3_ALIEN_PLAYER2) && theIsBuildable && theEntityIsFriendly)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextAlienEnergy))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Movement chamber
|
|
if((theUser3 == AVH_USER3_MOVEMENT_CHAMBER) && theIsBuilt)
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
this->AddTooltip(kHelpTextFriendlyMovementChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
else if(theEntityIsEnemy)
|
|
{
|
|
this->AddTooltip(kHelpTextAttackMovementChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Defensive chamber
|
|
if((theUser3 == AVH_USER3_DEFENSE_CHAMBER) && theIsBuilt)
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
this->AddTooltip(kHelpTextFriendlyDefensiveChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
else if(theEntityIsEnemy)
|
|
{
|
|
this->AddTooltip(kHelpTextAttackDefensiveChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Sensory chamber
|
|
if((theUser3 == AVH_USER3_SENSORY_CHAMBER) && theIsBuilt)
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
this->AddTooltip(kHelpTextFriendlySensoryChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
else if(theEntityIsEnemy)
|
|
{
|
|
this->AddTooltip(kHelpTextAttackSensoryChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Offensive chamber
|
|
if((theUser3 == AVH_USER3_OFFENSE_CHAMBER) && theIsBuilt)
|
|
{
|
|
if(theEntityIsFriendly)
|
|
{
|
|
this->AddTooltip(kHelpTextFriendlyOffensiveChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
else if(theEntityIsEnemy)
|
|
{
|
|
this->AddTooltip(kHelpTextAttackOffensiveChamber);
|
|
theDisplayedTooltip = true;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// if(this->GetIsMarine())
|
|
// {
|
|
// if(theWeldable && theWeldable->GetCanBeWelded() && (theWeldable->GetNormalizedBuildPercentage() < 1.0f))
|
|
// {
|
|
// if(theWeldable->GetWeldOpens())
|
|
// {
|
|
// if(this->AddTooltip(kHelpTextOpenWeldable))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// if(this->AddTooltip(kHelpTextCloseWeldable))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return theDisplayedTooltip;
|
|
}
|
|
|
|
bool AvHHud::ProcessGeneralHelp()
|
|
{
|
|
const float kTimeBeforeUpgradeHelp = 500;
|
|
const float kTimeBeforeLifeformHelp = 200;
|
|
|
|
int theTimeSinceGameStarted = this->GetGameTime();
|
|
bool theDisplayedTooltip = false;
|
|
|
|
if(!theDisplayedTooltip && this->AddTooltipOnce(kHelpTextPopupMenu))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
// Don't send these messages until the game has been going for a bit...don't want to overwhelm players
|
|
else if(!theDisplayedTooltip && this->GetIsAlien() && (theTimeSinceGameStarted > kTimeBeforeLifeformHelp) && this->AddTooltipOnce(kHelpTextBuyLifeform))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->GetHasJetpack() && !this->GetIsInTopDownMode() && this->AddTooltipOnce(kHelpTextJetpacks))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->GetIsAlien() && this->AddTooltipOnce(kHelpTextAlienPopupMenu))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->GetIsMarine() && !this->GetIsInTopDownMode() && this->AddTooltipOnce(kHelpTextMarinePopupMenu))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextDisableHelp))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
// Else if we have an order
|
|
else if(this->GetDoesPlayerHaveOrder() && this->AddTooltipOnce(kHelpTextOrder))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
|
|
return theDisplayedTooltip;
|
|
}
|
|
|
|
bool AvHHud::ProcessWeaponsHelp()
|
|
{
|
|
bool theDisplayedTooltip = false;
|
|
|
|
if((this->mCurrentWeaponID >= 0) && this->mCurrentWeaponEnabled)
|
|
{
|
|
if(!theDisplayedTooltip && (this->mCurrentWeaponID == AVH_WEAPON_BITE))
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextBite))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
}
|
|
if(!theDisplayedTooltip && (this->mCurrentWeaponID == AVH_WEAPON_WEBSPINNER))
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextWeb))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
}
|
|
if(!theDisplayedTooltip && (this->mCurrentWeaponID == AVH_WEAPON_SPORES))
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextSpores))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return theDisplayedTooltip;
|
|
}
|
|
|
|
bool AvHHud::ProcessAlienHelp()
|
|
{
|
|
bool theDisplayedTooltip = false;
|
|
|
|
// Have we explained resources?
|
|
if(this->AddTooltipOnce(kHelpTextAlienWeapons))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextAlienResources))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
// Have we explained energy?
|
|
else if(this->AddTooltipOnce(kHelpTextAlienEnergy))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
// Do we have upgrades pending?
|
|
else if(this->GetHasAlienUpgradesAvailable())
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextAlienPendingUpgrades))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextAlienHiveSight))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextAlienVisionMode))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
}
|
|
|
|
if(!theDisplayedTooltip)
|
|
{
|
|
switch(this->GetHUDUser3())
|
|
{
|
|
// If we're a level 1 alien and we're holding crouch, tell them they can wall-walk
|
|
case AVH_USER3_ALIEN_PLAYER1:
|
|
if(this->AddTooltipOnce(kHelpTextWallwalking))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
// TODO: More level 1 help here
|
|
break;
|
|
|
|
case AVH_USER3_ALIEN_PLAYER2:
|
|
if(this->AddTooltipOnce(kHelpTextBuilder))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
if(this->AddTooltipOnce(kHelpTextAlienBuildStructure))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case AVH_USER3_ALIEN_PLAYER3:
|
|
// If level 3 jumps, tell player about flying
|
|
if(this->AddTooltipOnce(kHelpTextFlight))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
// TODO: More level 3 help here
|
|
break;
|
|
|
|
case AVH_USER3_ALIEN_PLAYER4:
|
|
break;
|
|
|
|
case AVH_USER3_ALIEN_PLAYER5:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return theDisplayedTooltip;
|
|
}
|
|
|
|
bool AvHHud::ProcessOrderHelp()
|
|
{
|
|
bool theDisplayedTooltip = false;
|
|
|
|
// vec3_t theOrderPosition;
|
|
// int theEntIndex = -1;
|
|
// AvHUser3 theUser3 = AVH_USER3_NONE;
|
|
//
|
|
// AvHOrderType theOrder = AvHGetDefaultOrderType(this->GetTeam(), this->GetVisualOrigin(), this->mMouseWorldPos, theEntIndex, theOrderPosition, theUser3);
|
|
// if(theOrder == ORDERTYPET_BUILD)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderBuild))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
//// else if(theOrder == ORDERTYPEL_USE)
|
|
//// {
|
|
//// if(this->AddTooltipOnce(kHelpTextCommanderUse))
|
|
//// {
|
|
//// theDisplayedTooltip = true;
|
|
//// }
|
|
//// }
|
|
// else if(theOrder == ORDERTYPET_ATTACK)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderAttack))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// else if(theOrder == ORDERTYPET_WELD)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderWeld))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// else if(theOrder == ORDERTYPET_GET)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderGet))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
|
|
return theDisplayedTooltip;
|
|
}
|
|
|
|
void AvHHud::UpdateHelpText()
|
|
{
|
|
const float kHelpTextInterval = 20.0f;
|
|
bool theDisplayedTooltip = false;
|
|
|
|
bool theIsCommander = (this->GetHUDUser3() == AVH_USER3_COMMANDER_PLAYER);
|
|
bool theIsAlien = this->GetIsAlien();
|
|
|
|
bool theAutoHelpEnabled = gEngfuncs.pfnGetCvarFloat(kvAutoHelp);
|
|
|
|
if(theAutoHelpEnabled)
|
|
{
|
|
// Has it been a little bit since we sent the last help message?
|
|
if((this->mTimeOfLastHelpText == -1) || (this->mTimeOfLastHelpText + kHelpTextInterval < gEngfuncs.GetClientTime()))
|
|
{
|
|
if(this->GetIsRelevant() && this->GetGameStarted() && !this->GetIsCombatMode())
|
|
{
|
|
// Process general help first
|
|
theDisplayedTooltip = this->ProcessGeneralHelp();
|
|
if(!theDisplayedTooltip)
|
|
{
|
|
theDisplayedTooltip = this->ProcessWeaponsHelp();
|
|
if(!theDisplayedTooltip)
|
|
{
|
|
// Search around us
|
|
theDisplayedTooltip = this->ProcessEntityHelp();
|
|
|
|
// If there is nothing around us to trigger something
|
|
if(!theDisplayedTooltip)
|
|
{
|
|
// If we are alien and a friendly hive is being attacked
|
|
//kHelpTextHiveAttacked
|
|
|
|
// AvHAlertType theAlertType;
|
|
// float theTimeOfLastAlert = theTeam->GetLastAlertTime(-1, &theAlertType);
|
|
// if(theTimeOfLastAlert > 0)
|
|
// {
|
|
// if(theIsAlien && (theAlertType == ALERT_UNDER_ATTACK))
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextAlienUnderAttack))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// else if(theIsCommander)
|
|
// {
|
|
// if(theAlertType == ALERT_UNDER_ATTACK)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderUnderAttack))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// }
|
|
// else if(theAlertType == ALERT_RESEARCH_COMPLETE)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderResearchComplete))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// else if(theAlertType == ALERT_UPGRADE_COMPLETE)
|
|
// {
|
|
// if(this->AddTooltipOnce(kHelpTextCommanderUpgradeComplete))
|
|
// {
|
|
// theDisplayedTooltip = true;
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
if(!theDisplayedTooltip)
|
|
{
|
|
// If the player has never used the command menu
|
|
//kHelpTextMarineCommandMenu
|
|
//kHelpTextAlienCommandMenu
|
|
switch(this->GetHUDUser3())
|
|
{
|
|
case AVH_USER3_MARINE_PLAYER:
|
|
//if(this->AddTooltipOnce(kHelpTextPopupMenu))
|
|
//{
|
|
// theDisplayedTooltip = true;
|
|
//}
|
|
break;
|
|
|
|
case AVH_USER3_COMMANDER_PLAYER:
|
|
if(this->mSelected.size() > 0)
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextCommanderGiveOrders))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(this->AddTooltipOnce(kHelpTextCommanderSelectPlayers))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
else if(this->AddTooltipOnce(kHelpTextCommanderLogout))
|
|
{
|
|
theDisplayedTooltip = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
theDisplayedTooltip = this->ProcessOrderHelp();
|
|
break;
|
|
|
|
case AVH_USER3_ALIEN_PLAYER1:
|
|
case AVH_USER3_ALIEN_PLAYER2:
|
|
case AVH_USER3_ALIEN_PLAYER3:
|
|
case AVH_USER3_ALIEN_PLAYER4:
|
|
case AVH_USER3_ALIEN_PLAYER5:
|
|
theDisplayedTooltip = this->ProcessAlienHelp();
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(theDisplayedTooltip)
|
|
{
|
|
this->mTimeOfLastHelpText = gEngfuncs.GetClientTime();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|