Originally posted by [b]NoH[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=5012
And yes, I do mean critical, check how it can be exploited in the RE branch to have unlimited XP:
http://www.eathena.ws/board/index.php?auto...g=5011&st=0So, here is the thing: checkquest(x,HUNTING) returns 2 even if the quest is completed, not just when it's active (aka: checkquest(x) == 0 or checkquest(x) == 1). Poorly scripted scripts such as the Aegis eden scripts converted to use the eA syntax may therefore ignore the fact you don't have the quest and give you the reward over and over if you have completed the HUNTING part.
Here is the fix. In quest.c:
CODE
int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
{
int i;
ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
if(i == sd->num_quests)
return -1;
switch( type )
{
case HAVEQUEST:
return sd->quest_log[i].state;
case PLAYTIME:
return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
case HUNTING:
{
int j;
ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
if( j == MAX_QUEST_OBJECTIVES )
return 2;
if( sd->quest_log[i].time < (unsigned int)time(NULL) )
return 1;
return 0;
}
->
CODE
int quest_check(TBL_PC * sd, int quest_id, quest_check_type type)
{
int i;
ARR_FIND(0, sd->num_quests, i, sd->quest_log[i].quest_id == quest_id);
if(i == sd->num_quests)
return -1;
switch( type )
{
case HAVEQUEST:
return sd->quest_log[i].state;
case PLAYTIME:
return (sd->quest_log[i].time < (unsigned int)time(NULL) ? 2 : sd->quest_log[i].state == Q_COMPLETE ? 1 : 0);
case HUNTING:
{
if (sd->quest_log[i].state == 0 || sd->quest_log[i].state == 1) {
int j;
ARR_FIND(0, MAX_QUEST_OBJECTIVES, j, sd->quest_log[i].count[j] < quest_db[sd->quest_index[i]].count[j]);
if( j == MAX_QUEST_OBJECTIVES )
return 2;
if( sd->quest_log[i].time < (unsigned int)time(NULL) )
return 1;
return 0;
}
else
return 0;
}