Added support for homunculus autofeeding (#3007)
* Added support for homunculus autofeeding This feature is available in 2017-09-20bRagexeRE or later Credits to @Asheraf in HerculesWS/Hercules#1898
This commit is contained in:
parent
1390930ca5
commit
aff70f6482
@ -67,3 +67,11 @@ feature.roulette: off
|
||||
// Achievement (Note 1)
|
||||
// Requires: 2015-05-13aRagexe or later
|
||||
feature.achievement: on
|
||||
|
||||
// Homunculues Autofeeding (Note 1)
|
||||
// Requires: 2017-09-20bRagexeRE or later
|
||||
feature.homunculus_autofeed: off
|
||||
|
||||
// At which rate should homunculus autofeeding trigger?
|
||||
// Default: 30
|
||||
feature.homunculus_autofeed_rate: 30
|
||||
|
@ -608,6 +608,7 @@ CREATE TABLE IF NOT EXISTS `homunculus` (
|
||||
`alive` tinyint(2) NOT NULL default '1',
|
||||
`rename_flag` tinyint(2) NOT NULL default '0',
|
||||
`vaporize` tinyint(2) NOT NULL default '0',
|
||||
`autofeed` tinyint(2) NOT NULL default '0',
|
||||
PRIMARY KEY (`homun_id`)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
|
2
sql-files/upgrades/upgrade_20180404.sql
Normal file
2
sql-files/upgrades/upgrade_20180404.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `homunculus`
|
||||
ADD COLUMN `autofeed` tinyint(2) NOT NULL default '0' AFTER `vaporize`;
|
@ -2453,7 +2453,7 @@ bool char_checkdb(void){
|
||||
}
|
||||
//checking homunculus_db
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`,"
|
||||
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`alive`,`rename_flag`,`vaporize` "
|
||||
"`str`,`agi`,`vit`,`int`,`dex`,`luk`,`hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`alive`,`rename_flag`,`vaporize`,`autofeed` "
|
||||
" FROM `%s` LIMIT 1;", schema_config.homunculus_db) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return false;
|
||||
|
@ -93,10 +93,10 @@ bool mapif_homunculus_save(struct s_homunculus* hd)
|
||||
if( hd->hom_id == 0 )
|
||||
{// new homunculus
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "INSERT INTO `%s` "
|
||||
"(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`) "
|
||||
"VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%d')",
|
||||
"(`char_id`, `class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`, `rename_flag`, `vaporize`, `autofeed`) "
|
||||
"VALUES ('%d', '%d', '%d', '%s', '%d', '%u', '%u', '%d', '%d', %d, '%d', '%d', '%d', '%d', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d')",
|
||||
schema_config.homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
|
||||
hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize) )
|
||||
hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->autofeed) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
flag = false;
|
||||
@ -108,9 +108,9 @@ bool mapif_homunculus_save(struct s_homunculus* hd)
|
||||
}
|
||||
else
|
||||
{
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%u',`max_hp`='%u',`sp`='%u',`max_sp`='%u',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d' WHERE `homun_id`='%d'",
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `char_id`='%d', `class`='%d',`prev_class`='%d',`name`='%s',`level`='%d',`exp`='%u',`intimacy`='%u',`hunger`='%d', `str`='%d', `agi`='%d', `vit`='%d', `int`='%d', `dex`='%d', `luk`='%d', `hp`='%u',`max_hp`='%u',`sp`='%u',`max_sp`='%u',`skill_point`='%d', `rename_flag`='%d', `vaporize`='%d', `autofeed`='%d' WHERE `homun_id`='%d'",
|
||||
schema_config.homunculus_db, hd->char_id, hd->class_, hd->prev_class, esc_name, hd->level, hd->exp, hd->intimacy, hd->hunger, hd->str, hd->agi, hd->vit, hd->int_, hd->dex, hd->luk,
|
||||
hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->hom_id) )
|
||||
hd->hp, hd->max_hp, hd->sp, hd->max_sp, hd->skillpts, hd->rename_flag, hd->vaporize, hd->autofeed, hd->hom_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
flag = false;
|
||||
@ -155,7 +155,7 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
|
||||
|
||||
memset(hd, 0, sizeof(*hd));
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize` FROM `%s` WHERE `homun_id`='%u'",
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `homun_id`,`char_id`,`class`,`prev_class`,`name`,`level`,`exp`,`intimacy`,`hunger`, `str`, `agi`, `vit`, `int`, `dex`, `luk`, `hp`,`max_hp`,`sp`,`max_sp`,`skill_point`,`rename_flag`, `vaporize`, `autofeed` FROM `%s` WHERE `homun_id`='%u'",
|
||||
schema_config.homunculus_db, homun_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
@ -196,6 +196,7 @@ bool mapif_homunculus_load(int homun_id, struct s_homunculus* hd)
|
||||
Sql_GetData(sql_handle, 19, &data, NULL); hd->skillpts = atoi(data);
|
||||
Sql_GetData(sql_handle, 20, &data, NULL); hd->rename_flag = atoi(data);
|
||||
Sql_GetData(sql_handle, 21, &data, NULL); hd->vaporize = atoi(data);
|
||||
Sql_GetData(sql_handle, 22, &data, NULL); hd->autofeed = atoi(data);
|
||||
Sql_FreeResult(sql_handle);
|
||||
|
||||
hd->intimacy = umin(hd->intimacy,100000);
|
||||
|
@ -434,6 +434,7 @@ struct s_homunculus { //[orn]
|
||||
int luk_value;
|
||||
|
||||
char spiritball; //for homun S [lighta]
|
||||
bool autofeed;
|
||||
};
|
||||
|
||||
struct s_mercenary {
|
||||
|
@ -8503,6 +8503,8 @@ static const struct _battle_data {
|
||||
{ "autoloot_adjust", &battle_config.autoloot_adjust, 0, 0, 1, },
|
||||
{ "broadcast_hide_name", &battle_config.broadcast_hide_name, 2, 0, NAME_LENGTH, },
|
||||
{ "skill_drop_items_full", &battle_config.skill_drop_items_full, 0, 0, 1, },
|
||||
{ "feature.homunculus_autofeed", &battle_config.feature_homunculus_autofeed, 1, 0, 1, },
|
||||
{ "feature.homunculus_autofeed_rate", &battle_config.feature_homunculus_autofeed_rate,30, 0, 100, },
|
||||
|
||||
#include "../custom/battle_config_init.inc"
|
||||
};
|
||||
@ -8633,6 +8635,13 @@ void battle_adjust_conf()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PACKETVER < 20170920
|
||||
if( battle_config.feature_homunculus_autofeed ){
|
||||
ShowWarning("conf/battle/feature.conf homunculus autofeeding is enabled but it requires PACKETVER 2017-09-20 or newer, disabling...\n");
|
||||
battle_config.feature_homunculus_autofeed = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CELL_NOSTACK
|
||||
if (battle_config.custom_cell_stack_limit != 1)
|
||||
ShowWarning("Battle setting 'custom_cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");
|
||||
|
@ -639,6 +639,8 @@ struct Battle_Config
|
||||
int autoloot_adjust;
|
||||
int broadcast_hide_name;
|
||||
int skill_drop_items_full;
|
||||
int feature_homunculus_autofeed;
|
||||
int feature_homunculus_autofeed_rate;
|
||||
|
||||
#include "../custom/battle_config_struct.inc"
|
||||
};
|
||||
|
@ -9765,23 +9765,21 @@ void clif_feel_hate_reset(struct map_session_data *sd)
|
||||
}
|
||||
|
||||
|
||||
/// Equip window (un)tick ack (ZC_CONFIG).
|
||||
/// 02d9 <type>.L <value>.L
|
||||
/// type:
|
||||
/// 0 = open equip window
|
||||
/// value:
|
||||
/// 0 = disabled
|
||||
/// 1 = enabled
|
||||
void clif_equiptickack(struct map_session_data* sd, int flag)
|
||||
{
|
||||
/// Send out reply to configuration change
|
||||
/// 02d9 <type>.L <value>.L (ZC_CONFIG)
|
||||
/// type: see enum e_config_type
|
||||
/// value:
|
||||
/// false = disabled
|
||||
/// true = enabled
|
||||
void clif_configuration( struct map_session_data* sd, enum e_config_type type, bool enabled ){
|
||||
int fd;
|
||||
nullpo_retv(sd);
|
||||
fd = sd->fd;
|
||||
|
||||
WFIFOHEAD(fd, packet_len(0x2d9));
|
||||
WFIFOW(fd, 0) = 0x2d9;
|
||||
WFIFOL(fd, 2) = 0;
|
||||
WFIFOL(fd, 6) = flag;
|
||||
WFIFOL(fd, 2) = type;
|
||||
WFIFOL(fd, 6) = enabled;
|
||||
WFIFOSET(fd, packet_len(0x2d9));
|
||||
}
|
||||
|
||||
@ -10449,6 +10447,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
|
||||
clif_partyinvitationstate(sd);
|
||||
clif_equipcheckbox(sd);
|
||||
#endif
|
||||
#if PACKETVER >= 20170920
|
||||
if( sd->hd ){
|
||||
clif_configuration( sd, CONFIG_HOMUNCULUS_AUTOFEED, sd->hd->homunculus.autofeed );
|
||||
}else{
|
||||
clif_configuration( sd, CONFIG_HOMUNCULUS_AUTOFEED, false );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sd->guild && battle_config.guild_notice_changemap == 1)
|
||||
clif_guild_notice(sd); // Displays after VIP
|
||||
@ -16543,19 +16548,38 @@ void clif_parse_ViewPlayerEquip(int fd, struct map_session_data* sd)
|
||||
}
|
||||
|
||||
|
||||
/// Request to change equip window tick (CZ_CONFIG).
|
||||
/// 02d8 <type>.L <flag>.L
|
||||
/// type:
|
||||
/// 0 = open equip window
|
||||
/// Request to a configuration.
|
||||
/// 02d8 <type>.L <flag>.L (CZ_CONFIG)
|
||||
/// type: see enum e_config_type
|
||||
/// flag:
|
||||
/// 0 = disabled
|
||||
/// 1 = enabled
|
||||
void clif_parse_EquipTick(int fd, struct map_session_data* sd)
|
||||
{
|
||||
//int type = RFIFOL(fd,packet_db[cmd].pos[0]);
|
||||
bool flag = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[1]) != 0;
|
||||
sd->status.show_equip = flag;
|
||||
clif_equiptickack(sd, flag);
|
||||
/// false = disabled
|
||||
/// true = enabled
|
||||
void clif_parse_configuration( int fd, struct map_session_data* sd ){
|
||||
int cmd = RFIFOW(fd,0);
|
||||
int type = RFIFOL(fd,packet_db[cmd].pos[0]);
|
||||
bool flag = RFIFOL(fd,packet_db[cmd].pos[1]) != 0;
|
||||
|
||||
switch( type ){
|
||||
case CONFIG_OPEN_EQUIPMENT_WINDOW:
|
||||
sd->status.show_equip = flag;
|
||||
break;
|
||||
case CONFIG_PET_AUTOFEED:
|
||||
// TODO: Implement with pet evolution system
|
||||
break;
|
||||
case CONFIG_HOMUNCULUS_AUTOFEED:
|
||||
// Player can not click this if he does not have a homunculus or it is vaporized
|
||||
if( sd->hd == nullptr || sd->hd->homunculus.vaporize ){
|
||||
return;
|
||||
}
|
||||
|
||||
sd->hd->homunculus.autofeed = flag;
|
||||
break;
|
||||
default:
|
||||
ShowWarning( "clif_parse_configuration: received unknown configuration type '%d'...\n", type );
|
||||
return;
|
||||
}
|
||||
|
||||
clif_configuration( sd, static_cast<e_config_type>(type), flag );
|
||||
}
|
||||
|
||||
/// Request to change party invitation tick.
|
||||
|
@ -536,6 +536,13 @@ enum e_damage_type : uint8_t {
|
||||
DMG_TOUCH, /// (touch skill?)
|
||||
};
|
||||
|
||||
enum e_config_type : uint32 {
|
||||
CONFIG_OPEN_EQUIPMENT_WINDOW = 0,
|
||||
// Unknown
|
||||
CONFIG_PET_AUTOFEED = 2,
|
||||
CONFIG_HOMUNCULUS_AUTOFEED
|
||||
};
|
||||
|
||||
int clif_setip(const char* ip);
|
||||
void clif_setbindip(const char* ip);
|
||||
void clif_setport(uint16 port);
|
||||
@ -862,7 +869,7 @@ void clif_homskillup(struct map_session_data *sd, uint16 skill_id); //[orn]
|
||||
int clif_hom_food(struct map_session_data *sd,int foodid,int fail); //[orn]
|
||||
void clif_send_homdata(struct map_session_data *sd, int state, int param); //[orn]
|
||||
|
||||
void clif_equiptickack(struct map_session_data* sd, int flag);
|
||||
void clif_configuration( struct map_session_data* sd, enum e_config_type type, bool enabled );
|
||||
void clif_partytickack(struct map_session_data* sd, bool flag);
|
||||
void clif_viewequip_ack(struct map_session_data* sd, struct map_session_data* tsd);
|
||||
void clif_equipcheckbox(struct map_session_data* sd);
|
||||
|
@ -1123,7 +1123,7 @@
|
||||
packet(0x02d5,2);
|
||||
parseable_packet(0x02d6,6,clif_parse_ViewPlayerEquip,2);
|
||||
packet(0x02d7,-1);
|
||||
parseable_packet(0x02d8,10,clif_parse_EquipTick,2,6);
|
||||
parseable_packet(0x02d8,10,clif_parse_configuration,2,6);
|
||||
packet(0x02d9,10);
|
||||
packet(0x02da,3);
|
||||
parseable_packet(0x02db,-1,clif_parse_BattleChat,2,4);
|
||||
|
@ -4008,6 +4008,7 @@
|
||||
parseable_packet(0x0281,6,clif_parse_GetCharNameRequest,2);
|
||||
// 2017-09-13bRagexeRE
|
||||
#elif PACKETVER == 20170913
|
||||
parseable_packet(0x0281,6,clif_parse_GetCharNameRequest,2);
|
||||
parseable_packet(0x035F,26,clif_parse_FriendsListAdd,2);
|
||||
parseable_packet(0x0437,-1,clif_parse_SearchStoreInfo,2,4,5,9,13,14,15);
|
||||
parseable_packet(0x07E4,8,clif_parse_MoveFromKafra,2,4);
|
||||
|
@ -892,6 +892,10 @@ static int hom_hungry(int tid, unsigned int tick, int id, intptr_t data)
|
||||
clif_emotion(&hd->bl, ET_OK);
|
||||
}
|
||||
|
||||
if( battle_config.feature_homunculus_autofeed && hd->homunculus.autofeed && hd->homunculus.hunger <= battle_config.feature_homunculus_autofeed_rate ){
|
||||
hom_food( sd, hd );
|
||||
}
|
||||
|
||||
if (hd->homunculus.hunger < 0) {
|
||||
hd->homunculus.hunger = 0;
|
||||
// Delete the homunculus if intimacy <= 100
|
||||
|
Loading…
x
Reference in New Issue
Block a user