Przeglądaj źródła

- Killed mobs with NPC_REBIRTH skill used should not drop items again. (Aegis test)
- Monsters with SC_KAIZEL should not trigger event script until.
- Monsters NPC_REBIRTH should not be casted if no source (killmonster script or @killmonster)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13047 54d463be-8e91-2dee-dedb-b68131a5f0ec

zephyrus 17 lat temu
rodzic
commit
b19fbe57bc
3 zmienionych plików z 51 dodań i 38 usunięć
  1. 44 37
      src/map/mob.c
  2. 1 0
      src/map/mob.h
  3. 6 1
      src/map/status.c

+ 44 - 37
src/map/mob.c

@@ -2081,7 +2081,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	unsigned int mvp_damage, tick = gettick();
 	unsigned short flaghom = 1; // [Zephyrus] Does the mob only received damage from homunculus?
 
-	if(src && src->type == BL_PC) {
+	if(src && src->type == BL_PC)
+	{
 		sd = (struct map_session_data *)src;
 		mvp_sd = sd;
 	}
@@ -2091,8 +2092,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	if( md->guardian_data && md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS )
 		guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
 
-	md->state.skillstate = MSS_DEAD;	
-	mobskill_use(md,tick,-1);	//On Dead skill.
+	if( src )
+	{ // Use Dead skill only if not killed by Script or Command
+		md->state.skillstate = MSS_DEAD;	
+		mobskill_use(md,tick,-1);
+	}
 
 	map_freeblock_lock();
 
@@ -2278,14 +2282,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 	} //End EXP giving.
 	
-	if (!(type&1) &&
-		!map[m].flag.nomobloot &&
-		(
-		 	!md->special_state.ai || //Non special mob
-			battle_config.alchemist_summon_reward == 2 || //All summoned give drops
-			(md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
-		)
-	) {	//item drop
+	if( !(type&1) && !map[m].flag.nomobloot && !md->state.rebirth && (
+		!md->special_state.ai || //Non special mob
+		battle_config.alchemist_summon_reward == 2 || //All summoned give drops
+		(md->special_state.ai==2 && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items.
+		) )
+	{ // Item Drop
 		struct item_drop_list *dlist = ers_alloc(item_drop_list_ers, struct item_drop_list);
 		struct item_drop *ditem;
 		int drop_rate;
@@ -2493,32 +2495,38 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	  	//Emperium destroyed by script. Discard mvp character. [Skotlex]
 		mvp_sd = NULL;
 
-	if(md->npc_event[0] && !md->state.npc_killmonster)
-	{
-		md->status.hp = 0; //So that npc_event invoked functions KNOW that I am dead.
-		if(src) 
-		switch (src->type) {
-		case BL_PET:
-			sd = ((TBL_PET*)src)->msd;
-			break;
-		case BL_HOM:
-			sd = ((TBL_HOM*)src)->master;
-			break;
+	if( !md->sc.data[SC_KAIZEL] )
+	{ // Only trigger event on final kill
+		if( md->npc_event[0] && !md->state.npc_killmonster )
+		{
+			md->status.hp = 0; //So that npc_event invoked functions KNOW that I am dead.
+			if( src )
+				switch( src->type )
+				{
+					case BL_PET: sd = ((TBL_PET*)src)->msd; break;
+					case BL_HOM: sd = ((TBL_HOM*)src)->master; break;
+				}
+
+			if( sd && battle_config.mob_npc_event_type )
+			{
+				pc_setglobalreg(sd,"killerrid",sd->bl.id);
+				npc_event(sd,md->npc_event,0);
+			}
+			else if( mvp_sd )
+			{
+				pc_setglobalreg(mvp_sd,"killerrid",sd?sd->bl.id:0);
+				npc_event(mvp_sd,md->npc_event,0);
+			}
+			else
+				npc_event_do(md->npc_event);
+
+			md->status.hp = 1;
 		}
-		if(sd && battle_config.mob_npc_event_type) {
-			pc_setglobalreg(sd,"killerrid",sd->bl.id);
-			npc_event(sd,md->npc_event,0);
-		} else if(mvp_sd) {
-			pc_setglobalreg(mvp_sd,"killerrid",sd?sd->bl.id:0);
-			npc_event(mvp_sd,md->npc_event,0);
+		else if( mvp_sd )
+		{
+			pc_setglobalreg(mvp_sd,"killedrid",md->class_);
+			npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance]
 		}
-		else
-			npc_event_do(md->npc_event);
-			
-		md->status.hp = 1;
-	} else if (mvp_sd) {	//lordalfa
-		pc_setglobalreg(mvp_sd,"killedrid",md->class_);
-		npc_script_event(mvp_sd, NPCE_KILLNPC); // PCKillNPC [Lance]
 	}
 
 	if( md->barricade != NULL )
@@ -2534,9 +2542,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 	map_freeblock_unlock();
 
 	if(pcdb_checkid(md->vd->class_))
-	{	//Player mobs are not removed automatically by the client.
+		//Player mobs are not removed automatically by the client.
 		clif_clearunit_delayed(&md->bl, tick+3000);
-	}
 
 	if(!md->spawn) //Tell status_damage to remove it from memory.
 		return 5; // Note: Actually, it's 4. Oh well...

+ 1 - 0
src/map/mob.h

@@ -98,6 +98,7 @@ struct mob_data {
 		unsigned char attacked_count; //For rude attacked.
 		int provoke_flag; // Celest
 		unsigned npc_killmonster: 1; //for new killmonster behavior
+		unsigned rebirth: 1; // NPC_Rebirth used
 	} state;
 	struct guardian_data* guardian_data; 
 	struct {

+ 6 - 1
src/map/status.c

@@ -742,12 +742,17 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 		}
 	}
    
-	if (!(flag&8) && sc && sc->data[SC_KAIZEL]) { //flag&8 = disable Kaizel
+	if( !(flag&8) && sc && sc->data[SC_KAIZEL] )
+	{ //flag&8 = disable Kaizel
 		int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
 		status_revive(target, sc->data[SC_KAIZEL]->val2, 0);
 		status_change_clear(target,0);
 		clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
 		sc_start(target,status_skill2sc(PR_KYRIE),100,10,time);
+
+		if( target->type == BL_MOB ) 
+			((TBL_MOB*)target)->state.rebirth = 1;
+
 		return hp+sp;
 	}