summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-01-25 20:06:13 +0000
committerzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-01-25 20:06:13 +0000
commit0d9785742ca4554d633c226c2db8fa7a2d255082 (patch)
tree2b689304aa2df09f623816315be6538bc64e5258 /src/map
parent922f62e89a8b3dae0f7e407fae044299988b9ece (diff)
downloadhercules-0d9785742ca4554d633c226c2db8fa7a2d255082.tar.gz
hercules-0d9785742ca4554d633c226c2db8fa7a2d255082.tar.bz2
hercules-0d9785742ca4554d633c226c2db8fa7a2d255082.tar.xz
hercules-0d9785742ca4554d633c226c2db8fa7a2d255082.zip
- Implemented new Pet Bonus System. Enjoy!! :D
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13491 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c3
-rw-r--r--src/map/battle.c1
-rw-r--r--src/map/battle.h8
-rw-r--r--src/map/pc.c17
-rw-r--r--src/map/pet.c179
-rw-r--r--src/map/pet.h4
-rw-r--r--src/map/status.c14
-rw-r--r--src/map/unit.c7
8 files changed, 156 insertions, 77 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 91440bf0e..a4641b882 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -3178,7 +3178,8 @@ int atcommand_petfriendly(const int fd, struct map_session_data* sd, const char*
clif_displaymessage(fd, msg_txt(183)); // Pet intimacy is already at maximum.
return -1;
}
- pd->pet.intimate = friendly;
+
+ pet_set_intimate(pd, friendly);
clif_send_petstatus(sd);
clif_displaymessage(fd, msg_txt(182)); // Pet intimacy changed.
return 0;
diff --git a/src/map/battle.c b/src/map/battle.c
index 381dcd67e..f9bbd08b6 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -3505,6 +3505,7 @@ static const struct _battle_data {
{ "pet_attack_support", &battle_config.pet_attack_support, 0, 0, 1, },
{ "pet_damage_support", &battle_config.pet_damage_support, 0, 0, 1, },
{ "pet_support_min_friendly", &battle_config.pet_support_min_friendly, 900, 0, 950, },
+ { "pet_equip_min_friendly", &battle_config.pet_equip_min_friendly, 900, 0, 950, },
{ "pet_support_rate", &battle_config.pet_support_rate, 100, 0, INT_MAX, },
{ "pet_attack_exp_to_master", &battle_config.pet_attack_exp_to_master, 0, 0, 1, },
{ "pet_attack_exp_rate", &battle_config.pet_attack_exp_rate, 100, 0, INT_MAX, },
diff --git a/src/map/battle.h b/src/map/battle.h
index 50d780bae..4326fb6ee 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -180,6 +180,7 @@ extern struct Battle_Config
int emergency_call;
int guild_aura;
int pc_invincible_time;
+
int pet_catch_rate;
int pet_rename;
int pet_friendly_rate;
@@ -189,6 +190,7 @@ extern struct Battle_Config
int pet_attack_support;
int pet_damage_support;
int pet_support_min_friendly; //[Skotlex]
+ int pet_equip_min_friendly;
int pet_support_rate;
int pet_attack_exp_to_master;
int pet_attack_exp_rate;
@@ -197,6 +199,8 @@ extern struct Battle_Config
int pet_max_atk1; //[Skotlex]
int pet_max_atk2; //[Skotlex]
int pet_no_gvg; //Disables pets in gvg. [Skotlex]
+ int pet_equip_required;
+
int skill_min_damage;
int finger_offensive_type;
int heal_exp;
@@ -280,7 +284,7 @@ extern struct Battle_Config
int item_rate_mvp, item_rate_common, item_rate_common_boss, item_rate_card, item_rate_card_boss,
item_rate_equip, item_rate_equip_boss, item_rate_heal, item_rate_heal_boss, item_rate_use,
item_rate_use_boss, item_rate_treasure, item_rate_adddrop;
-
+
int logarithmic_drops;
int item_drop_common_min,item_drop_common_max; // Added by TyrNemesis^
int item_drop_card_min,item_drop_card_max;
@@ -290,6 +294,7 @@ extern struct Battle_Config
int item_drop_use_min,item_drop_use_max; //End
int item_drop_treasure_min,item_drop_treasure_max; //by [Skotlex]
int item_drop_adddrop_min,item_drop_adddrop_max; //[Skotlex]
+
int prevent_logout; // Added by RoVeRT
int alchemist_summon_reward; // [Valaris]
@@ -298,7 +303,6 @@ extern struct Battle_Config
int equip_natural_break_rate; //Base Natural break rate for attacks.
int equip_self_break_rate; //Natural & Penalty skills break rate
int equip_skill_break_rate; //Offensive skills break rate
- int pet_equip_required;
int multi_level_up;
int max_exp_gain_rate; //Max amount of exp bar % you can get in one go.
int pk_mode;
diff --git a/src/map/pc.c b/src/map/pc.c
index f094eafce..28e18fd44 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -5201,14 +5201,15 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
if(sd->status.pet_id > 0 && sd->pd)
{
- struct s_pet *pet = &sd->pd->pet;
- if(!map[sd->bl.m].flag.noexppenalty){
- pet->intimate -= sd->pd->petDB->die;
- if(pet->intimate < 0)
- pet->intimate = 0;
- clif_send_petdata(sd,sd->pd,1,pet->intimate);
- }
- if(sd->pd->target_id) // Unlock all targets...
+ struct pet_data *pd = sd->pd;
+ if( !map[sd->bl.m].flag.noexppenalty && !flag )
+ {
+ pet_set_intimate(pd, pd->pet.intimate - pd->petDB->die);
+ if( pd->pet.intimate < 0 )
+ pd->pet.intimate = 0;
+ clif_send_petdata(sd,sd->pd,1,pd->pet.intimate);
+ }
+ if( sd->pd->target_id ) // Unlock all targets...
pet_unlocktarget(sd->pd);
}
diff --git a/src/map/pet.c b/src/map/pet.c
index 7089875c9..f933836a1 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -56,6 +56,20 @@ int pet_hungry_val(struct pet_data *pd)
return 0;
}
+void pet_set_intimate(struct pet_data *pd, int value)
+{
+ int intimate;
+ struct map_session_data *sd;
+
+ nullpo_retv(pd);
+ intimate = pd->pet.intimate;
+ sd = pd->msd;
+
+ pd->pet.intimate = value;
+ if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) )
+ status_calc_pc(sd,0);
+}
+
int pet_create_egg(struct map_session_data *sd, int item_id)
{
int pet_id = search_petDB_index(item_id, PET_EGG);
@@ -179,7 +193,7 @@ static int pet_hungry(int tid, unsigned int tick, int id, intptr data)
{
struct map_session_data *sd;
struct pet_data *pd;
- int interval,t;
+ int interval;
sd=map_id2sd(id);
if(!sd)
@@ -199,12 +213,13 @@ static int pet_hungry(int tid, unsigned int tick, int id, intptr data)
return 1; //You lost the pet already, the rest is irrelevant.
pd->pet.hungry--;
- t = pd->pet.intimate;
- if(pd->pet.hungry < 0) {
+ if( pd->pet.hungry < 0 )
+ {
pet_stop_attack(pd);
pd->pet.hungry = 0;
- pd->pet.intimate -= battle_config.pet_hungry_friendly_decrease;
- if(pd->pet.intimate <= 0) {
+ pet_set_intimate(pd, pd->pet.intimate - battle_config.pet_hungry_friendly_decrease);
+ if( pd->pet.intimate <= 0 )
+ {
pd->pet.intimate = 0;
pd->status.speed = pd->db->status.speed;
}
@@ -291,13 +306,9 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
pd->pet.incuvate = 1;
- //No need, pet is saved on unit_free below.
- //intif_save_petdata(sd->status.account_id,&pd->pet);
- if(pd->state.skillbonus) {
- pd->state.skillbonus = 0;
- status_calc_pc(sd,0);
- }
unit_free(&pd->bl,0);
+
+ status_calc_pc(sd,0);
sd->status.pet_id = 0;
return 1;
@@ -358,7 +369,9 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
pd->last_thinktime = gettick();
pd->state.skillbonus = 0;
if( battle_config.pet_status_support )
- run_script(pet_db[i].script,0,sd->bl.id,0);
+ run_script(pet_db[i].pet_script,0,sd->bl.id,0);
+ if( pd->petDB && pd->petDB->equip_script )
+ status_calc_pc(sd,0);
if( battle_config.pet_hungry_delay_rate != 100 )
interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
@@ -686,21 +699,22 @@ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
clif_additem(sd,0,0,flag);
map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
- if (battle_config.pet_equip_required)
- { //Skotlex: halt support timers if needed
- if(pd->state.skillbonus) {
+ if( battle_config.pet_equip_required )
+ { // Skotlex: halt support timers if needed
+ if( pd->state.skillbonus )
+ {
pd->state.skillbonus = 0;
status_calc_pc(sd,0);
}
- if (pd->s_skill && pd->s_skill->timer != -1)
+ if( pd->s_skill && pd->s_skill->timer != -1 )
{
- if (pd->s_skill->id)
+ if( pd->s_skill->id )
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
else
delete_timer(pd->s_skill->timer, pet_heal_timer);
pd->s_skill->timer = INVALID_TIMER;
}
- if (pd->bonus && pd->bonus->timer != -1)
+ if( pd->bonus && pd->bonus->timer != -1 )
{
delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
pd->bonus->timer = INVALID_TIMER;
@@ -722,30 +736,33 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
}
pc_delitem(sd,i,1,0);
- if(pd->pet.hungry > 90)
- pd->pet.intimate -= pd->petDB->r_full;
- else {
- if(battle_config.pet_friendly_rate != 100)
+ if( pd->pet.hungry > 90 )
+ pet_set_intimate(pd, pd->pet.intimate - pd->petDB->r_full);
+ else
+ {
+ if( battle_config.pet_friendly_rate != 100 )
k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate)/100;
else
k = pd->petDB->r_hungry;
- if(pd->pet.hungry > 75) {
+ if( pd->pet.hungry > 75 )
+ {
k = k >> 1;
- if(k <= 0)
+ if( k <= 0 )
k = 1;
}
- pd->pet.intimate += k;
+ pet_set_intimate(pd, pd->pet.intimate + k);
}
- if(pd->pet.intimate <= 0) {
+ if( pd->pet.intimate <= 0 )
+ {
pd->pet.intimate = 0;
pet_stop_attack(pd);
pd->status.speed = pd->db->status.speed;
}
- else if(pd->pet.intimate > 1000)
+ else if( pd->pet.intimate > 1000 )
pd->pet.intimate = 1000;
status_calc_pet(pd, 0);
pd->pet.hungry += pd->petDB->fullness;
- if(pd->pet.hungry > 100)
+ if( pd->pet.hungry > 100 )
pd->pet.hungry = 100;
clif_send_petdata(sd,pd,2,pd->pet.hungry);
@@ -1185,10 +1202,18 @@ int read_petdb()
// Remove any previous scripts in case reloaddb was invoked.
for( j = 0; j < MAX_PET_DB; j++ )
- if (pet_db[j].script) {
- script_free_code(pet_db[j].script);
- pet_db[j].script = NULL;
+ {
+ if( pet_db[j].pet_script )
+ {
+ script_free_code(pet_db[j].pet_script);
+ pet_db[j].pet_script = NULL;
}
+ if( pet_db[j].equip_script )
+ {
+ script_free_code(pet_db[j].equip_script);
+ pet_db[j].pet_script = NULL;
+ }
+ }
// clear database
memset(pet_db,0,sizeof(pet_db));
@@ -1211,30 +1236,63 @@ int read_petdb()
lines = 0;
while( fgets(line, sizeof(line), fp) && j < MAX_PET_DB )
{
- char *str[32],*p,*np;
-
+ char *str[22], *p;
lines++;
if(line[0] == '/' && line[1] == '/')
continue;
+ memset(str, 0, sizeof(str));
+ p = line;
+ while( ISSPACE(*p) )
+ ++p;
+ if( *p == '\0' )
+ continue; // empty line
+ for( k = 0; k < 20; ++k )
+ {
+ str[k] = p;
+ p = strchr(p,',');
+ if( p == NULL )
+ break; // comma not found
+ *p = '\0';
+ ++p;
+ }
- // split string into table columns
- for(k=0,p=line;k<20;k++){
- if((np=strchr(p,','))!=NULL){
- str[k]=p;
- *np=0;
- p=np+1;
- } else {
- str[k]=p;
- p+=strlen(p);
- }
+ if( p == NULL )
+ {
+ ShowError("read_petdb: Insufficient columns in line %d, skipping.\n", lines);
+ continue;
+ }
+
+ // Pet Script
+ if( *p != '{' )
+ {
+ ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
+ continue;
+ }
+
+ str[20] = p;
+ p = strstr(p+1,"},");
+ if( p == NULL )
+ {
+ ShowError("read_petdb: Invalid format (Pet Script column) in line %d, skipping.\n", lines);
+ continue;
+ }
+ p[1] = '\0';
+ p += 2;
+
+ // Equip Script
+ if( *p != '{' )
+ {
+ ShowError("read_petdb: Invalid format (Equip Script column) in line %d, skipping.\n", lines);
+ continue;
}
+ str[21] = p;
- nameid=atoi(str[0]);
- if(nameid<=0)
+ if( (nameid = atoi(str[0])) <= 0 )
continue;
- if (!mobdb_checkid(nameid)) {
+ if( !mobdb_checkid(nameid) )
+ {
ShowWarning("pet_db reading: Invalid mob-class %d, pet not read.\n", nameid);
continue;
}
@@ -1249,7 +1307,7 @@ int read_petdb()
pet_db[j].fullness=atoi(str[7]);
pet_db[j].hungry_delay=atoi(str[8])*1000;
pet_db[j].r_hungry=atoi(str[9]);
- if(pet_db[j].r_hungry <= 0)
+ if( pet_db[j].r_hungry <= 0 )
pet_db[j].r_hungry=1;
pet_db[j].r_full=atoi(str[10]);
pet_db[j].intimate=atoi(str[11]);
@@ -1261,10 +1319,14 @@ int read_petdb()
pet_db[j].attack_rate=atoi(str[17]);
pet_db[j].defence_attack_rate=atoi(str[18]);
pet_db[j].change_target_rate=atoi(str[19]);
- pet_db[j].script = NULL;
- if((np=strchr(p,'{'))==NULL)
- continue;
- pet_db[j].script = parse_script(np, filename[i], lines, 0);
+ pet_db[j].pet_script = NULL;
+ pet_db[j].equip_script = NULL;
+
+ if( *str[20] )
+ pet_db[j].pet_script = parse_script(str[20], filename[i], lines, 0);
+ if( *str[21] )
+ pet_db[j].equip_script = parse_script(str[21], filename[i], lines, 0);
+
j++;
}
@@ -1301,10 +1363,17 @@ int do_init_pet(void)
int do_final_pet(void)
{
int i;
- for( i = 0; i < MAX_PET_DB; i++ ) {
- if(pet_db[i].script) {
- script_free_code(pet_db[i].script);
- pet_db[i].script = NULL;
+ for( i = 0; i < MAX_PET_DB; i++ )
+ {
+ if( pet_db[i].pet_script )
+ {
+ script_free_code(pet_db[i].pet_script);
+ pet_db[i].pet_script = NULL;
+ }
+ if( pet_db[i].equip_script )
+ {
+ script_free_code(pet_db[i].equip_script);
+ pet_db[i].equip_script = NULL;
}
}
ers_destroy(item_drop_ers);
diff --git a/src/map/pet.h b/src/map/pet.h
index 20538e240..729fdeb92 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -27,7 +27,8 @@ struct s_pet_db {
int attack_rate;
int defence_attack_rate;
int change_target_rate;
- struct script_code *script;
+ struct script_code *equip_script;
+ struct script_code *pet_script;
};
extern struct s_pet_db pet_db[MAX_PET_DB];
@@ -101,6 +102,7 @@ struct pet_data {
int pet_create_egg(struct map_session_data *sd, int item_id);
int pet_hungry_val(struct pet_data *pd);
+void pet_set_intimate(struct pet_data *pd, int value);
int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type);
int pet_unlocktarget(struct pet_data *pd);
int pet_sc_check(struct map_session_data *sd, int type); //Skotlex
diff --git a/src/map/status.c b/src/map/status.c
index 67f4a7c85..f7da7d505 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1967,16 +1967,16 @@ int status_calc_pc(struct map_session_data* sd,int first)
}
}
- if(sd->pd && battle_config.pet_status_support)
- { // Pet
- struct pet_data *pd=sd->pd;
- if(pd && pd->pet.intimate > 0 &&
- (!battle_config.pet_equip_required || pd->pet.equip > 0) &&
- pd->state.skillbonus == 1 && pd->bonus) //Skotlex: Readjusted for pets
+ if( sd->pd )
+ { // Pet Bonus
+ struct pet_data *pd = sd->pd;
+ if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly )
+ run_script(pd->petDB->equip_script,0,sd->bl.id,0);
+ if( pd && pd->pet.intimate > 0 && (!battle_config.pet_equip_required || pd->pet.equip > 0) && pd->state.skillbonus == 1 && pd->bonus )
pc_bonus(sd,pd->bonus->type, pd->bonus->val);
}
- //param_bonus now holds card bonuses.
+ //param_bonus now holds card bonuses.
if(status->rhw.range < 1) status->rhw.range = 1;
if(status->lhw.range < 1) status->lhw.range = 1;
if(status->rhw.range < status->lhw.range)
diff --git a/src/map/unit.c b/src/map/unit.c
index f79a16664..7260930fe 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -518,15 +518,16 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
return 0;
} else
sd->areanpc_id=0;
- if(sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0)
- { //Check if pet needs to be teleported. [Skotlex]
+ if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
+ { // Check if pet needs to be teleported. [Skotlex]
int flag = 0;
struct block_list* bl = &sd->pd->bl;
if( !checkpath && !path_search(NULL,bl->m,bl->x,bl->y,dst_x,dst_y,0,CELL_CHKNOPASS) )
flag = 1;
else if (!check_distance_bl(&sd->bl, bl, AREA_SIZE)) //Too far, teleport.
flag = 2;
- if (flag) {
+ if( flag )
+ {
unit_movepos(bl,sd->bl.x,sd->bl.y, 0, 0);
clif_slide(bl,bl->x,bl->y);
}