forked from metin2/server
970 lines
29 KiB
C++
970 lines
29 KiB
C++
//#define __FISHING_MAIN__
|
||
#include "stdafx.h"
|
||
#include "constants.h"
|
||
#include "fishing.h"
|
||
#include "locale_service.h"
|
||
|
||
#ifndef __FISHING_MAIN__
|
||
#include "item_manager.h"
|
||
|
||
#include "config.h"
|
||
#include "packet.h"
|
||
|
||
#include "sectree_manager.h"
|
||
#include "char.h"
|
||
#include "char_manager.h"
|
||
|
||
#include "log.h"
|
||
|
||
#include "questmanager.h"
|
||
#include "buffer_manager.h"
|
||
#include "desc_client.h"
|
||
#include "locale_service.h"
|
||
|
||
#include "affect.h"
|
||
#include "unique_item.h"
|
||
#endif
|
||
|
||
namespace fishing
|
||
{
|
||
enum
|
||
{
|
||
MAX_FISH = 37,
|
||
NUM_USE_RESULT_COUNT = 10, // 1 : DEAD 2 : BONE 3 ~ 12 : rest
|
||
FISH_BONE_VNUM = 27799,
|
||
SHELLFISH_VNUM = 27987,
|
||
EARTHWORM_VNUM = 27801,
|
||
WATER_STONE_VNUM_BEGIN = 28030,
|
||
WATER_STONE_VNUM_END = 28043,
|
||
FISH_NAME_MAX_LEN = 64,
|
||
MAX_PROB = 4,
|
||
};
|
||
|
||
enum
|
||
{
|
||
USED_NONE,
|
||
USED_SHELLFISH,
|
||
USED_WATER_STONE,
|
||
USED_TREASURE_MAP,
|
||
USED_EARTHWARM,
|
||
MAX_USED_FISH
|
||
};
|
||
|
||
enum
|
||
{
|
||
FISHING_TIME_NORMAL,
|
||
FISHING_TIME_SLOW,
|
||
FISHING_TIME_QUICK,
|
||
FISHING_TIME_ALL,
|
||
FISHING_TIME_EASY,
|
||
|
||
FISHING_TIME_COUNT,
|
||
|
||
MAX_FISHING_TIME_COUNT = 31,
|
||
};
|
||
|
||
enum
|
||
{
|
||
FISHING_LIMIT_NONE,
|
||
FISHING_LIMIT_APPEAR,
|
||
};
|
||
|
||
int aFishingTime[FISHING_TIME_COUNT][MAX_FISHING_TIME_COUNT] =
|
||
{
|
||
{ 0, 0, 0, 0, 0, 2, 4, 8, 12, 16, 20, 22, 25, 30, 50, 80, 50, 30, 25, 22, 20, 16, 12, 8, 4, 2, 0, 0, 0, 0, 0 },
|
||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 12, 16, 20, 22, 25, 30, 50, 80, 50, 30, 25, 22, 20 },
|
||
{ 20, 22, 25, 30, 50, 80, 50, 30, 25, 22, 20, 16, 12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||
{ 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 },
|
||
{ 20, 20, 20, 20, 20, 22, 24, 28, 32, 36, 40, 42, 45, 50, 70, 100, 70, 50, 45, 42, 40, 36, 32, 28, 24, 22, 20, 20, 20, 20, 20 },
|
||
};
|
||
|
||
struct SFishInfo
|
||
{
|
||
char name[FISH_NAME_MAX_LEN];
|
||
|
||
DWORD vnum;
|
||
DWORD dead_vnum;
|
||
DWORD grill_vnum;
|
||
|
||
int prob[MAX_PROB];
|
||
int difficulty;
|
||
|
||
int time_type;
|
||
int length_range[3]; // MIN MAX EXTRA_MAX : 99% MIN~MAX, 1% MAX~EXTRA_MAX
|
||
|
||
int used_table[NUM_USE_RESULT_COUNT];
|
||
// 6000 2000 1000 500 300 100 50 30 10 5 4 1
|
||
};
|
||
|
||
bool operator < ( const SFishInfo& lhs, const SFishInfo& rhs )
|
||
{
|
||
return lhs.vnum < rhs.vnum;
|
||
}
|
||
|
||
int g_prob_sum[MAX_PROB];
|
||
int g_prob_accumulate[MAX_PROB][MAX_FISH];
|
||
|
||
SFishInfo fish_info[MAX_FISH] = { { "\0", }, };
|
||
/*
|
||
{
|
||
{ "<22><>", 00000, 00000, 00000, { 750, 1750, 2750 }, 10, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, { 0, },
|
||
{0, } },
|
||
{ "<22>ݹ<EFBFBD><DDB9><EFBFBD>", 50002, 00000, 00000, { 50, 50, 0 }, 200, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, { 0, },
|
||
{0, } },
|
||
{ "<22>Ƕ<EFBFBD><C7B6><EFBFBD>", 27802, 00000, 00000, { 2100, 1500, 50 }, 10, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_EASY, {500, 550, 600},
|
||
{0, } },
|
||
{ "<22>ؾ<EFBFBD>", 27803, 27833, 27863, { 2100, 1500, 100 }, 13, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_EASY, {1000,2500,2800},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><EFBFBD><EEB0A1>", 27804, 27834, 27864, { 1100, 1300, 150 }, 16, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {2000,3500,3800},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><>ô<EFBFBD>ؾ<EFBFBD>", 27805, 27835, 27865, { 1100, 1100, 200 }, 20, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_SLOW, {3030,3500,4300},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><EFBFBD>", 27806, 27836, 27866, { 1100, 500, 300 }, 26, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {4000,6000,10000},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27807, 27837, 27867, { 1100, 450, 400 }, 33, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{6000,8000,10000},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27808, 27838, 27868, { 200, 400, 500 }, 42, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{1500,3000,3800},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22>۾<EFBFBD>", 27809, 27839, 27869, { 200, 300, 700 }, 54, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{5000,7000,8000},
|
||
{USED_NONE, USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22>ι<EFBFBD><CEB9><EFBFBD><EFBFBD><EFBFBD>", 27810, 27840, 27870, { 0, 270, 1000 }, 70, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{4000,5000,6000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>۾<EFBFBD>", 27811, 27841, 27871, { 0, 200, 1000 }, 91, FISHING_LIMIT_APPEAR, { 0, 0, 0}, FISHING_TIME_NORMAL,{5000,7000,8000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD>۾<EFBFBD>", 27812, 27842, 27872, { 0, 160, 1000 }, 118, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_QUICK,{4000,6000,7000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27813, 27843, 27873, { 0, 130, 700 }, 153, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{4000,6000,10000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><>ġ", 27814, 27844, 27874, { 0, 100, 400 }, 198, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{3000,4000,5000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><>ġ", 27815, 27845, 27875, { 0, 50, 300 }, 257, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{3500,5500,8000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22>ޱ<EFBFBD>", 27816, 27846, 27876, { 0, 30, 100 }, 334, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{3000,5000,10000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22>̲ٶ<CCB2><D9B6><EFBFBD>", 27817, 27847, 27877, { 0, 10, 64 }, 434, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_QUICK,{1800,2200,3000},
|
||
{USED_SHELLFISH, USED_NONE, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27818, 27848, 27878, { 0, 0, 15 }, 564, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{5000,8000,10000},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27819, 27849, 27879, { 0, 0, 9 }, 733, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{1500,3000,3800},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27820, 27850, 27880, { 0, 0, 6 }, 952, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_QUICK,{1500,3000,3800},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD>", 27821, 27851, 27881, { 0, 0, 3 }, 1237, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL,{1000,1500,2000},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 27822, 27852, 27882, { 0, 0, 2 }, 1608, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_SLOW,{4000,6000,10000},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "Ȳ<>ݺؾ<DDBA>", 27823, 27853, 27883, { 0, 0, 1 }, 2090, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_SLOW,{1000,3000,3500},
|
||
{USED_SHELLFISH, USED_NONE, USED_WATER_STONE, USED_TREASURE_MAP, USED_NONE, USED_NONE, USED_EARTHWARM, USED_NONE,USED_NONE, USED_NONE } },
|
||
{ "Ż<><C5BB><EFBFBD><EFBFBD>", 70201, 00000, 00000, { 5, 5, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)", 70202, 00000, 00000, { 15, 15, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ݻ<EFBFBD>)", 70203, 00000, 00000, { 15, 15, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)",70204, 00000, 00000, { 15, 15, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)", 70205, 00000, 00000, { 15, 15, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)",70206, 00000, 00000, { 15, 15, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>", 70048, 00000, 00000, { 8, 8, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>", 70049, 00000, 00000, { 8, 8, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ǥ", 70050, 00000, 00000, { 8, 8, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>尩", 70051, 00000, 00000, { 8, 8, 0 }, 60, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, },
|
||
{0, }},
|
||
{ "<22>ݵ<EFBFBD><DDB5>", 80008, 00000, 00000, { 20, 20, 0 }, 250, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_SLOW, {0, },
|
||
{0, } },
|
||
{ "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 50009, 00000, 00000, {300, 300, 0, }, 70, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, }, {0, } },
|
||
|
||
{ "<22>ݿ<EFBFBD><DDBF><EFBFBD>", 50008, 00000, 00000, {110, 110, 0, }, 100, FISHING_LIMIT_NONE, { 0, 0, 0}, FISHING_TIME_NORMAL, {0, }, {0, } },
|
||
};
|
||
*/
|
||
void Initialize()
|
||
{
|
||
SFishInfo fish_info_bak[MAX_FISH];
|
||
memcpy(fish_info_bak, fish_info, sizeof(fish_info));
|
||
|
||
memset(fish_info, 0, sizeof(fish_info));
|
||
|
||
|
||
// LOCALE_SERVICE
|
||
const int FILE_NAME_LEN = 256;
|
||
char szFishingFileName[FILE_NAME_LEN+1];
|
||
snprintf(szFishingFileName, sizeof(szFishingFileName),
|
||
"%s/fishing.txt", LocaleService_GetBasePath().c_str());
|
||
FILE * fp = fopen(szFishingFileName, "r");
|
||
// END_OF_LOCALE_SERVICE
|
||
|
||
if (*fish_info_bak[0].name)
|
||
SendLog("Reloading fish table.");
|
||
|
||
if (!fp)
|
||
{
|
||
SendLog("error! cannot open fishing.txt");
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if (*fish_info_bak[0].name)
|
||
{
|
||
memcpy(fish_info, fish_info_bak, sizeof(fish_info));
|
||
SendLog(" restoring to backup");
|
||
}
|
||
return;
|
||
}
|
||
|
||
memset(fish_info, 0, sizeof(fish_info));
|
||
|
||
char buf[512];
|
||
int idx = 0;
|
||
|
||
while (fgets(buf, 512, fp))
|
||
{
|
||
if (*buf == '#')
|
||
continue;
|
||
|
||
char * p = strrchr(buf, '\n');
|
||
*p = '\0';
|
||
|
||
const char * start = buf;
|
||
const char * tab = strchr(start, '\t');
|
||
|
||
if (!tab)
|
||
{
|
||
printf("Tab error on line: %s\n", buf);
|
||
SendLog("error! parsing fishing.txt");
|
||
|
||
if (*fish_info_bak[0].name)
|
||
{
|
||
memcpy(fish_info, fish_info_bak, sizeof(fish_info));
|
||
SendLog(" restoring to backup");
|
||
}
|
||
break;
|
||
}
|
||
|
||
char szCol[256], szCol2[256];
|
||
int iColCount = 0;
|
||
|
||
do
|
||
{
|
||
strncpy(szCol2, start, std::min<size_t>(sizeof(szCol2), (tab - start) + 1));
|
||
szCol2[tab-start] = '\0';
|
||
|
||
trim_and_lower(szCol2, szCol, sizeof(szCol));
|
||
|
||
if (!*szCol || *szCol == '\t')
|
||
iColCount++;
|
||
else
|
||
{
|
||
switch (iColCount++)
|
||
{
|
||
case 0: strncpy(fish_info[idx].name, szCol, sizeof(fish_info[idx].name)); break;
|
||
case 1: str_to_number(fish_info[idx].vnum, szCol); break;
|
||
case 2: str_to_number(fish_info[idx].dead_vnum, szCol); break;
|
||
case 3: str_to_number(fish_info[idx].grill_vnum, szCol); break;
|
||
case 4: str_to_number(fish_info[idx].prob[0], szCol); break;
|
||
case 5: str_to_number(fish_info[idx].prob[1], szCol); break;
|
||
case 6: str_to_number(fish_info[idx].prob[2], szCol); break;
|
||
case 7: str_to_number(fish_info[idx].prob[3], szCol); break;
|
||
case 8: str_to_number(fish_info[idx].difficulty, szCol); break;
|
||
case 9: str_to_number(fish_info[idx].time_type, szCol); break;
|
||
case 10: str_to_number(fish_info[idx].length_range[0], szCol); break;
|
||
case 11: str_to_number(fish_info[idx].length_range[1], szCol); break;
|
||
case 12: str_to_number(fish_info[idx].length_range[2], szCol); break;
|
||
case 13: // 0
|
||
case 14: // 1
|
||
case 15: // 2
|
||
case 16: // 3
|
||
case 17: // 4
|
||
case 18: // 5
|
||
case 19: // 6
|
||
case 20: // 7
|
||
case 21: // 8
|
||
case 22: // 9
|
||
str_to_number(fish_info[idx].used_table[iColCount-1-12], szCol);
|
||
break;
|
||
}
|
||
}
|
||
|
||
start = tab + 1;
|
||
tab = strchr(start, '\t');
|
||
} while (tab);
|
||
|
||
idx++;
|
||
|
||
if (idx == MAX_FISH)
|
||
break;
|
||
}
|
||
|
||
fclose(fp);
|
||
|
||
for (int i = 0; i < MAX_FISH; ++i)
|
||
{
|
||
sys_log(0, "FISH: %-24s vnum %5lu prob %4d %4d %4d %4d len %d %d %d",
|
||
fish_info[i].name,
|
||
fish_info[i].vnum,
|
||
fish_info[i].prob[0],
|
||
fish_info[i].prob[1],
|
||
fish_info[i].prob[2],
|
||
fish_info[i].prob[3],
|
||
fish_info[i].length_range[0],
|
||
fish_info[i].length_range[1],
|
||
fish_info[i].length_range[2]);
|
||
}
|
||
|
||
// Ȯ<><C8AE> <20><><EFBFBD><EFBFBD>
|
||
for (int j = 0; j < MAX_PROB; ++j)
|
||
{
|
||
g_prob_accumulate[j][0] = fish_info[0].prob[j];
|
||
|
||
for (int i = 1; i < MAX_FISH; ++i)
|
||
g_prob_accumulate[j][i] = fish_info[i].prob[j] + g_prob_accumulate[j][i - 1];
|
||
|
||
g_prob_sum[j] = g_prob_accumulate[j][MAX_FISH - 1];
|
||
sys_log(0, "FISH: prob table %d %d", j, g_prob_sum[j]);
|
||
}
|
||
}
|
||
|
||
int DetermineFishByProbIndex(int prob_idx)
|
||
{
|
||
int rv = Random::get(1, g_prob_sum[prob_idx]);
|
||
int * p = std::lower_bound(g_prob_accumulate[prob_idx], g_prob_accumulate[prob_idx]+ MAX_FISH, rv);
|
||
int fish_idx = p - g_prob_accumulate[prob_idx];
|
||
return fish_idx;
|
||
}
|
||
|
||
int GetProbIndexByMapIndex(int index)
|
||
{
|
||
if (index > 60)
|
||
return -1;
|
||
|
||
switch (index)
|
||
{
|
||
case 1:
|
||
case 21:
|
||
case 41:
|
||
return 0;
|
||
|
||
case 3:
|
||
case 23:
|
||
case 43:
|
||
return 1;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
#ifndef __FISHING_MAIN__
|
||
int DetermineFish(LPCHARACTER ch)
|
||
{
|
||
int map_idx = ch->GetMapIndex();
|
||
int prob_idx = GetProbIndexByMapIndex(map_idx);
|
||
|
||
if (prob_idx < 0)
|
||
return 0;
|
||
|
||
// ADD_PREMIUM
|
||
if (ch->GetPremiumRemainSeconds(PREMIUM_FISH_MIND) > 0 ||
|
||
ch->IsEquipUniqueGroup(UNIQUE_GROUP_FISH_MIND)) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE> <20><><EFBFBD><EFBFBD>
|
||
{
|
||
if (quest::CQuestManager::instance().GetEventFlag("manwoo") != 0)
|
||
prob_idx = 3;
|
||
else
|
||
prob_idx = 2;
|
||
}
|
||
// END_OF_ADD_PREMIUM
|
||
|
||
int adjust = 0;
|
||
if (quest::CQuestManager::instance().GetEventFlag("fish_miss_pct") != 0)
|
||
{
|
||
int fish_pct_value = std::clamp(quest::CQuestManager::instance().GetEventFlag("fish_miss_pct"), 0, 200);
|
||
adjust = (100-fish_pct_value) * fish_info[0].prob[prob_idx] / 100;
|
||
}
|
||
|
||
int rv = Random::get(adjust + 1, g_prob_sum[prob_idx]);
|
||
|
||
int * p = std::lower_bound(g_prob_accumulate[prob_idx], g_prob_accumulate[prob_idx] + MAX_FISH, rv);
|
||
int fish_idx = p - g_prob_accumulate[prob_idx];
|
||
|
||
//if (!g_iUseLocale)
|
||
if ( LC_IsYMIR() )
|
||
{
|
||
if (fish_info[fish_idx].vnum >= 70040 && fish_info[fish_idx].vnum <= 70052)
|
||
return 0;
|
||
}
|
||
|
||
if (g_iUseLocale) // <20>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ݵ<EFBFBD><DDB5>, <20>ݿ<EFBFBD><DDBF><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><>
|
||
{
|
||
DWORD vnum = fish_info[fish_idx].vnum;
|
||
|
||
if (vnum == 50008 || vnum == 50009 || vnum == 80008)
|
||
return 0;
|
||
}
|
||
|
||
return (fish_idx);
|
||
}
|
||
|
||
void FishingReact(LPCHARACTER ch)
|
||
{
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_REACT;
|
||
p.info = ch->GetVID();
|
||
ch->PacketAround(&p, sizeof(p));
|
||
}
|
||
|
||
void FishingSuccess(LPCHARACTER ch)
|
||
{
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_SUCCESS;
|
||
p.info = ch->GetVID();
|
||
ch->PacketAround(&p, sizeof(p));
|
||
}
|
||
|
||
void FishingFail(LPCHARACTER ch)
|
||
{
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_FAIL;
|
||
p.info = ch->GetVID();
|
||
ch->PacketAround(&p, sizeof(p));
|
||
}
|
||
|
||
void FishingPractice(LPCHARACTER ch)
|
||
{
|
||
LPITEM rod = ch->GetWear(WEAR_WEAPON);
|
||
if (rod && rod->GetType() == ITEM_ROD)
|
||
{
|
||
// <20>ִ<EFBFBD> <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ô<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
if ( rod->GetRefinedVnum()>0 && rod->GetSocket(0) < rod->GetValue(2) && Random::get(1,rod->GetValue(1))==1 )
|
||
{
|
||
rod->SetSocket(0, rod->GetSocket(0) + 1);
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>! (%d/%d)"),rod->GetSocket(0), rod->GetValue(2));
|
||
if (rod->GetSocket(0) == rod->GetValue(2))
|
||
{
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD>ô밡 <20>ִ<EFBFBD> <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD>θ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD> <20><><EFBFBD><EFBFBD><D7B7>̵<EFBFBD> <20><> <20><> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>."));
|
||
}
|
||
}
|
||
}
|
||
// <20>̳<EFBFBD><CCB3><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
rod->SetSocket(2, 0);
|
||
}
|
||
|
||
bool PredictFish(LPCHARACTER ch)
|
||
{
|
||
// ADD_PREMIUM
|
||
// <20><><EFBFBD><EFBFBD>ȯ
|
||
if (ch->FindAffect(AFFECT_FISH_MIND_PILL) ||
|
||
ch->GetPremiumRemainSeconds(PREMIUM_FISH_MIND) > 0 ||
|
||
ch->IsEquipUniqueGroup(UNIQUE_GROUP_FISH_MIND))
|
||
return true;
|
||
// END_OF_ADD_PREMIUM
|
||
|
||
return false;
|
||
}
|
||
|
||
EVENTFUNC(fishing_event)
|
||
{
|
||
fishing_event_info * info = dynamic_cast<fishing_event_info *>( event->info );
|
||
|
||
if ( info == NULL )
|
||
{
|
||
sys_err( "fishing_event> <Factor> Null pointer" );
|
||
return 0;
|
||
}
|
||
|
||
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(info->pid);
|
||
|
||
if (!ch)
|
||
return 0;
|
||
|
||
LPITEM rod = ch->GetWear(WEAR_WEAPON);
|
||
|
||
if (!(rod && rod->GetType() == ITEM_ROD))
|
||
{
|
||
ch->m_pkFishingEvent = NULL;
|
||
return 0;
|
||
}
|
||
|
||
switch (info->step)
|
||
{
|
||
case 0: // <20><><EFBFBD>鸮<EFBFBD><E9B8AE> <20>Ǵ<EFBFBD> <20><><EFBFBD>丸 <20><><EFBFBD>ư<EFBFBD>
|
||
++info->step;
|
||
|
||
//info->ch->Motion(MOTION_FISHING_SIGN);
|
||
info->hang_time = get_dword_time();
|
||
info->fish_id = DetermineFish(ch);
|
||
FishingReact(ch);
|
||
|
||
if (PredictFish(ch))
|
||
{
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_FISH;
|
||
p.info = fish_info[info->fish_id].vnum;
|
||
ch->GetDesc()->Packet(&p, sizeof(TPacketGCFishing));
|
||
}
|
||
return (PASSES_PER_SEC(6));
|
||
|
||
default:
|
||
++info->step;
|
||
|
||
if (info->step > 5)
|
||
info->step = 5;
|
||
|
||
ch->m_pkFishingEvent = NULL;
|
||
FishingFail(ch);
|
||
rod->SetSocket(2, 0);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
LPEVENT CreateFishingEvent(LPCHARACTER ch)
|
||
{
|
||
fishing_event_info* info = AllocEventInfo<fishing_event_info>();
|
||
info->pid = ch->GetPlayerID();
|
||
info->step = 0;
|
||
info->hang_time = 0;
|
||
|
||
int time = Random::get(10, 40);
|
||
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_START;
|
||
p.info = ch->GetVID();
|
||
p.dir = (BYTE)(ch->GetRotation()/5);
|
||
ch->PacketAround(&p, sizeof(TPacketGCFishing));
|
||
|
||
return event_create(fishing_event, info, PASSES_PER_SEC(time));
|
||
}
|
||
|
||
int GetFishingLevel(LPCHARACTER ch)
|
||
{
|
||
LPITEM rod = ch->GetWear(WEAR_WEAPON);
|
||
|
||
if (!rod || rod->GetType()!= ITEM_ROD)
|
||
return 0;
|
||
|
||
return rod->GetSocket(2) + rod->GetValue(0);
|
||
}
|
||
|
||
int Compute(DWORD fish_id, DWORD ms, DWORD* item, int level)
|
||
{
|
||
if (fish_id == 0)
|
||
return -2;
|
||
|
||
if (fish_id >= MAX_FISH)
|
||
{
|
||
sys_err("Wrong FISH ID : %d", fish_id);
|
||
return -2;
|
||
}
|
||
|
||
if (ms > 6000)
|
||
return -1;
|
||
|
||
int time_step = std::clamp<int>(((ms + 99) / 200), 0, MAX_FISHING_TIME_COUNT - 1);
|
||
|
||
if (Random::get(1, 100) <= aFishingTime[fish_info[fish_id].time_type][time_step])
|
||
{
|
||
if (Random::get(1, fish_info[fish_id].difficulty) <= level)
|
||
{
|
||
*item = fish_info[fish_id].vnum;
|
||
return 0;
|
||
}
|
||
return -3;
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
int GetFishLength(int fish_id)
|
||
{
|
||
if (Random::get(0,99))
|
||
{
|
||
// 99% : normal size
|
||
return (int)(fish_info[fish_id].length_range[0] +
|
||
(fish_info[fish_id].length_range[1] - fish_info[fish_id].length_range[0])
|
||
* (Random::get(0,2000)+Random::get(0,2000)+Random::get(0,2000)+Random::get(0,2000)+Random::get(0,2000))/10000);
|
||
}
|
||
else
|
||
{
|
||
// 1% : extra LARGE size
|
||
return (int)(fish_info[fish_id].length_range[1] +
|
||
(fish_info[fish_id].length_range[2] - fish_info[fish_id].length_range[1])
|
||
* 2 * asin(Random::get(0,10000)/10000.) / M_PI);
|
||
}
|
||
}
|
||
|
||
void Take(fishing_event_info* info, LPCHARACTER ch)
|
||
{
|
||
if (info->step == 1) // <20><><EFBFBD>Ⱑ <20>ɸ<EFBFBD> <20><><EFBFBD>¸<EFBFBD>..
|
||
{
|
||
int ms = (int) ((get_dword_time() - info->hang_time));
|
||
DWORD item_vnum = 0;
|
||
int ret = Compute(info->fish_id, ms, &item_vnum, GetFishingLevel(ch));
|
||
|
||
//if (test_server)
|
||
//ch->ChatPacket(CHAT_TYPE_INFO, "%d ms", ms);
|
||
|
||
switch (ret)
|
||
{
|
||
case -2: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
case -3: // <20><><EFBFBD>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
case -1: // <20>ð<EFBFBD> Ȯ<><C8AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
//ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<22><><EFBFBD>Ⱑ <20>̳<EFBFBD><CCB3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD> <20><><EFBFBD><EFBFBD>Ĩ<EFBFBD>ϴ<EFBFBD>."));
|
||
{
|
||
int map_idx = ch->GetMapIndex();
|
||
int prob_idx = GetProbIndexByMapIndex(map_idx);
|
||
|
||
LogManager::instance().FishLog(
|
||
ch->GetPlayerID(),
|
||
prob_idx,
|
||
info->fish_id,
|
||
GetFishingLevel(ch),
|
||
ms);
|
||
}
|
||
FishingFail(ch);
|
||
break;
|
||
|
||
case 0:
|
||
//ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<22><><EFBFBD>Ⱑ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>! (%s)"), fish_info[info->fish_id].name);
|
||
if (item_vnum)
|
||
{
|
||
FishingSuccess(ch);
|
||
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_FISH;
|
||
p.info = item_vnum;
|
||
ch->GetDesc()->Packet(&p, sizeof(TPacketGCFishing));
|
||
|
||
LPITEM item = ch->AutoGiveItem(item_vnum, 1, -1, false);
|
||
if (item)
|
||
{
|
||
item->SetSocket(0,GetFishLength(info->fish_id));
|
||
if (test_server)
|
||
{
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD>̹<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> %.2fcm"), item->GetSocket(0)/100.f);
|
||
}
|
||
|
||
if (quest::CQuestManager::instance().GetEventFlag("fishevent") > 0 && (info->fish_id == 5 || info->fish_id == 6))
|
||
{
|
||
// <20>̺<EFBFBD>Ʈ <20><><EFBFBD>̹Ƿ<CCB9> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
|
||
TPacketGDHighscore p;
|
||
p.dwPID = ch->GetPlayerID();
|
||
p.lValue = item->GetSocket(0);
|
||
|
||
if (info->fish_id == 5)
|
||
{
|
||
strncpy(p.szBoard, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD>Ʈ<EFBFBD><EFBFBD>ô<EFBFBD>ؾ<EFBFBD>"), sizeof(p.szBoard));
|
||
}
|
||
else if (info->fish_id == 6)
|
||
{
|
||
strncpy(p.szBoard, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD>Ʈ<EFBFBD><EFBFBD>"), sizeof(p.szBoard));
|
||
}
|
||
|
||
db_clientdesc->DBPacket(HEADER_GD_HIGHSCORE_REGISTER, 0, &p, sizeof(TPacketGDHighscore));
|
||
}
|
||
}
|
||
|
||
int map_idx = ch->GetMapIndex();
|
||
int prob_idx = GetProbIndexByMapIndex(map_idx);
|
||
|
||
LogManager::instance().FishLog(
|
||
ch->GetPlayerID(),
|
||
prob_idx,
|
||
info->fish_id,
|
||
GetFishingLevel(ch),
|
||
ms,
|
||
true,
|
||
item ? item->GetSocket(0) : 0);
|
||
|
||
}
|
||
else
|
||
{
|
||
int map_idx = ch->GetMapIndex();
|
||
int prob_idx = GetProbIndexByMapIndex(map_idx);
|
||
|
||
LogManager::instance().FishLog(
|
||
ch->GetPlayerID(),
|
||
prob_idx,
|
||
info->fish_id,
|
||
GetFishingLevel(ch),
|
||
ms);
|
||
FishingFail(ch);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
else if (info->step > 1)
|
||
{
|
||
int map_idx = ch->GetMapIndex();
|
||
int prob_idx = GetProbIndexByMapIndex(map_idx);
|
||
|
||
LogManager::instance().FishLog(
|
||
ch->GetPlayerID(),
|
||
prob_idx,
|
||
info->fish_id,
|
||
GetFishingLevel(ch),
|
||
7000);
|
||
//ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<22><><EFBFBD>Ⱑ <20>̳<EFBFBD><CCB3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ΰ<EFBFBD> <20><><EFBFBD><EFBFBD>Ĩ<EFBFBD>ϴ<EFBFBD>."));
|
||
FishingFail(ch);
|
||
}
|
||
else
|
||
{
|
||
TPacketGCFishing p;
|
||
p.header = HEADER_GC_FISHING;
|
||
p.subheader = FISHING_SUBHEADER_GC_STOP;
|
||
p.info = ch->GetVID();
|
||
ch->PacketAround(&p, sizeof(p));
|
||
}
|
||
|
||
if (info->step)
|
||
{
|
||
FishingPractice(ch);
|
||
}
|
||
//Motion(MOTION_FISHING_PULL);
|
||
}
|
||
|
||
void Simulation(int level, int count, int prob_idx, LPCHARACTER ch)
|
||
{
|
||
std::map<std::string, int> fished;
|
||
int total_count = 0;
|
||
|
||
for (int i = 0; i < count; ++i)
|
||
{
|
||
int fish_id = DetermineFishByProbIndex(prob_idx);
|
||
DWORD item = 0;
|
||
Compute(fish_id, (Random::get(2000, 4000) + Random::get(2000,4000)) / 2, &item, level);
|
||
|
||
if (item)
|
||
{
|
||
fished[fish_info[fish_id].name]++;
|
||
total_count ++;
|
||
}
|
||
}
|
||
|
||
for (std::map<std::string,int>::iterator it = fished.begin(); it != fished.end(); ++it)
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s : %d <20><><EFBFBD><EFBFBD>"), it->first.c_str(), it->second);
|
||
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d <20><><EFBFBD><EFBFBD> %d <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>"), fished.size(), total_count);
|
||
}
|
||
|
||
void UseFish(LPCHARACTER ch, LPITEM item)
|
||
{
|
||
int idx = item->GetVnum() - fish_info[2].vnum+2;
|
||
|
||
// <20>Ƕ<EFBFBD><C7B6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ұ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>ִ°<D6B4> <20>ƴѰ<C6B4> <20><><EFBFBD><EFBFBD><EFBFBD>Ұ<EFBFBD>
|
||
|
||
if (idx<=1 || idx >= MAX_FISH)
|
||
return;
|
||
|
||
int r = Random::get(1, 10000);
|
||
|
||
item->SetCount(item->GetCount()-1);
|
||
|
||
if (r >= 4001)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
ch->AutoGiveItem(fish_info[idx].dead_vnum);
|
||
}
|
||
else if (r >= 2001)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
ch->AutoGiveItem(FISH_BONE_VNUM);
|
||
}
|
||
else
|
||
{
|
||
// 1000 500 300 100 50 30 10 5 4 1
|
||
static int s_acc_prob[NUM_USE_RESULT_COUNT] = { 1000, 1500, 1800, 1900, 1950, 1980, 1990, 1995, 1999, 2000 };
|
||
int u_index = std::lower_bound(s_acc_prob, s_acc_prob + NUM_USE_RESULT_COUNT, r) - s_acc_prob;
|
||
|
||
switch (fish_info[idx].used_table[u_index])
|
||
{
|
||
case USED_TREASURE_MAP: // 3
|
||
case USED_NONE: // 0
|
||
case USED_WATER_STONE: // 2
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD>Ⱑ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
||
break;
|
||
|
||
case USED_SHELLFISH: // 1
|
||
if ( LC_IsCanada() == true )
|
||
{
|
||
if ( Random::get(0, 2) != 2 ) return;
|
||
}
|
||
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD> <20>ӿ<EFBFBD><D3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Խ<EFBFBD><D4BD>ϴ<EFBFBD>."));
|
||
ch->AutoGiveItem(SHELLFISH_VNUM);
|
||
break;
|
||
|
||
case USED_EARTHWARM: // 4
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD> <20>ӿ<EFBFBD><D3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD> <20><><EFBFBD>Խ<EFBFBD><D4BD>ϴ<EFBFBD>."));
|
||
ch->AutoGiveItem(EARTHWORM_VNUM);
|
||
break;
|
||
|
||
default:
|
||
ch->AutoGiveItem(fish_info[idx].used_table[u_index]);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
void Grill(LPCHARACTER ch, LPITEM item)
|
||
{
|
||
/*if (item->GetVnum() < fish_info[3].vnum)
|
||
return;
|
||
int idx = item->GetVnum()-fish_info[3].vnum+3;
|
||
if (idx>=MAX_FISH)
|
||
idx = item->GetVnum()-fish_info[3].dead_vnum+3;
|
||
if (idx>=MAX_FISH)
|
||
return;*/
|
||
int idx = -1;
|
||
DWORD vnum = item->GetVnum();
|
||
if (vnum >= 27803 && vnum <= 27830)
|
||
idx = vnum - 27800;
|
||
if (vnum >= 27833 && vnum <= 27860)
|
||
idx = vnum - 27830;
|
||
if (idx == -1)
|
||
return;
|
||
|
||
int count = item->GetCount();
|
||
|
||
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s<><73> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>."), item->GetName());
|
||
item->SetCount(0);
|
||
ch->AutoGiveItem(fish_info[idx].grill_vnum, count);
|
||
}
|
||
|
||
bool RefinableRod(LPITEM rod)
|
||
{
|
||
if (rod->GetType() != ITEM_ROD)
|
||
return false;
|
||
|
||
if (rod->IsEquipped())
|
||
return false;
|
||
|
||
return (rod->GetSocket(0) == rod->GetValue(2));
|
||
}
|
||
|
||
int RealRefineRod(LPCHARACTER ch, LPITEM item)
|
||
{
|
||
if (!ch || !item)
|
||
return 2;
|
||
|
||
// REFINE_ROD_HACK_BUG_FIX
|
||
if (!RefinableRod(item))
|
||
{
|
||
sys_err("REFINE_ROD_HACK pid(%u) item(%s:%d)", ch->GetPlayerID(), item->GetName(), item->GetID());
|
||
|
||
LogManager::instance().RefineLog(ch->GetPlayerID(), item->GetName(), item->GetID(), -1, 1, "ROD_HACK");
|
||
|
||
return 2;
|
||
}
|
||
// END_OF_REFINE_ROD_HACK_BUG_FIX
|
||
|
||
LPITEM rod = item;
|
||
|
||
int iAdv = rod->GetValue(0) / 10;
|
||
|
||
if (Random::get(1,100) <= rod->GetValue(3))
|
||
{
|
||
LogManager::instance().RefineLog(ch->GetPlayerID(), rod->GetName(), rod->GetID(), iAdv, 1, "ROD");
|
||
|
||
LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(rod->GetRefinedVnum(), 1);
|
||
|
||
if (pkNewItem)
|
||
{
|
||
BYTE bCell = rod->GetCell();
|
||
// <20><><EFBFBD>ô<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)");
|
||
pkNewItem->AddToCharacter(ch, TItemPos (INVENTORY, bCell));
|
||
LogManager::instance().ItemLog(ch, pkNewItem, "REFINE FISH_ROD SUCCESS", pkNewItem->GetName());
|
||
return 1;
|
||
}
|
||
|
||
// <20><><EFBFBD>ô<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
return 2;
|
||
}
|
||
else
|
||
{
|
||
LogManager::instance().RefineLog(ch->GetPlayerID(), rod->GetName(), rod->GetID(), iAdv, 0, "ROD");
|
||
|
||
LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(rod->GetValue(4), 1);
|
||
if (pkNewItem)
|
||
{
|
||
BYTE bCell = rod->GetCell();
|
||
// <20><><EFBFBD>ô<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)");
|
||
pkNewItem->AddToCharacter(ch, TItemPos(INVENTORY, bCell));
|
||
LogManager::instance().ItemLog(ch, pkNewItem, "REFINE FISH_ROD FAIL", pkNewItem->GetName());
|
||
return 0;
|
||
}
|
||
|
||
// <20><><EFBFBD>ô<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
return 2;
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#ifdef __FISHING_MAIN__
|
||
int main(int argc, char **argv)
|
||
{
|
||
//srandom(time(0) + getpid());
|
||
srandomdev();
|
||
/*
|
||
struct SFishInfo
|
||
{
|
||
const char* name;
|
||
|
||
DWORD vnum;
|
||
DWORD dead_vnum;
|
||
DWORD grill_vnum;
|
||
|
||
int prob[3];
|
||
int difficulty;
|
||
|
||
int limit_type;
|
||
int limits[3];
|
||
|
||
int time_type;
|
||
int length_range[3]; // MIN MAX EXTRA_MAX : 99% MIN~MAX, 1% MAX~EXTRA_MAX
|
||
|
||
int used_table[NUM_USE_RESULT_COUNT];
|
||
// 6000 2000 1000 500 300 100 50 30 10 5 4 1
|
||
};
|
||
*/
|
||
using namespace fishing;
|
||
|
||
Initialize();
|
||
|
||
for (int i = 0; i < MAX_FISH; ++i)
|
||
{
|
||
printf("%s\t%u\t%u\t%u\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d",
|
||
fish_info[i].name,
|
||
fish_info[i].vnum,
|
||
fish_info[i].dead_vnum,
|
||
fish_info[i].grill_vnum,
|
||
fish_info[i].prob[0],
|
||
fish_info[i].prob[1],
|
||
fish_info[i].prob[2],
|
||
fish_info[i].difficulty,
|
||
fish_info[i].time_type,
|
||
fish_info[i].length_range[0],
|
||
fish_info[i].length_range[1],
|
||
fish_info[i].length_range[2]);
|
||
|
||
for (int j = 0; j < NUM_USE_RESULT_COUNT; ++j)
|
||
printf("\t%d", fish_info[i].used_table[j]);
|
||
|
||
puts("");
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
#endif
|