Major updates to the quest system.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12581 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
Kevin 2008-04-13 22:19:02 +00:00
parent d7355c9899
commit 302adbf42a
16 changed files with 309 additions and 83 deletions

View File

@ -4,6 +4,8 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2008/04/13
* Some major updates to the quest system, beginning to move it
over to the inter server instead of char server. (r12581) [Kevin]
* Added an include in clif.h to avoid a complaint of gcc [Toms]
* Quick&dirty reversal of the inter-server behaviour introduced in r3255/r3256:
- the behaviour enabled a desynch between the char-server and the map-server

View File

@ -0,0 +1,3 @@
ALTER TABLE `quest_objective` ADD COLUMN `char_id` INTEGER UNSIGNED NOT NULL AFTER `num`,
DROP PRIMARY KEY,
ADD PRIMARY KEY USING BTREE(`quest_id`, `num`, `char_id`);

View File

@ -14,8 +14,8 @@ COMMON_SQL_OBJ = ../common/obj_sql/sql.o
COMMON_H = ../common/sql.h
CHAR_OBJ = obj_sql/char.o obj_sql/inter.o obj_sql/int_party.o obj_sql/int_guild.o \
obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o
CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h
obj_sql/int_storage.o obj_sql/int_pet.o obj_sql/int_homun.o obj_sql/int_mail.o obj_sql/int_auction.o obj_sql/int_quest.o
CHAR_H = char.h inter.h int_party.h int_guild.h int_storage.h int_pet.h int_homun.h int_mail.h int_auction.h int_quest.h
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)

View File

@ -431,7 +431,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
int diff = 0;
char save_status[128]; //For displaying save information. [Skotlex]
struct mmo_charstatus *cp;
StringBuf buf, buf2;
StringBuf buf;
if (char_id!=p->char_id) return 0;
@ -644,76 +644,6 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
strcat(save_status, " friends");
}
StringBuf_Clear(&buf);
StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `quest_id`, `state`) VALUES ", quest_db);
for(i=0; i<MAX_QUEST; i++)
{
if(p->quest_log[i].quest_id)
{
if(diff)
StringBuf_AppendStr(&buf, ",");
StringBuf_Printf(&buf, "('%d', '%d', '%d')", p->char_id, p->quest_log[i].quest_id, p->quest_log[i].state);
diff = 1;
}
}
if(diff) {
if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
Sql_ShowDebug(sql_handle);
else
strcat(save_status, " hotkeys");
}
//save quests
StringBuf_Init(&buf2);
StringBuf_Clear(&buf);
StringBuf_Clear(&buf2);
diff = 0;
StringBuf_Printf(&buf, "REPLACE INTO `%s` (`char_id`, `quest_id`, `state`) VALUES ", quest_db);
for(i=0; i<MAX_QUEST; i++)
{
if(p->quest_log[i].quest_id)
{
if(diff)
StringBuf_AppendStr(&buf, ",");
StringBuf_Printf(&buf, "('%d', '%d', '%d')", p->char_id, p->quest_log[i].quest_id, p->quest_log[i].state);
diff = 1;
StringBuf_Printf(&buf2, "REPLACE INTO `%s` (`quest_id`, `num`, `name`, `count`) VALUES ", quest_obj_db);
count = 0;
for(j=0; j<p->quest_log[i].num_objectives; j++)
{
if(p->quest_log[i].objectives[j].name)
{
if(count)
StringBuf_AppendStr(&buf2, ",");
StringBuf_Printf(&buf2, "('%d', '%d', '%s', '%d')", p->quest_log[i].quest_id, j, p->quest_log[i].objectives[j].name, p->quest_log[i].objectives[j].count);
count = 1;
}
}
if(count) {
if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf2)) )
Sql_ShowDebug(sql_handle);
}
}
}
if(diff) {
if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
Sql_ShowDebug(sql_handle);
else
strcat(save_status, " quests");
}
StringBuf_Destroy(&buf2);
#ifdef HOTKEY_SAVING
// hotkeys
StringBuf_Clear(&buf);

View File

@ -59,6 +59,8 @@ extern char party_db[256];
extern char pet_db[256];
extern char mail_db[256];
extern char auction_db[256];
extern char quest_db[256];
extern char quest_obj_db[256];
extern int db_use_sqldbs; // added for sql item_db read for char server [Valaris]

112
src/char_sql/int_quest.c Normal file
View File

@ -0,0 +1,112 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#include "../common/mmo.h"
#include "../common/malloc.h"
#include "../common/showmsg.h"
#include "../common/socket.h"
#include "../common/strlib.h"
#include "../common/sql.h"
#include "../common/timer.h"
#include "char.h"
#include "inter.h"
#include "int_quest.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int mapif_parse_quest_delete(int fd)
{
bool success = true;
int char_id = RFIFOL(fd,2);
int quest_id = RFIFOL(fd,6);
if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_db, quest_id, char_id) )
{
Sql_ShowDebug(sql_handle);
success = false;
}
if ( success && SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `quest_id` = '%d' AND `char_id` = '%d'", quest_obj_db, quest_id, char_id) )
{
Sql_ShowDebug(sql_handle);
success = false;
}
WFIFOHEAD(fd,11);
WFIFOW(fd,0) = 0x3862;
WFIFOL(fd,2) = char_id;
WFIFOL(fd,6) = quest_id;
WFIFOB(fd,10) = success?1:0;
WFIFOSET(fd,11);
return 0;
}
int mapif_parse_quest_add(int fd)
{
StringBuf buf;
bool success = true;
int char_id = RFIFOL(fd,4);
struct quest qd;
int i;
memcpy(&qd, RFIFOP(fd,8), RFIFOW(fd,2)-8);
StringBuf_Init(&buf);
StringBuf_Printf(&buf, "INSERT INTO `%s`(`quest_id`, `char_id`, `state`) VALUES ('%d', '%d', '%d')", quest_db, qd.quest_id, char_id, qd.state);
if ( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
{
Sql_ShowDebug(sql_handle);
success = false;
}
for(i=0; i<qd.num_objectives && success; i++)
{
StringBuf_Clear(&buf);
StringBuf_Printf(&buf, "INSERT INTO `%s`(`quest_id`, `char_id`, `num`, `name`, `count`) VALUES ('%d', '%d', '%d', '%s', '%d')",
quest_obj_db, qd.quest_id, char_id, i, qd.objectives[i].name, qd.objectives[i].count);
if ( success && SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
{
Sql_ShowDebug(sql_handle);
success = false;
}
}
WFIFOHEAD(fd,11);
WFIFOW(fd,0) = 0x3861;
WFIFOL(fd,2) = char_id;
WFIFOL(fd,6) = qd.quest_id;
WFIFOB(fd,10) = success?1:0;
WFIFOSET(fd,11);
StringBuf_Destroy(&buf);
return 0;
}
int inter_quest_parse_frommap(int fd)
{
switch(RFIFOW(fd,0))
{
case 0x3061: mapif_parse_quest_add(fd); break;
case 0x3062: mapif_parse_quest_delete(fd); break;
default:
return 0;
}
return 1;
}

12
src/char_sql/int_quest.h Normal file
View File

@ -0,0 +1,12 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#ifndef _QUEST_H_
#define _QUEST_H_
/*questlog system*/
struct quest;
int inter_quest_parse_frommap(int fd);
#endif

View File

@ -17,6 +17,7 @@
#include "int_homun.h"
#include "int_mail.h"
#include "int_auction.h"
#include "int_quest.h"
#include <stdio.h>
#include <string.h>
@ -56,7 +57,7 @@ int inter_recv_packet_length[] = {
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1, // 3030-
5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040-
-1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus]
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060-
-1,-1,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin]
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070-
48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3080-
-1,10,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3090- Homunculus packets [albator]
@ -843,6 +844,7 @@ int inter_parse_frommap(int fd)
|| inter_homunculus_parse_frommap(fd)
|| inter_mail_parse_frommap(fd)
|| inter_auction_parse_frommap(fd)
|| inter_quest_parse_frommap(fd)
)
break;
else

View File

@ -20,6 +20,7 @@
#include "atcommand.h"
#include "mercenary.h" //albator
#include "mail.h"
#include "quest.h"
#include <sys/types.h>
#include <stdio.h>
@ -36,7 +37,7 @@ static const int packet_len_table[]={
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
9, 9,-1,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
-1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus]
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin]
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3880
-1,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3890 Homunculus [albator]
@ -1398,7 +1399,58 @@ int intif_parse_DeleteHomunculusOk(int fd)
return 0;
}
/**************************************
QUESTLOG SYSTEM FUNCTIONS
***************************************/
int intif_parse_questDelete(int fd)
{
quest_delete_ack(RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOB(fd, 10));
return 0;
}
int intif_quest_delete(int char_id, int quest_id)
{
if(CheckForCharServer())
return 0;
WFIFOHEAD(inter_fd, 10);
WFIFOW(inter_fd,0) = 0x3062;
WFIFOL(inter_fd,2) = char_id;
WFIFOL(inter_fd,6) = quest_id;
WFIFOSET(inter_fd, 10);
return 0;
}
int intif_parse_questAdd(int fd)
{
quest_add_ack(RFIFOL(fd, 2), RFIFOL(fd, 6), RFIFOB(fd, 10));
return 0;
}
int intif_quest_add(int char_id, struct quest * qd)
{
int sSize = sizeof(struct quest);
if(CheckForCharServer())
return 0;
WFIFOHEAD(inter_fd, sSize + 8);
WFIFOW(inter_fd,0) = 0x3061;
WFIFOW(inter_fd,2) = sSize + 8;
WFIFOL(inter_fd,4) = char_id;
memcpy(WFIFOP(inter_fd,8), qd, sSize);
WFIFOSET(inter_fd, sSize + 8);
return 0;
}
#ifndef TXT_ONLY
/*==========================================
* MAIL SYSTEM
* By Zephyrus
@ -1938,6 +1990,11 @@ int intif_parse(int fd)
case 0x3841: intif_parse_GuildCastleDataSave(fd); break;
case 0x3842: intif_parse_GuildCastleAllDataLoad(fd); break;
case 0x3843: intif_parse_GuildMasterChanged(fd); break;
//Quest system
case 0x3861: intif_parse_questAdd(fd); break;
case 0x3862: intif_parse_questDelete(fd); break;
#ifndef TXT_ONLY
// Mail System
case 0x3848: intif_parse_Mail_inboxreceived(fd); break;

View File

@ -75,6 +75,10 @@ int intif_homunculus_requestload(int account_id, int homun_id);
int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh);
int intif_homunculus_requestdelete(int homun_id);
/******QUEST SYTEM*******/
int intif_quest_delete(int char_id, int quest_id);
int intif_quest_add(int char_id, struct quest * qd);
#ifndef TXT_ONLY
// MAIL SYSTEM
int intif_Mail_requestinbox(int char_id, unsigned char flag);

View File

@ -25,6 +25,7 @@
#include "log.h"
#include "clif.h"
#include "quest.h"
#include "intif.h"
#include <stdio.h>
#include <stdlib.h>
@ -67,13 +68,46 @@ int quest_add(TBL_PC * sd, struct quest * qd)
memcpy(&sd->quest_log[i], qd, sizeof(struct quest));
sd->num_quests++;
//Notify client
clif_send_quest_info(sd, &sd->quest_log[i]);
//Notify inter server
intif_quest_add(sd->status.char_id, qd);
return 0;
}
int quest_add_ack(int char_id, int quest_id, int success)
{
int i;
TBL_PC * sd = map_charid2sd(char_id);
///Player no longer on map
if(!sd)
return -1;
//Search for quest
ARR_FIND(0, MAX_QUEST, i, sd->quest_log[i].quest_id == quest_id);
//Quest not found, shouldn't happen?
if(i == MAX_QUEST)
return -1;
if(success)
{
//Notify client
clif_send_quest_info(sd, &sd->quest_log[i]);
}
else
{
ShowError("Quest %d for character %d could not be added!\n", quest_id, char_id);
//Zero quest
memset(&sd->quest_log[i], 0, sizeof(struct quest));
sd->num_quests--;
}
return 0;
}
int quest_delete(TBL_PC * sd, int quest_id)
{
@ -83,14 +117,47 @@ int quest_delete(TBL_PC * sd, int quest_id)
ARR_FIND(0, MAX_QUEST, i, sd->quest_log[i].quest_id == quest_id);
//Quest not found
if(i != MAX_QUEST)
if(i == MAX_QUEST)
return -1;
//Zero quest
memset(&sd->quest_log[i], 0, sizeof(struct quest));
intif_quest_delete(sd->status.char_id, quest_id);
//Notify client
clif_send_quest_delete(sd, quest_id);
return 0;
}
int quest_delete_ack(int char_id, int quest_id, int success)
{
int i;
TBL_PC * sd = map_charid2sd(char_id);
///Player no longer on map
if(!sd)
return -1;
//Search for quest
ARR_FIND(0, MAX_QUEST, i, sd->quest_log[i].quest_id == quest_id);
//Quest not found
if(i == MAX_QUEST)
return -1;
if(success)
{
//Zero quest
memset(&sd->quest_log[i], 0, sizeof(struct quest));
sd->num_quests--;
//Notify client
clif_send_quest_delete(sd, quest_id);
return 1;
}
else
ShowError("Quest %d for character %d could not be deleted!\n", quest_id, char_id);
return 0;

View File

@ -7,8 +7,13 @@
int quest_pc_login(TBL_PC * sd);
int quest_load_info(TBL_PC * sd, struct mmo_charstatus * st);
int quest_make_savedata(TBL_PC * sd);
int quest_add(TBL_PC * sd, struct quest * qd);
int quest_add_ack(int char_id, int quest_id, int success);
int quest_delete(TBL_PC * sd, int quest_id);
int quest_delete_ack(int char_id, int quest_id, int success);
int quest_update_objective(TBL_PC * sd, int quest_id, int objective_num, const char * name, int count);
int quest_update_status(TBL_PC * sd, int quest_id, bool status);

View File

@ -251,6 +251,14 @@ SOURCE=..\src\char_sql\int_storage.h
# End Source File
# Begin Source File
SOURCE=..\src\char_sql\int_quest.c
# End Source File
# Begin Source File
SOURCE=..\src\char_sql\int_quest.h
# End Source File
# Begin Source File
SOURCE=..\src\char_sql\inter.c
# End Source File
# Begin Source File

View File

@ -191,6 +191,12 @@
<File
RelativePath="..\src\char_sql\int_storage.h">
</File>
<File
RelativePath="..\src\char_sql\int_quest.c">
</File>
<File
RelativePath="..\src\char_sql\int_quest.h">
</File>
<File
RelativePath="..\src\char_sql\inter.c">
</File>

View File

@ -401,6 +401,14 @@
RelativePath="..\src\char_sql\int_storage.h"
>
</File>
<File
RelativePath="..\src\char_sql\int_quest.c"
>
</File>
<File
RelativePath="..\src\char_sql\int_quest.h"
>
</File>
<File
RelativePath="..\src\char_sql\inter.c"
>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Version="9.00"
Name="char-server_sql"
ProjectGUID="{D356871D-58E1-450B-967A-E4E9646175AF}"
RootNamespace="char-server_sql"
@ -391,6 +391,14 @@
RelativePath="..\src\char_sql\int_pet.h"
>
</File>
<File
RelativePath="..\src\char_sql\int_quest.c"
>
</File>
<File
RelativePath="..\src\char_sql\int_quest.h"
>
</File>
<File
RelativePath="..\src\char_sql\int_storage.c"
>