From 01920ca0c1f2c30ebb0abd4793cf6e308454f0cd Mon Sep 17 00:00:00 2001 From: blackhole89 Date: Sun, 21 May 2006 18:59:13 +0000 Subject: * Part A of the Homunculus code. This only features the structures, status_* and clif_* (packets) and is not functional yet in any conventional way, but doesn't interfere with present functionality either. I would only forget half of this stuff if I tried to do all at once. Expect the rest somewhen within the upcoming week. (This is not similar to jA's implementation.) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6681 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/clif.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/map/clif.h | 7 +++ src/map/map.h | 40 ++++++++++++++ src/map/status.c | 47 ++++++++++++++++ 4 files changed, 254 insertions(+) (limited to 'src') diff --git a/src/map/clif.c b/src/map/clif.c index 811f3bde0..f8d07aa41 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1362,6 +1362,147 @@ int clif_spawn(struct block_list *bl) } return 0; } +/*========================================== + * Homunculus [blackhole89] + *------------------------------------------ + */ +// Can somebody tell me why exactly I have commented this lot of stuff out? +// acknowledge client it has a homunculus +int clif_homunack(struct map_session_data *sd) +{ + struct homun_data *hd = sd->hd; + + nullpo_retr(0, sd); + nullpo_retr(0, sd->hd); + + unsigned char buf[64]; + //memset(buf,0,packet_len_table[0x230]); + memset(buf,0,12); //not yet set that stuff + WBUFW(buf,0)=0x230; + WBUFL(buf,4)=hd->bl.id; + ShowError("in clif_homunack~\n"); + clif_send(buf,/*packet_len_table[0x230]*/12,&sd->bl,SELF); + + return 0; +} + +// homunculus stats et al +int clif_homuninfo(struct map_session_data *sd) +{ + struct homun_data *hd = sd->hd; + + nullpo_retr(0, sd); + nullpo_retr(0, sd->hd); + + unsigned char buf[128]; + memset(buf,0,71); //packet_len_table[0x22e]); + WBUFW(buf,0)=0x22e; + memcpy(WBUFP(buf,2),hd->name,NAME_LENGTH); + WBUFW(buf,27)=hd->level; + WBUFW(buf,29)=hd->hunger_rate; + WBUFL(buf,31)=0xFF; //intimacy, leave it as is + WBUFW(buf,35)=hd->atk; + WBUFW(buf,37)=hd->matk; + WBUFW(buf,39)=hd->hit; + WBUFW(buf,41)=hd->crit/10; //crit is a +1 decimal value! + WBUFW(buf,43)=hd->def; + WBUFW(buf,45)=hd->mdef; + WBUFW(buf,47)=hd->flee; + WBUFW(buf,49)=status_get_amotion(&hd->bl)+200; //credits to jA for this field. + WBUFW(buf,51)=hd->hp; + WBUFW(buf,53)=hd->max_hp; + WBUFW(buf,55)=hd->sp; + WBUFW(buf,57)=hd->max_sp; + WBUFL(buf,59)=hd->exp; + WBUFL(buf,63)=hd->exp_next; + WBUFW(buf,67)=hd->skillpts; + WBUFW(buf,69)=0x21; + clif_send(buf,/*packet_len_table[0x22e]*/71,&sd->bl,SELF); +} + +// like skillinfoblock, just for homunculi. +int clif_homunskillinfoblock(struct map_session_data *sd) +{ + int fd; + int i,c,len=4,id, inf2; + + nullpo_retr(0, sd); + nullpo_retr(0, sd->hd); + + fd=sd->fd; + WFIFOHEAD(fd, 4 * 37 + 4); + WFIFOW(fd,0)=0x235; + for ( i = c = 0; i < 4; i++){ + if( (id=sd->hd->hskill[i].id)!=0 ){ + WFIFOW(fd,len ) = id; + WFIFOW(fd,len+2) = skill_get_inf(id-7300); // H. skills mapped to 700 and above + WFIFOW(fd,len+4) = 0; + WFIFOW(fd,len+6) = sd->hd->hskill[i].level; + WFIFOW(fd,len+8) = skill_get_sp(id,sd->hd->hskill[i].level); + WFIFOW(fd,len+10)= skill_get_range2(&sd->bl, id,sd->hd->hskill[i].level); + strncpy(WFIFOP(fd,len+12), /*merc_skill_get_name(id)*/ "", NAME_LENGTH); // can somebody tell me what exactly that function was good for anyway + /* inf2 = skill_get_inf2(id); + if(((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) && + !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL))) || + (battle_config.gm_allskill > 0 && pc_isGM(sd) >= battle_config.gm_allskill) ) + //WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_get_max(id) && sd->status.skill[i].flag ==0 )? 1:0; + WFIFOB(fd,len+36)= (sd->status.skill[i].lv < skill_tree_get_max(id, sd->status.class_) && sd->status.skill[i].flag ==0 )? 1:0; + else */ + WFIFOB(fd,len+36) = 1;//0; + len+=37; + c++; + } + } + WFIFOW(fd,2)=len; + WFIFOSET(fd,len); + + return 0; +} + +// Request a Homunculus name change +void clif_parse_ChangeHomunculusName(int fd, struct map_session_data *sd) { + RFIFOHEAD(fd); + nullpo_retv(sd); + nullpo_retv(sd->hd); + memcpy(sd->hd->name,RFIFOP(fd,2),24); + clif_homuninfo(sd); + clif_charnameack(sd->fd,&sd->hd->bl); +} + +// Somebody who is less lazy than me rename this to ReturnToMaster or something +void clif_parse_QueryHomunPos(int fd, struct map_session_data *sd) { + RFIFOHEAD(fd); + nullpo_retv(sd); + nullpo_retv(sd->hd); + unit_walktoxy(&sd->hd->bl, sd->bl.x,sd->bl.y-1, 0); //move to master + //clif_homunposack(sd->hd); +} + +// Request a Homunculus move-to-position +void clif_parse_HMoveTo(int fd,struct map_session_data *sd) { + int x,y,cmd; + + nullpo_retv(sd); + nullpo_retv(sd->hd); + + cmd = RFIFOW(fd,0); + x = RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]) * 4 + + (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 1) >> 6); + y = ((RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0]+1) & 0x3f) << 4) + + (RFIFOB(fd,packet_db[sd->packet_ver][cmd].pos[0] + 2) >> 4); + + unit_walktoxy(&sd->hd->bl,x,y,0); +} + +// Request the Homunculus attacking a bl +void clif_parse_HAttack(int fd,struct map_session_data *sd) { + nullpo_retv(sd); + nullpo_retv(sd->hd); + + if(sd->hd->bl.id != RFIFOL(fd,2)) return; + + printf("unit_attack returned: %d\n",unit_attack(&sd->hd->bl,RFIFOL(fd,6),0)); +} /*========================================== * *------------------------------------------ @@ -7728,6 +7869,10 @@ int clif_charnameack (int fd, struct block_list *bl) } } break; + //[blackhole89] + case BL_HOMUNCULUS: + memcpy(WBUFP(buf,6), ((struct homun_data*)bl)->name, NAME_LENGTH); + break; case BL_PET: memcpy(WBUFP(buf,6), ((struct pet_data*)bl)->name, NAME_LENGTH); break; @@ -8165,6 +8310,16 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_send_petstatus(sd); } + //homunculus [blackhole89] + if(sd->hd && sd->hd->alive) { + map_addblock(&sd->hd->bl); + clif_spawn(&sd->hd->bl); + clif_homunack(sd); + clif_homuninfo(sd); + clif_homuninfo(sd); //for some reason, at least older clients want this sent twice + clif_homunskillinfoblock(sd); + } + if(sd->state.connect_new) { sd->state.connect_new = 0; //Delayed night effect on log-on fix for the glow-issue. Thanks to Larry. @@ -11648,6 +11803,11 @@ static int packetdb_readdb(void) {clif_parse_FeelSaveOk,"feelsaveok"}, {clif_parse_AdoptRequest,"adopt"}, {clif_parse_debug,"debug"}, + //[blackhole89] + {clif_parse_ChangeHomunculusName,"changehomunculusname"}, + {clif_parse_QueryHomunPos,"queryhomunpos"}, + {clif_parse_HMoveTo,"hmoveto"}, + {clif_parse_HAttack,"hattack"}, {NULL,NULL} }; diff --git a/src/map/clif.h b/src/map/clif.h index 621dc28d4..492e24587 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -330,6 +330,13 @@ void clif_parse_ReqFeel(int fd, struct map_session_data *sd, int skilllv); void clif_feel_info(struct map_session_data *sd, int feel_level); void clif_hate_mob(struct map_session_data *sd, int skilllv,int mob_id); void clif_mission_mob(struct map_session_data *sd, unsigned short mob_id, unsigned short progress); + +// [blackhole89] +int clif_spawnhomun(struct homun_data *hd); +int clif_homunack(struct map_session_data *sd); +int clif_homuninfo(struct map_session_data *sd); +int clif_homuninsight(struct block_list *bl,va_list ap); +int clif_homunoutsight(struct block_list *bl,va_list ap); #endif diff --git a/src/map/map.h b/src/map/map.h index 042058885..79474cc63 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -733,6 +733,8 @@ struct map_session_data { struct pet_data *pd; int pet_hungry_timer; + struct homun_data *hd; // [blackhole89] + struct{ int m; //-1 - none, other: map index corresponding to map name. unsigned short index; //map index @@ -874,6 +876,7 @@ struct mob_data { struct { int id; int dmg; + unsigned char to_homun; //[blackhole89] - determines whether this damage was dealt by homunculus or its master } dmglog[DAMAGELOG_SIZE]; struct spawn_data *spawn; //Spawn data. struct item *lootitem; @@ -903,6 +906,43 @@ struct mob_data { char npc_event[50]; }; +/* [blackhole89] */ +struct homun_data { + struct block_list bl; + struct unit_data ud; + struct view_data *vd; + struct status_change sc; + + char name[NAME_LENGTH]; + int id; + short speed; + short class_; + + struct map_session_data *master; //pointer back to its master + + short hunger_rate; + + struct { + int id; //0 = none + int level; + } hskill[4]; //skills (max. 4 for now) + + int alive; //does it live + + int target_id,attacked_id; + + int amotion,dmotion; + + short level; + short atk,matk,hit,crit,def,mdef,flee,flee2; //flee2 is not transmitted; lucky flee + short regenhp,regensp; + short str,agi,vit,int_,dex,luk; //According to various sources, they do have these though they aren't transfered to client. + short hp,max_hp; + short sp,max_sp; + unsigned long exp,exp_next; + short skillpts; +}; + struct pet_data { struct block_list bl; struct unit_data ud; diff --git a/src/map/status.c b/src/map/status.c index 048fbe19e..2210ea63c 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2395,6 +2395,8 @@ int status_get_range(struct block_list *bl) return ((struct map_session_data *)bl)->attackrange; if(bl->type==BL_PET) return ((struct pet_data *)bl)->db->range; + if(bl->type==BL_HOMUNCULUS) + return 1; //[blackhole89] return 0; } /*========================================== @@ -2409,6 +2411,8 @@ int status_get_hp(struct block_list *bl) return ((struct mob_data *)bl)->hp; if(bl->type==BL_PC) return ((struct map_session_data *)bl)->status.hp; + if(bl->type==BL_HOMUNCULUS) + return ((struct homun_data *)bl)->hp; return 1; } /*========================================== @@ -2422,6 +2426,8 @@ int status_get_max_hp(struct block_list *bl) if(bl->type==BL_PC) return ((struct map_session_data *)bl)->status.max_hp; + else if(bl->type==BL_HOMUNCULUS) + return ((struct homun_data *)bl)->max_hp; //[blackhole89] else { int max_hp = 1; @@ -2471,6 +2477,8 @@ int status_get_str(struct block_list *bl) str = ((struct pet_data *)bl)->status->str; else str = ((struct pet_data *)bl)->db->str; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + str = ((struct homun_data *)bl)->str; } str = status_calc_str(bl,str); @@ -2505,6 +2513,8 @@ int status_get_agi(struct block_list *bl) agi = ((struct pet_data *)bl)->status->agi; else agi = ((struct pet_data *)bl)->db->agi; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + agi = ((struct homun_data *)bl)->agi; } agi = status_calc_agi(bl,agi); @@ -2538,6 +2548,8 @@ int status_get_vit(struct block_list *bl) vit = ((struct pet_data *)bl)->status->vit; else vit = ((struct pet_data *)bl)->db->vit; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + vit = ((struct homun_data *)bl)->vit; } vit = status_calc_vit(bl,vit); @@ -2571,6 +2583,8 @@ int status_get_int(struct block_list *bl) int_ = ((struct pet_data *)bl)->status->int_; else int_ = ((struct pet_data *)bl)->db->int_; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + int_ = ((struct homun_data *)bl)->int_; } int_ = status_calc_int(bl,int_); @@ -2604,6 +2618,8 @@ int status_get_dex(struct block_list *bl) dex = ((struct pet_data *)bl)->status->dex; else dex = ((struct pet_data *)bl)->db->dex; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + dex = ((struct homun_data *)bl)->dex; } dex = status_calc_dex(bl,dex); @@ -2637,6 +2653,8 @@ int status_get_luk(struct block_list *bl) luk = ((struct pet_data *)bl)->status->luk; else luk = ((struct pet_data *)bl)->db->luk; + } else if(bl->type == BL_HOMUNCULUS) { //[blackhole89] + luk = ((struct homun_data *)bl)->luk; } luk = status_calc_luk(bl,luk); @@ -2766,6 +2784,9 @@ int status_get_atk(struct block_list *bl) else atk = ((struct pet_data*)bl)->db->atk1; break; + case BL_HOMUNCULUS: //[blackhole89] + atk = ((struct homun_data*)bl)->atk; + break; } // Absolute, then relative modifiers from status changes (shared between PC and NPC) atk = status_calc_watk(bl,atk); @@ -2810,6 +2831,9 @@ int status_get_atk2(struct block_list *bl) else atk2 = ((struct pet_data*)bl)->db->atk2; break; + case BL_HOMUNCULUS: //[blackhole89] + atk2 = ((struct homun_data*)bl)->atk; + break; } // Absolute, then relative modifiers from status changes (shared between PC and NPC) @@ -2994,6 +3018,8 @@ int status_get_speed(struct block_list *bl) speed = ((struct pet_data *)bl)->speed; else if(bl->type==BL_NPC) //Added BL_NPC (Skotlex) speed = ((struct npc_data *)bl)->speed; + else if(bl->type==BL_HOMUNCULUS) //[blackhole89] + speed = ((struct homun_data *)bl)->speed; speed = status_calc_speed(bl,speed); @@ -3023,6 +3049,10 @@ int status_get_adelay(struct block_list *bl) adelay = ((struct pet_data *)bl)->db->adelay; aspd_rate = 100; break; + case BL_HOMUNCULUS: + adelay = 500; //temp; this should go into the structure later + aspd_rate=100; //[blackhole89] + break; default: adelay=4000; aspd_rate = 100; @@ -3049,6 +3079,7 @@ int status_get_amotion(struct block_list *bl) aspd_rate -= aspd_rate * 10*((struct mob_data *)bl)->guardian_data->guardup_lv/100; // Strengthen Guardians - custom value +10% ASPD / lv } else if(bl->type==BL_PET) amotion = ((struct pet_data *)bl)->db->amotion; + else if(bl->type==BL_HOMUNCULUS) ((struct homun_data *)bl)->amotion; //[blackhole89] aspd_rate = status_calc_aspd_rate(bl,aspd_rate); @@ -3078,6 +3109,7 @@ int status_get_dmotion(struct block_list *bl) } else if(bl->type==BL_PET) ret=((struct pet_data *)bl)->db->dmotion; + else if(bl->type==BL_HOMUNCULUS) ((struct homun_data *)bl)->dmotion; //[blackhole89] else return 2000; @@ -3256,6 +3288,8 @@ int status_get_mode(struct block_list *bl) } if(bl->type==BL_PC) return (MD_CANMOVE|MD_LOOTER|MD_CANATTACK); + if(bl->type==BL_HOMUNCULUS) //[blackhole89] + return (MD_CANMOVE|MD_CANATTACK); if(bl->type==BL_PET) return ((struct pet_data *)bl)->db->mode; if (bl->type==BL_SKILL) @@ -3315,6 +3349,8 @@ struct view_data *status_get_viewdata(struct block_list *bl) return &((TBL_PET*)bl)->vd; case BL_NPC: return ((TBL_NPC*)bl)->vd; + case BL_HOMUNCULUS: //[blackhole89] + return ((struct homun_data*)bl)->vd; } return NULL; } @@ -3411,6 +3447,15 @@ void status_set_viewdata(struct block_list *bl, int class_) ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_); } break; + case BL_HOMUNCULUS: //[blackhole89] + { + struct homun_data *hd = (struct homun_data*)bl; + if (vd) + hd->vd = vd; + else if (battle_config.error_log) + ShowError("status_set_viewdata (HOMUNCULUS): No view data for class %d\n", class_); + } + break; } vd = status_get_viewdata(bl); if (vd && vd->cloth_color && ( @@ -3430,6 +3475,8 @@ struct status_change *status_get_sc(struct block_list *bl) return &((TBL_PC*)bl)->sc; case BL_NPC: return &((TBL_NPC*)bl)->sc; + case BL_HOMUNCULUS: //[blackhole89] + return &((struct homun_data*)bl)->sc; } return NULL; } -- cgit v1.2.3-70-g09d2