summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/atcommand.c2
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/homunculus.c22
-rw-r--r--src/map/homunculus.h10
-rw-r--r--src/map/itemdb.h1
-rw-r--r--src/map/pc.c6
-rw-r--r--src/map/script.c124
-rw-r--r--src/map/skill.c2
-rw-r--r--src/map/status.c2
9 files changed, 111 insertions, 60 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 3d04a6bff..4933256a2 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6869,7 +6869,7 @@ ACMD(makehomun) {
homunid = atoi(message);
if( homunid == -1 && sd->status.hom_id && !homun_alive(sd->hd) ) {
- if( !sd->hd->homunculus.vaporize )
+ if( sd->hd->homunculus.vaporize )
homun->ressurect(sd, 100, sd->bl.x, sd->bl.y);
else
homun->call(sd);
diff --git a/src/map/clif.c b/src/map/clif.c
index 57830478d..0c21c796c 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1379,7 +1379,7 @@ void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int flag)
WBUFW(buf,0)=0x22e;
memcpy(WBUFP(buf,2),hd->homunculus.name,NAME_LENGTH);
// Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
- WBUFB(buf,26)=(battle_config.hom_rename?0:hd->homunculus.rename_flag) | (hd->homunculus.vaporize << 1) | (hd->homunculus.hp?0:4);
+ WBUFB(buf,26)=(battle_config.hom_rename && hd->homunculus.rename_flag ? 0x1 : 0x0) | (hd->homunculus.vaporize == HOM_ST_REST ? 0x2 : 0) | (hd->homunculus.hp > 0 ? 0x4 : 0);
WBUFW(buf,27)=hd->homunculus.level;
WBUFW(buf,29)=hd->homunculus.hunger;
WBUFW(buf,31)=(unsigned short) (hd->homunculus.intimacy / 100) ;
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 45e9af2b0..1e47053fe 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -134,25 +134,25 @@ int homunculus_dead(struct homun_data *hd) {
}
//Vaporize a character's homun. If flag, HP needs to be 80% or above.
-int homunculus_vaporize(struct map_session_data *sd, int flag) {
+int homunculus_vaporize(struct map_session_data *sd, enum homun_state flag) {
struct homun_data *hd;
nullpo_ret(sd);
hd = sd->hd;
- if (!hd || hd->homunculus.vaporize)
+ if (!hd || hd->homunculus.vaporize != HOM_ST_ACTIVE)
return 0;
if (status->isdead(&hd->bl))
return 0; //Can't vaporize a dead homun.
- if (flag && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80)
+ if (flag == HOM_ST_REST && get_percentage(hd->battle_status.hp, hd->battle_status.max_hp) < 80)
return 0;
hd->regen.state.block = 3; //Block regen while vaporized.
//Delete timers when vaporized.
homun->hunger_timer_delete(hd);
- hd->homunculus.vaporize = 1;
+ hd->homunculus.vaporize = flag;
if(battle_config.hom_setting&0x40)
memset(hd->blockskill, 0, sizeof(hd->blockskill));
clif->hominfo(sd, sd->hd, 0);
@@ -260,7 +260,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) {
int i = 0 ;
nullpo_retv(hd);
- if(hd->homunculus.vaporize)
+ if(hd->homunculus.vaporize != HOM_ST_ACTIVE)
return;
i = skill_id - HM_SKILLBASE;
@@ -471,7 +471,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) {
int homunculus_gainexp(struct homun_data *hd,unsigned int exp) {
enum homun_type htype;
- if(hd->homunculus.vaporize)
+ if(hd->homunculus.vaporize != HOM_ST_ACTIVE)
return 1;
if( (htype = homun->class2type(hd->homunculus.class_)) == HT_INVALID ) {
@@ -571,7 +571,7 @@ unsigned char homunculus_menu(struct map_session_data *sd,unsigned char menu_num
bool homunculus_feed(struct map_session_data *sd, struct homun_data *hd) {
int i, foodID, emotion;
- if(hd->homunculus.vaporize)
+ if(hd->homunculus.vaporize == HOM_ST_REST)
return false;
foodID = hd->homunculusDB->foodID;
@@ -781,11 +781,11 @@ bool homunculus_call(struct map_session_data *sd) {
hd = sd->hd;
- if (!hd->homunculus.vaporize)
+ if (hd->homunculus.vaporize != HOM_ST_REST)
return false; //Can't use this if homun wasn't vaporized.
homun->init_timers(hd);
- hd->homunculus.vaporize = 0;
+ hd->homunculus.vaporize = HOM_ST_ACTIVE;
if (hd->bl.prev == NULL) { //Spawn him
hd->bl.x = sd->bl.x;
hd->bl.y = sd->bl.y;
@@ -833,7 +833,7 @@ bool homunculus_recv_data(int account_id, struct s_homunculus *sh, int flag) {
homun->create(sd, sh);
hd = sd->hd;
- if(hd && hd->homunculus.hp && !hd->homunculus.vaporize && hd->bl.prev == NULL && sd->bl.prev != NULL) {
+ if(hd && hd->homunculus.hp && hd->homunculus.vaporize == HOM_ST_ACTIVE && hd->bl.prev == NULL && sd->bl.prev != NULL) {
enum homun_type htype = homun->class2type(hd->homunculus.class_);
map->addblock(&hd->bl);
@@ -908,7 +908,7 @@ bool homunculus_ressurect(struct map_session_data* sd, unsigned char per, short
hd = sd->hd;
- if (hd->homunculus.vaporize)
+ if (hd->homunculus.vaporize != HOM_ST_ACTIVE)
return false; // vaporized homunculi need to be 'called'
if (!status->isdead(&hd->bl))
diff --git a/src/map/homunculus.h b/src/map/homunculus.h
index 9562ed5c3..2cb558930 100644
--- a/src/map/homunculus.h
+++ b/src/map/homunculus.h
@@ -11,7 +11,7 @@
#define MAX_HOM_SKILL_REQUIRE 5
#define homdb_checkid(id) (id >= HM_CLASS_BASE && id <= HM_CLASS_MAX)
-#define homun_alive(x) ((x) && (x)->homunculus.vaporize != 1 && (x)->battle_status.hp > 0)
+#define homun_alive(x) ((x) && (x)->homunculus.vaporize == HOM_ST_ACTIVE && (x)->battle_status.hp > 0)
struct h_stats {
unsigned int HP, SP;
@@ -44,6 +44,12 @@ enum {
SP_HUNGRY = 0x2,
};
+enum homun_state {
+ HOM_ST_ACTIVE = 0,/* either alive or dead */
+ HOM_ST_REST = 1,/* is resting (vaporized) */
+ HOM_ST_MORPH = 2,/* in morph state */
+};
+
struct homun_data {
struct block_list bl;
struct unit_data ud;
@@ -94,7 +100,7 @@ struct homunculus_interface {
enum homun_type (*class2type) (int class_);
void (*damaged) (struct homun_data *hd);
int (*dead) (struct homun_data *hd);
- int (*vaporize) (struct map_session_data *sd, int flag);
+ int (*vaporize) (struct map_session_data *sd, enum homun_state flag);
int (*delete) (struct homun_data *hd, int emote);
int (*checkskill) (struct homun_data *hd, uint16 skill_id);
int (*calc_skilltree) (struct homun_data *hd, int flag_evolve);
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index fe67ebbef..0f46c1c01 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -40,6 +40,7 @@ enum item_itemid {
ITEMID_RED_GEMSTONE = 716,
ITEMID_BLUE_GEMSTONE = 717,
ITEMID_TRAP = 1065,
+ ITEMID_STRANGE_EMBRYO = 6415,
ITEMID_FACE_PAINT = 6120,
ITEMID_STONE = 7049,
ITEMID_SKULL_ = 7420,
diff --git a/src/map/pc.c b/src/map/pc.c
index ffc3427c7..157d9e28a 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -6438,7 +6438,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
pc->setoption(sd, i);
if( homun_alive(sd->hd) && pc->checkskill(sd, AM_CALLHOMUN) )
- homun->vaporize(sd, 0);
+ homun->vaporize(sd, HOM_ST_ACTIVE);
}
for( i = 1; i < MAX_SKILL; i++ ) {
@@ -6663,7 +6663,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
if (sd->status.hom_id > 0){
if(battle_config.homunculus_auto_vapor && sd->hd && !sd->hd->sc.data[SC_LIGHT_OF_REGENE])
- homun->vaporize(sd, 0);
+ homun->vaporize(sd, HOM_ST_ACTIVE);
}
if( sd->md )
@@ -7588,7 +7588,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
pc->setoption(sd, i);
if(homun_alive(sd->hd) && !pc->checkskill(sd, AM_CALLHOMUN))
- homun->vaporize(sd, 0);
+ homun->vaporize(sd, HOM_ST_ACTIVE);
if(sd->status.manner < 0)
clif->changestatus(sd,SP_MANNER,sd->status.manner);
diff --git a/src/map/script.c b/src/map/script.c
index 8460b23b0..1bedb78b6 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -6780,7 +6780,7 @@ BUILDIN(strnpcinfo) {
}
/*==========================================
- * GetEquipID(Pos); Pos: 1-10
+ * GetEquipID(Pos); Pos: 1-SCRIPT_EQUIP_TABLE_SIZE
*------------------------------------------*/
BUILDIN(getequipid)
{
@@ -9564,44 +9564,82 @@ BUILDIN(homunculus_evolution)
/*==========================================
* [Xantara]
+ * Checks for vaporized morph state
+ * and deletes ITEMID_STRANGE_EMBRYO.
*------------------------------------------*/
BUILDIN(homunculus_mutate) {
int homun_id;
enum homun_type m_class, m_id;
TBL_PC *sd;
+ bool success = false;
sd = script->rid2sd(st);
if( sd == NULL || sd->hd == NULL )
return true;
-
- if( script_hasdata(st,2) )
- homun_id = script_getnum(st,2);
- else
- homun_id = 6048 + (rnd() % 4);
-
- if( homun_alive(sd->hd) ) {
+
+ if( sd->hd->homunculus.vaporize == HOM_ST_MORPH ) {
+ int i = pc->search_inventory(sd, ITEMID_STRANGE_EMBRYO);
+ if( script_hasdata(st,2) )
+ homun_id = script_getnum(st,2);
+ else
+ homun_id = 6048 + (rnd() % 4);
+
m_class = homun->class2type(sd->hd->homunculus.class_);
m_id = homun->class2type(homun_id);
- if( m_class != HT_INVALID && m_id != HT_INVALID && m_class == HT_EVO && m_id == HT_S && sd->hd->homunculus.level >= 99 )
+ if( m_class == HT_EVO && m_id == HT_S &&
+ sd->hd->homunculus.level >= 99 && i >= 0 &&
+ !pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_SCRIPT) ) {
+ sd->hd->homunculus.vaporize = HOM_ST_REST; // Remove morph state.
+ homun->call(sd); // Respawn homunculus.
homun->mutate(sd->hd, homun_id);
- else
+ success = true;
+ } else
clif->emotion(&sd->hd->bl, E_SWT);
- }
+ } else
+ clif->emotion(&sd->hd->bl, E_SWT);
+
+ script_pushint(st,success?1:0);
return true;
}
-// [Zephyrus]
-BUILDIN(homunculus_shuffle) {
+/*==========================================
+ * Puts homunculus into morph state
+ * and gives ITEMID_STRANGE_EMBRYO.
+ *------------------------------------------*/
+BUILDIN(homunculus_morphembryo) {
+ enum homun_type m_class;
+ int i = 0;
TBL_PC *sd;
+ bool success = false;
- sd=script->rid2sd(st);
- if( sd == NULL )
+ sd = script->rid2sd(st);
+ if( sd == NULL || sd->hd == NULL )
return true;
- if(homun_alive(sd->hd))
- homun->shuffle(sd->hd);
+ if( homun_alive(sd->hd) ) {
+ m_class = homun->class2type(sd->hd->homunculus.class_);
+
+ if ( m_class == HT_EVO && sd->hd->homunculus.level >= 99 ) {
+ struct item item_tmp;
+
+ memset(&item_tmp, 0, sizeof(item_tmp));
+ item_tmp.nameid = ITEMID_STRANGE_EMBRYO;
+ item_tmp.identify = 1;
+
+ if( (i = pc->additem(sd, &item_tmp, 1, LOG_TYPE_SCRIPT)) ) {
+ clif->additem(sd, 0, 0, i);
+ clif->emotion(&sd->hd->bl, E_SWT);
+ } else {
+ homun->vaporize(sd, HOM_ST_MORPH);
+ success = true;
+ }
+ } else
+ clif->emotion(&sd->hd->bl, E_SWT);
+ } else
+ clif->emotion(&sd->hd->bl, E_SWT);
+ script_pushint(st, success?1:0);
return true;
}
@@ -9612,21 +9650,29 @@ BUILDIN(homunculus_shuffle) {
* 1 = Homunculus is vaporized (rest)
* 2 = Homunculus is in morph state
*------------------------------------------*/
-BUILDIN(checkhomcall)
-{
+BUILDIN(homunculus_checkcall) {
TBL_PC *sd = script->rid2sd(st);
- TBL_HOM *hd;
- if( sd == NULL )
- return false;
-
- hd = sd->hd;
-
- if( !hd )
+ if( sd == NULL || !sd->hd )
script_pushint(st, -1);
else
- script_pushint(st, hd->homunculus.vaporize);
+ script_pushint(st, sd->hd->homunculus.vaporize);
+
+ return true;
+}
+
+// [Zephyrus]
+BUILDIN(homunculus_shuffle) {
+ TBL_PC *sd;
+
+ sd=script->rid2sd(st);
+ if( sd == NULL )
+ return true;
+
+ if(homun_alive(sd->hd))
+ homun->shuffle(sd->hd);
+
return true;
}
@@ -12166,12 +12212,9 @@ BUILDIN(getpetinfo)
BUILDIN(gethominfo)
{
TBL_PC *sd=script->rid2sd(st);
- TBL_HOM *hd;
- int type=script_getnum(st,2);
+ int type = script_getnum(st,2);
- hd = sd?sd->hd:NULL;
- if(!homun_alive(hd))
- {
+ if(!sd || !sd->hd) {
if (type == 2)
script_pushconststr(st,"null");
else
@@ -12180,13 +12223,13 @@ BUILDIN(gethominfo)
}
switch(type){
- case 0: script_pushint(st,hd->homunculus.hom_id); break;
- case 1: script_pushint(st,hd->homunculus.class_); break;
- case 2: script_pushstrcopy(st,hd->homunculus.name); break;
- case 3: script_pushint(st,hd->homunculus.intimacy); break;
- case 4: script_pushint(st,hd->homunculus.hunger); break;
- case 5: script_pushint(st,hd->homunculus.rename_flag); break;
- case 6: script_pushint(st,hd->homunculus.level); break;
+ case 0: script_pushint(st,sd->hd->homunculus.hom_id); break;
+ case 1: script_pushint(st,sd->hd->homunculus.class_); break;
+ case 2: script_pushstrcopy(st,sd->hd->homunculus.name); break;
+ case 3: script_pushint(st,sd->hd->homunculus.intimacy); break;
+ case 4: script_pushint(st,sd->hd->homunculus.hunger); break;
+ case 5: script_pushint(st,sd->hd->homunculus.rename_flag); break;
+ case 6: script_pushint(st,sd->hd->homunculus.level); break;
default:
script_pushint(st,0);
break;
@@ -17655,8 +17698,9 @@ void script_parse_builtin(void) {
BUILDIN_DEF(warpportal,"iisii"),
BUILDIN_DEF2(homunculus_evolution,"homevolution",""), //[orn]
BUILDIN_DEF2(homunculus_mutate,"hommutate","?"),
+ BUILDIN_DEF2(homunculus_morphembryo,"morphembryo",""),
+ BUILDIN_DEF2(homunculus_checkcall,"checkhomcall",""),
BUILDIN_DEF2(homunculus_shuffle,"homshuffle",""), //[Zephyrus]
- BUILDIN_DEF(checkhomcall,""),
BUILDIN_DEF(eaclass,"?"), //[Skotlex]
BUILDIN_DEF(roclass,"i?"), //[Skotlex]
BUILDIN_DEF(checkvending,"?"),
diff --git a/src/map/skill.c b/src/map/skill.c
index 248e19e77..82a584ce2 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -7516,7 +7516,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AM_REST:
if (sd) {
- if (homun->vaporize(sd,1))
+ if (homun->vaporize(sd,HOM_ST_REST))
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
else
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
diff --git a/src/map/status.c b/src/map/status.c
index 497d02bbf..ae900e04d 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -8230,7 +8230,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( pc_isridingwug(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_WUGRIDER);
if( pc_isfalcon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_FALCON);
if( sd->status.pet_id > 0 ) pet->menu(sd, 3);
- if( homun_alive(sd->hd) ) homun->vaporize(sd,1);
+ if( homun_alive(sd->hd) ) homun->vaporize(sd,HOM_ST_REST);
if( sd->md ) mercenary->delete(sd->md,3);
}
break;