Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,674 changes: 1,674 additions & 0 deletions includes/attribute_system.inc

Large diffs are not rendered by default.

893 changes: 893 additions & 0 deletions includes/db_manager.inc

Large diffs are not rendered by default.

763 changes: 763 additions & 0 deletions includes/event_handler.inc

Large diffs are not rendered by default.

280 changes: 280 additions & 0 deletions includes/exp_level_system.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
/**
* =============================================================================
* TF2 Level System - ๊ฒฝํ—˜์น˜/๋ ˆ๋ฒจ์—… ์‹œ์Šคํ…œ ๋ชจ๋“ˆ
* =============================================================================
*
* ์„ค๋ช…: ํ”Œ๋ ˆ์ด์–ด์˜ ๊ฒฝํ—˜์น˜ ํš๋“, ๋ ˆ๋ฒจ์—… ์ฒ˜๋ฆฌ, ๋ณด์ƒ ์ง€๊ธ‰ ๋“ฑ์„ ๊ด€๋ฆฌํ•˜๋Š” ํ•ต์‹ฌ ๋ชจ๋“ˆ
*
* ์ฃผ์š” ๊ธฐ๋Šฅ:
* - ๊ฒฝํ—˜์น˜ ํš๋“ ๋ฐ ๋ ˆ๋ฒจ์—… ์ฒ˜๋ฆฌ
* - ๋ฐ๋ฏธ์ง€ ๋ˆ„์  ์ถ”์  ๋ฐ ๋ณด์ƒ
* - ํƒ€์ด๋จธ ๊ธฐ๋ฐ˜ ๋ณด์ƒ
* - ๋ ˆ๋ฒจ์—… ์ดํŽ™ํŠธ ๋ฐ ์‚ฌ์šด๋“œ
*/

#if defined _exp_level_system_included
#endinput
#endif
#define _exp_level_system_included

// =============================================================================
// ๊ฒฝํ—˜์น˜ ํ…Œ์ด๋ธ” (๋ ˆ๋ฒจ๋‹น ํ•„์š” ๊ฒฝํ—˜์น˜)
// =============================================================================

#define EXP_TABLE_SIZE 80

// ๊ฒฝํ—˜์น˜ ํ…Œ์ด๋ธ” (80 ๋ ˆ๋ฒจ)
static const int EXP_TABLE[EXP_TABLE_SIZE] = {
25, 60, 110, 175, 250, 350, 475, 625, 800, 1000,
1225, 1475, 1750, 2050, 2375, 2725, 3100, 3500, 3925, 4375,
4850, 5350, 5875, 6425, 7000, 7600, 8225, 8875, 9550, 10250,
10975, 11725, 12500, 13300, 14125, 14975, 15850, 16750, 17675, 18625,
19600, 20600, 21625, 22675, 23750, 24850, 25975, 27125, 28300, 29500,
30750, 32050, 33400, 34800, 36250, 37750, 39300, 40900, 42550, 44250,
46000, 47800, 49650, 51550, 53500, 55500, 57550, 59650, 61800, 64000,
66250, 68550, 70900, 73300, 75750, 78250, 80800, 83400, 86050, 88750
};

// =============================================================================
// ๋ณด์ƒ ์ƒ์ˆ˜
// =============================================================================

// ํƒ€์ด๋จธ ๋ณด์ƒ (10๋ถ„๋งˆ๋‹ค)
const float REWARD_TIMER_INTERVAL = 600.0;
const int REWARD_POINT_TIMER = 100;
const int REWARD_EXP_TIMER = 50;

// ๋ฐ๋ฏธ์ง€ ๋ˆ„์  ๋ณด์ƒ (2000 ๋ฐ๋ฏธ์ง€๋งˆ๋‹ค)
const int REWARD_DAMAGE_THRESHOLD = 2000;
const int REWARD_POINT_DAMAGE = 40;
const int REWARD_EXP_DAMAGE = 20;

// ์ฒ˜์น˜ ๋ณด์ƒ
const int REWARD_POINT_KILL = 20;
const int REWARD_EXP_KILL = 20;

// ๋ ˆ๋ฒจ์—… ๋ณด์ƒ
const int REWARD_SKILLPOINT_LEVELUP = 3;

// =============================================================================
// ๋ ˆ๋ฒจ/๊ฒฝํ—˜์น˜ ๊ด€๋ฆฌ ํ•จ์ˆ˜
// =============================================================================

/**
* ํ”Œ๋ ˆ์ด์–ด์—๊ฒŒ ๊ฒฝํ—˜์น˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ ˆ๋ฒจ์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @param exp ์ถ”๊ฐ€ํ•  ๊ฒฝํ—˜์น˜
* @noreturn
*/
stock void ExpLevel_AddExp(int client, int exp)
{
if (!IsValidClient(client))
return;

playerDataList[client].exp += exp;

// ๋ ˆ๋ฒจ์—… ์ฒดํฌ
if (playerDataList[client].level < (EXP_TABLE_SIZE - 1) &&
playerDataList[client].exp >= EXP_TABLE[playerDataList[client].level])
{
// ๋‚จ์€ ๊ฒฝํ—˜์น˜ ๊ณ„์‚ฐ
int delta = playerDataList[client].exp - EXP_TABLE[playerDataList[client].level];

// ํ˜„์žฌ ๋ ˆ๋ฒจ ๊ฒฝํ—˜์น˜ ์†Œ๋ชจ
playerDataList[client].exp -= EXP_TABLE[playerDataList[client].level];

// ๋ ˆ๋ฒจ์—… ์ฒ˜๋ฆฌ
ExpLevel_ProcessLevelUp(client);

// ๋‚จ์€ ๊ฒฝํ—˜์น˜๋กœ ์žฌ๊ท€ ํ˜ธ์ถœ (์—ฐ์† ๋ ˆ๋ฒจ์—… ์ฒ˜๋ฆฌ)
if (delta > 0)
{
ExpLevel_AddExp(client, delta);
}
}
}

/**
* ํ”Œ๋ ˆ์ด์–ด์˜ ๋ ˆ๋ฒจ์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @noreturn
*/
stock void ExpLevel_ProcessLevelUp(int client)
{
if (!IsValidClient(client))
return;

// ๋ ˆ๋ฒจ ์ฆ๊ฐ€
playerDataList[client].level++;

// ์Šคํ‚ฌํฌ์ธํŠธ ๋ณด์ƒ
playerDataList[client].skillpoint += REWARD_SKILLPOINT_LEVELUP;

// ๋‹‰๋„ค์ž„ ์—…๋ฐ์ดํŠธ
ExpLevel_UpdateNickname(client);

// ์ดํŽ™ํŠธ ๋ฐ ์‚ฌ์šด๋“œ
ExpLevel_ShowLevelUpEffect(client);
ExpLevel_PlayLevelUpSound(client);

// ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€
CPrintToChat(client, "{green}[๋ ˆ๋ฒจ์—…]{default} ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค! ๋ ˆ๋ฒจ์ด ์˜ฌ๋ผ {orange}%d{default} ๋ ˆ๋ฒจ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!",
playerDataList[client].level);
}

/**
* ํ”Œ๋ ˆ์ด์–ด์—๊ฒŒ ํฌ์ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @param points ์ถ”๊ฐ€ํ•  ํฌ์ธํŠธ
* @noreturn
*/
stock void ExpLevel_AddPoints(int client, int points)
{
if (!IsValidClient(client))
return;

playerDataList[client].point += points;
}

/**
* ํŠน์ • ๋ ˆ๋ฒจ์— ํ•„์š”ํ•œ ๊ฒฝํ—˜์น˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
*
* @param level ๋ ˆ๋ฒจ (0~79)
* @return ํ•„์š” ๊ฒฝํ—˜์น˜
*/
stock int ExpLevel_GetExpForLevel(int level)
{
if (level < 0 || level >= EXP_TABLE_SIZE)
return 0;

return EXP_TABLE[level];
}

/**
* ์ตœ๋Œ€ ๋ ˆ๋ฒจ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
*
* @return ์ตœ๋Œ€ ๋ ˆ๋ฒจ
*/
stock int ExpLevel_GetMaxLevel()
{
return EXP_TABLE_SIZE;
}

// =============================================================================
// ๋ฐ๋ฏธ์ง€ ์ถ”์  ๋ฐ ๋ณด์ƒ
// =============================================================================

/**
* ํ”Œ๋ ˆ์ด์–ด์˜ ๋ฐ๋ฏธ์ง€๋ฅผ ์ถ”์ ํ•˜๊ณ  ์ž„๊ณ„๊ฐ’ ๋„๋‹ฌ ์‹œ ๋ณด์ƒ์„ ์ง€๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @param damage ๊ฐ€ํ•œ ๋ฐ๋ฏธ์ง€
* @noreturn
*/
stock void ExpLevel_TrackDamage(int client, int damage)
{
if (!IsValidClient(client))
return;

playerDataList[client].damage += damage;

// ๋ฐ๋ฏธ์ง€ ์ž„๊ณ„๊ฐ’ ๋„๋‹ฌ ์ฒดํฌ
if (playerDataList[client].damage >= REWARD_DAMAGE_THRESHOLD)
{
// ๋‹ฌ์„ฑ ํšŸ์ˆ˜ ๊ณ„์‚ฐ (์—ฌ๋Ÿฌ ๋ฒˆ ๋‹ฌ์„ฑ ๊ฐ€๋Šฅ)
int multiple = playerDataList[client].damage / REWARD_DAMAGE_THRESHOLD;

// ๋ณด์ƒ ์ง€๊ธ‰
ExpLevel_AddExp(client, REWARD_EXP_DAMAGE * multiple);
ExpLevel_AddPoints(client, REWARD_POINT_DAMAGE * multiple);

// ์ฑ„ํŒ… ๋ฉ”์‹œ์ง€
CPrintToChat(client, "{olive}[EXP&Point]{default} ๋ฐ๋ฏธ์ง€ ๋ˆ„์  ๋‹ฌ์„ฑ! {rare}[%d ๊ฒฝํ—˜์น˜]{default} {unique}[%d ํฌ์ธํŠธ]{default} ํš๋“!",
REWARD_EXP_DAMAGE * multiple, REWARD_POINT_DAMAGE * multiple);

// ์‚ฌ์šฉํ•œ ๋ฐ๋ฏธ์ง€ ์ฐจ๊ฐ
playerDataList[client].damage -= multiple * REWARD_DAMAGE_THRESHOLD;
}
}

// =============================================================================
// ๋‹‰๋„ค์ž„ ์—…๋ฐ์ดํŠธ
// =============================================================================

/**
* ํ”Œ๋ ˆ์ด์–ด์˜ ๋‹‰๋„ค์ž„์„ ํ˜„์žฌ ๋ ˆ๋ฒจ๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @noreturn
*/
stock void ExpLevel_UpdateNickname(int client)
{
if (!IsValidClient(client))
return;

char prefix[12];
char prefixName[255];

Format(prefix, sizeof(prefix), "[Lv%d]", playerDataList[client].level);
Format(prefixName, sizeof(prefixName), "%s%s", prefix, playerDataList[client].basenick);

SetClientInfo(client, "name", prefixName);
}

// =============================================================================
// ๋ ˆ๋ฒจ์—… ์ดํŽ™ํŠธ
// =============================================================================

/**
* ๋ ˆ๋ฒจ์—… ์‹œ๊ฐ ํšจ๊ณผ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @noreturn
*/
stock void ExpLevel_ShowLevelUpEffect(int client)
{
if (!IsValidClient(client))
return;

if (!IsClientInGame(client) || !IsPlayerAlive(client))
return;

// ํŒŒํ‹ฐํด ํšจ๊ณผ ํ‘œ์‹œ
AttachParticle(client, "bl_killtaunt", "head", 0.0, 0.5);
AttachParticle(client, "achieved", "head", 0.0, 0.5);
}

/**
* ๋ ˆ๋ฒจ์—… ์‚ฌ์šด๋“œ๋ฅผ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @noreturn
*/
stock void ExpLevel_PlayLevelUpSound(int client)
{
if (!IsValidClient(client))
return;

if (!IsClientInGame(client))
return;

EmitSoundToClient(client, "misc/achievement_earned.wav", _, _, SNDLEVEL_RAIDSIREN);
}

// =============================================================================
// ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜
// =============================================================================

/**
* ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์œ ํšจํ•œ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
*
* @param client ํด๋ผ์ด์–ธํŠธ ์ธ๋ฑ์Šค
* @return ์œ ํšจํ•˜๋ฉด true
*/
stock bool IsValidClient(int client)
{
return (client > 0 && client <= MaxClients && IsClientInGame(client) && !IsFakeClient(client));
}
Loading