summaryrefslogtreecommitdiff
path: root/game/shared/econ/econ_entity_creation.cpp
blob: 246100503f3fe85a1b0204acd08c8ad5adead03f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
//=============================================================================

#include "cbase.h"
#include "econ_entity_creation.h"
#include "utldict.h"
#include "filesystem.h"
#include "gamestringpool.h"
#include "KeyValues.h"
#include "attribute_manager.h"
#include "vgui/ILocalize.h"
#include "tier3/tier3.h"
#include "util_shared.h"

#ifdef TF_CLIENT_DLL
#include "c_tf_player.h"
#endif // TF_CLIENT_DLL

//==================================================================================
// GENERATION SYSTEM
//==================================================================================
CItemGeneration g_ItemGenerationSystem;
CItemGeneration *ItemGeneration( void )
{
	return &g_ItemGenerationSystem;
}

//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CItemGeneration::CItemGeneration( void )
{
}

//-----------------------------------------------------------------------------
// Purpose: Generate a random item matching the specified criteria
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::GenerateRandomItem( CItemSelectionCriteria *pCriteria, const Vector &vecOrigin, const QAngle &vecAngles )
{
	entityquality_t iQuality;
	int iChosenItem = ItemSystem()->GenerateRandomItem( pCriteria, &iQuality );
	if ( iChosenItem == INVALID_ITEM_DEF_INDEX )
		return NULL;

	return SpawnItem( iChosenItem, vecOrigin, vecAngles, pCriteria->GetItemLevel(), iQuality, NULL );
}

//-----------------------------------------------------------------------------
// Purpose: Generate a random item matching the specified definition index
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::GenerateItemFromDefIndex( int iDefIndex, const Vector &vecOrigin, const QAngle &vecAngles )
{
	return SpawnItem( iDefIndex, vecOrigin, vecAngles, 1, AE_UNIQUE, NULL );
}

//-----------------------------------------------------------------------------
// Purpose: Generate an item from the specified item data
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::GenerateItemFromScriptData( const CEconItemView *pData, const Vector &vecOrigin, const QAngle &vecAngles, const char *pszOverrideClassName )
{
	return SpawnItem( pData, vecOrigin, vecAngles, pszOverrideClassName );
}

//-----------------------------------------------------------------------------
// Purpose: Generate the base item for a class's loadout slot 
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::GenerateBaseItem( struct baseitemcriteria_t *pCriteria )
{
	int iChosenItem = ItemSystem()->GenerateBaseItem( pCriteria );
	if ( iChosenItem == INVALID_ITEM_DEF_INDEX )
		return NULL;

	return SpawnItem( iChosenItem, vec3_origin, vec3_angle, 1, AE_NORMAL, NULL );
}

//-----------------------------------------------------------------------------
// Purpose: Create a new instance of the chosen item
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::SpawnItem( int iChosenItem, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, int iItemLevel, entityquality_t entityQuality, const char *pszOverrideClassName )
{
	CEconItemDefinition *pData = ItemSystem()->GetStaticDataForItemByDefIndex( iChosenItem );
	if ( !pData )
		return NULL;

	if ( !pszOverrideClassName )
	{
		pszOverrideClassName = pData->GetItemClass();
	}

	if ( !pszOverrideClassName )
		return NULL;

	CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
	if ( !pItem )
		return NULL;

	// Set the item level & quality
	IHasAttributes *pItemInterface = GetAttribInterface( pItem );
	Assert( pItemInterface );
	if ( pItemInterface )
	{
		// Setup the script item. Don't generate attributes here, because it'll be done during entity spawn.
		CEconItemView *pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
		pScriptItem->Init( iChosenItem, entityQuality, iItemLevel, false );
	}

	return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
}

//-----------------------------------------------------------------------------
// Purpose: Create a base entity for the specified item data
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::SpawnItem( const CEconItemView *pData, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles, const char *pszOverrideClassName )
{
	if ( !pData->GetStaticData() )
		return NULL;

	if ( !pszOverrideClassName )
	{
		pszOverrideClassName = pData->GetStaticData()->GetItemClass();
	}

	if ( !pszOverrideClassName )
		return NULL;

	CBaseEntity *pItem = CreateEntityByName( pszOverrideClassName );
	if ( !pItem )
		return NULL;

	// Set the item level & quality
	IHasAttributes *pItemInterface = GetAttribInterface( pItem );
	Assert( pItemInterface );
	if ( pItemInterface )
	{
		pItemInterface->GetAttributeContainer()->SetItem( pData );
	}

	return PostSpawnItem( pItem, pItemInterface, vecAbsOrigin, vecAbsAngles );
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CBaseEntity *CItemGeneration::PostSpawnItem( CBaseEntity *pItem, IHasAttributes *pItemInterface, const Vector &vecAbsOrigin, const QAngle &vecAbsAngles )
{
#ifdef CLIENT_DLL
	const char *pszPlayerModel = NULL;
	if ( pItemInterface )
	{
		CEconItemView *pScriptItem = pItemInterface->GetAttributeContainer()->GetItem();
		
		int iClass = 0;
		int iTeam = 0;
#ifdef TF_CLIENT_DLL
		C_TFPlayer *pTFPlayer = ToTFPlayer( GetPlayerByAccountID( pScriptItem->GetAccountID() ) );
		if ( pTFPlayer )
		{
			iClass = pTFPlayer->GetPlayerClass()->GetClassIndex();
			iTeam = pTFPlayer->GetTeamNumber();
		}
#endif // TF_CLIENT_DLL
		pszPlayerModel = pScriptItem->GetPlayerDisplayModel( iClass, iTeam );
	}

	// If we create a clientside item, we need to force it to initialize attributes
	if ( pItem->InitializeAsClientEntity( pszPlayerModel, RENDER_GROUP_OPAQUE_ENTITY ) == false )
		return NULL;
#endif // CLIENT_DLL

	pItem->SetAbsOrigin( vecAbsOrigin );
	pItem->SetAbsAngles( vecAbsAngles );

	pItem->Spawn();
	pItem->Activate();
	return pItem;
}