Jump to content

Squall

Members
  • Posts

    18
  • Joined

  • Last visited

Posts posted by Squall

  1. Crash again...

     

    0PhtOnx.png

    int skill_detonator(struct block_list *bl, va_list ap)
    {
    	struct skill_unit *unit=NULL;
    	struct block_list *src;
    	int unit_id;
    
    	nullpo_ret(bl);
    	nullpo_ret(ap);
    	src = va_arg(ap,struct block_list *);
    
    	if( bl->type != BL_SKILL || (unit = (struct skill_unit *)bl) == NULL || !unit->group )
    		return 0;
    	if( unit->group->src_id != src->id )
    		return 0;
    
    	unit_id = unit->group->unit_id;
    	switch( unit_id )
    	{ //List of Hunter and Ranger Traps that can be detonate.
    		case UNT_BLASTMINE:
    		case UNT_SANDMAN:
    		case UNT_CLAYMORETRAP:
    		case UNT_TALKIEBOX:
    		case UNT_CLUSTERBOMB:
    		case UNT_FIRINGTRAP:
    		case UNT_ICEBOUNDTRAP:
    			if( unit_id == UNT_TALKIEBOX )
    			{
    				clif_talkiebox(bl,unit->group->valstr);
    				unit->group->val2 = -1;
    			}
    			else
    				map_foreachinrange(skill_trap_splash,bl,skill_get_splash(unit->group->skill_id,unit->group->skill_lv),unit->group->bl_flag,bl,unit->group->tick);
    
    			clif_changetraplook(bl,unit_id == UNT_FIRINGTRAP ? UNT_DUMMYSKILL : UNT_USED_TRAPS);
    			unit->group->unit_id = UNT_USED_TRAPS;
    			unit->group->limit = DIFF_TICK(gettick(),unit->group->tick) +
    				(unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : 1500) );
    			break;
    	}
    	return 0;
    }
    

    Line 15519: clif_changetraplook(bl,unit_id == UNT_FIRINGTRAP ? UNT_DUMMYSKILL : UNT_USED_TRAPS);

     

     

     

     

    My map server not online for 1 day, always appears a different crash. Is it better to give up?

  2. Thanks, I'll try.


    This info appears randomly, so my suspicion about skill_delunit () be the source of problems ..

     

    J1wgMRl.png


    int skill_delunit (struct skill_unit* unit) {
    	struct skill_unit_group *group;
    
    	nullpo_ret(unit);
    	if( !unit->alive )
    		return 0;
    	unit->alive=0;
    
    	nullpo_ret(group=unit->group);
    
    	if( group->state.song_dance&0x1 ) //Cancel dissonance effect.
    		skill_dance_overlap(unit, 0);
    
    	// invoke onout event
    	if( !unit->range )
    		map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
    
    	// perform ondelete actions
    	switch (group->skill_id) {
    		case HT_ANKLESNARE: {
    				struct block_list* target = map_id2bl(group->val2);
    				if( target )
    					status_change_end(target, SC_ANKLE, INVALID_TIMER);
    			}
    			break;
    		case WZ_ICEWALL:
    			map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
    			clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug
    			skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
    			map[unit->bl.m].icewall_num--;
    			break;
    		case SA_LANDPROTECTOR:
    			skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
    			break;
    		case HP_BASILICA:
    			skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
    			// Because of Basilica's range we need to specifically update the players inside when it's cancelled prematurely
    			map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,0,4);
    			break;
    		case RA_ELECTRICSHOCKER: {
    				struct block_list* target = map_id2bl(group->val2);
    				if( target )
    					status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER);
    			}
    			break;
    		case SC_MAELSTROM:
    			skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false);
    			break;
    		case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info)
    			if( group->val2 ) { // Someone Traped
    				struct status_change *tsc = status_get_sc( map_id2bl(group->val2));
    				if( tsc && tsc->data[SC__MANHOLE] )
    					tsc->data[SC__MANHOLE]->val4 = 0; // Remove the Unit ID
    			}
    			break;
    	}
    
    	clif_skill_delunit(unit);
    
    	unit->group=NULL;
    	map_delblock(&unit->bl); // don't free yet
    	map_deliddb(&unit->bl);
    	idb_remove(skillunit_db, unit->bl.id);
    	if(--group->alive_count==0)
    		skill_delunitgroup(group);
    
    	return 0;
    }

     

    Line 15895 is: nullpo_ret(unit);

  3. case GN_FIRE_EXPANSION: {
    		int i;
    		struct unit_data *ud = unit_bl2ud(src);
    
    		if( !ud ) break;
    
    		for( i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i]; i ++ ) {
    			if( ud->skillunit[i]->skill_id == GN_DEMONIC_FIRE &&
    			   distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 4 ) {
    				switch( skill_lv ) {
    					case 3:
    						ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_SMOKE_POWDER;
    						clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_SMOKE_POWDER);
    						break;
    					case 4:
    						ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_TEAR_GAS;
    						clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_TEAR_GAS);
    						break;
    					case 5:
    						map_foreachinarea(skill_area_sub, src->m,
    										  ud->skillunit[i]->unit->bl.x - 3, ud->skillunit[i]->unit->bl.y - 3,
    										  ud->skillunit[i]->unit->bl.x + 3, ud->skillunit[i]->unit->bl.y + 3, BL_CHAR,
    										  src, CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : skill_lv, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill_castend_damage_id);
    						skill_delunit(ud->skillunit[i]->unit);
    						break;
    					default:
    						ud->skillunit[i]->unit->val2 = skill_lv;
    						ud->skillunit[i]->unit->group->val2 = skill_lv;
    						break;
    					}
    				}
    			}
    		}
    		break;
    

    Line 10895: skill_delunit(ud->skillunit->unit);

     

     

    Function skill_casend_pos2():

    int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
    {
    	struct map_session_data* sd;
    	struct status_change* sc;
    	struct status_change_entry *sce;
    	struct skill_unit_group* sg;
    	enum sc_type type;
    	int i;
    
    	//if(skill_lv <= 0) return 0;
    	if(skill_id > 0 && !skill_lv) return 0;	// celest
    
    	nullpo_ret(src);
    
    	if(status_isdead(src))
    		return 0;
    
    	sd = BL_CAST(BL_PC, src);
    
    	sc = status_get_sc(src);
    	type = status_skill2sc(skill_id);
    	sce = (sc && type != -1)?sc->data[type]:NULL;
    
    	switch (skill_id) { //Skill effect.
    		case WZ_METEOR:
    		case MO_BODYRELOCATION:
    		case CR_CULTIVATION:
    		case HW_GANBANTEIN:
    		case LG_EARTHDRIVE:
    			break; //Effect is displayed on respective switch case.
    		default:
    			if(skill_get_inf(skill_id)&INF_SELF_SKILL)
    				clif_skill_nodamage(src,src,skill_id,skill_lv,1);
    			else
    				clif_skill_poseffect(src,skill_id,skill_lv,x,y,tick);
    	}
    
    	// SC_MAGICPOWER needs to switch states before any damage is actually dealt
    	skill_toggle_magicpower(src, skill_id);
    
    	switch(skill_id)
    	{
    	case PR_BENEDICTIO:
    		skill_area_temp[1] = src->id;
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea(skill_area_sub,
    			src->m, x-i, y-i, x+i, y+i, BL_PC,
    			src, skill_id, skill_lv, tick, flag|BCT_ALL|1,
    			skill_castend_nodamage_id);
    		map_foreachinarea(skill_area_sub,
    			src->m, x-i, y-i, x+i, y+i, BL_CHAR,
    			src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1,
    			skill_castend_damage_id);
    		break;
    
    	case BS_HAMMERFALL:
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea (skill_area_sub,
    			src->m, x-i, y-i, x+i, y+i, BL_CHAR,
    			src, skill_id, skill_lv, tick, flag|BCT_ENEMY|2,
    			skill_castend_nodamage_id);
    		break;
    
    	case HT_DETECTING:
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea( status_change_timer_sub,
    			src->m, x-i, y-i, x+i,y+i,BL_CHAR,
    			src,NULL,SC_SIGHT,tick);
    		if(battle_config.traps_setting&1)
    		map_foreachinarea( skill_reveal_trap,
    			src->m, x-i, y-i, x+i,y+i,BL_SKILL);
    		break;
    
    	case SR_RIDEINLIGHTNING:
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
    			src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
    		break;
    
    	case SA_VOLCANO:
    	case SA_DELUGE:
    	case SA_VIOLENTGALE:
    	{	//Does not consumes if the skill is already active. [Skotlex]
    		struct skill_unit_group *sg;
    		if ((sg= skill_locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
    		{
    			if (sg->limit - DIFF_TICK(gettick(), sg->tick) > 0)
    			{
    				skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    				return 0; // not to consume items
    			}
    			else
    				sg->limit = 0; //Disable it.
    		}
    		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    		break;
    	}
    	case MG_SAFETYWALL:
    	case MG_FIREWALL:
    	case MG_THUNDERSTORM:
    
    	case AL_PNEUMA:
    	case WZ_ICEWALL:
    	case WZ_FIREPILLAR:
    	case WZ_QUAGMIRE:
    	case WZ_VERMILION:
    	case WZ_STORMGUST:
    	case WZ_HEAVENDRIVE:
    	case PR_SANCTUARY:
    	case PR_MAGNUS:
    	case CR_GRANDCROSS:
    	case NPC_GRANDDARKNESS:
    	case HT_SKIDTRAP:
    	case MA_SKIDTRAP:
    	case HT_LANDMINE:
    	case MA_LANDMINE:
    	case HT_ANKLESNARE:
    	case HT_SHOCKWAVE:
    	case HT_SANDMAN:
    	case MA_SANDMAN:
    	case HT_FLASHER:
    	case HT_FREEZINGTRAP:
    	case MA_FREEZINGTRAP:
    	case HT_BLASTMINE:
    	case HT_CLAYMORETRAP:
    	case AS_VENOMDUST:
    	case AM_DEMONSTRATION:
    	case PF_FOGWALL:
    	case PF_SPIDERWEB:
    	case HT_TALKIEBOX:
    	case WE_CALLPARTNER:
    	case WE_CALLPARENT:
    	case WE_CALLBABY:
    	case AC_SHOWER:	//Ground-placed skill implementation.
    	case MA_SHOWER:
    	case SA_LANDPROTECTOR:
    	case BD_LULLABY:
    	case BD_RICHMANKIM:
    	case BD_ETERNALCHAOS:
    	case BD_DRUMBATTLEFIELD:
    	case BD_RINGNIBELUNGEN:
    	case BD_ROKISWEIL:
    	case BD_INTOABYSS:
    	case BD_SIEGFRIED:
    	case BA_DISSONANCE:
    	case BA_POEMBRAGI:
    	case BA_WHISTLE:
    	case BA_ASSASSINCROSS:
    	case BA_APPLEIDUN:
    	case DC_UGLYDANCE:
    	case DC_HUMMING:
    	case DC_DONTFORGETME:
    	case DC_FORTUNEKISS:
    	case DC_SERVICEFORYOU:
    	case CG_MOONLIT:
    	case GS_DESPERADO:
    	case NJ_KAENSIN:
    	case NJ_BAKUENRYU:
    	case NJ_SUITON:
    	case NJ_HYOUSYOURAKU:
    	case NJ_RAIGEKISAI:
    	case NJ_KAMAITACHI:
    #ifdef RENEWAL
    	case NJ_HUUMA:
    #endif
    	case NPC_EVILLAND:
    	case RA_ELECTRICSHOCKER:
    	case RA_CLUSTERBOMB:
    	case RA_MAGENTATRAP:
    	case RA_COBALTTRAP:
    	case RA_MAIZETRAP:
    	case RA_VERDURETRAP:
    	case RA_FIRINGTRAP:
    	case RA_ICEBOUNDTRAP:
    	case SC_MANHOLE:
    	case SC_DIMENSIONDOOR:
    	case SC_CHAOSPANIC:
    	case SC_MAELSTROM:
    	case SC_BLOODYLUST:
    	case WM_REVERBERATION:
    	case WM_SEVERE_RAINSTORM:
    	case WM_POEMOFNETHERWORLD:
    	case SO_PSYCHIC_WAVE:
    	case SO_VACUUM_EXTREME:
    	case GN_WALLOFTHORN:
    	case GN_THORNS_TRAP:
    	case GN_DEMONIC_FIRE:
    	case GN_HELLS_PLANT:
    	case SO_EARTHGRAVE:
    	case SO_DIAMONDDUST:
    	case SO_FIRE_INSIGNIA:
    	case SO_WATER_INSIGNIA:
    	case SO_WIND_INSIGNIA:
    	case SO_EARTH_INSIGNIA:
    	case KO_HUUMARANKA:
    	case KO_MUCHANAGE:
    	case KO_BAKURETSU:
    	case KO_ZENKAI:
    	case MH_LAVA_SLIDE:
    	case MH_VOLCANIC_ASH:
    	case MH_POISON_MIST:
    	case MH_STEINWAND:
    	case MH_XENO_SLASHER:
    		flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
    	case GS_GROUNDDRIFT: //Ammo should be deleted right away.
    		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    		break;
    	case RG_GRAFFITI:			/* Graffiti [Valaris] */
    		skill_clear_unitgroup(src);
    		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    		flag|=1;
    		break;
    	case HP_BASILICA:
    		if( sc->data[SC_BASILICA] ) {
    			status_change_end(src, SC_BASILICA, INVALID_TIMER); // Cancel Basilica and return so requirement isn't consumed again
    			return 0;
    		} else { // Create Basilica. Start SC on caster. Unit timer start SC on others.
    			if( map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) ) {
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL,0);
    				return 0;
    			}
    			skill_clear_unitgroup(src);
    			if( skill_unitsetting(src,skill_id,skill_lv,x,y,0) )
    				sc_start4(src,src,type,100,skill_lv,0,0,src->id,skill_get_time(skill_id,skill_lv));
    			flag|=1;
    		}
    		break;
    	case CG_HERMODE:
    		skill_clear_unitgroup(src);
    		if ((sg = skill_unitsetting(src,skill_id,skill_lv,x,y,0)))
    			sc_start4(src,src,SC_DANCING,100,
    				skill_id,0,skill_lv,sg->group_id,skill_get_time(skill_id,skill_lv));
    		flag|=1;
    		break;
    	case RG_CLEANER: // [Valaris]
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL);
    		break;
    
    	case SO_WARMER:
    		flag|= 8;
    	case SO_CLOUD_KILL:
    		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    		break;
    
    	case WZ_METEOR: {
    			int area = skill_get_splash(skill_id, skill_lv);
    			short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
    
    			for( i = 0; i < 2 + (skill_lv>>1); i++ ) {
    				// Creates a random Cell in the Splash Area
    				tmpx = x - area + rnd()%(area * 2 + 1);
    				tmpy = y - area + rnd()%(area * 2 + 1);
    
    				if( i == 0 && path_search_long(NULL, src->m, src->x, src->y, tmpx, tmpy, CELL_CHKWALL) )
    					clif_skill_poseffect(src,skill_id,skill_lv,tmpx,tmpy,tick);
    
    				if( i > 0 )
    					skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skill_id,skill_lv,(x1<<16)|y1,0);
    
    				x1 = tmpx;
    				y1 = tmpy;
    			}
    
    			skill_addtimerskill(src,tick+i*1000,0,tmpx,tmpy,skill_id,skill_lv,-1,0);
    		}
    		break;
    
    	case AL_WARP:
    		if(sd)
    		{
    			clif_skill_warppoint(sd, skill_id, skill_lv, sd->status.save_point.map,
    				(skill_lv >= 2) ? sd->status.memo_point[0].map : 0,
    				(skill_lv >= 3) ? sd->status.memo_point[1].map : 0,
    				(skill_lv >= 4) ? sd->status.memo_point[2].map : 0
    			);
    		}
    		if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
    			status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
    		return 0; // not to consume item.
    
    	case MO_BODYRELOCATION:
    		if (unit_movepos(src, x, y, 1, 1)) {
    #if PACKETVER >= 20111005
    			clif_snap(src, src->x, src->y);
    #else
    			clif_skill_poseffect(src,skill_id,skill_lv,src->x,src->y,tick);
    #endif
    			if (sd)
    				skill_blockpc_start (sd, MO_EXTREMITYFIST, 2000);
    		}
    		break;
    	case NJ_SHADOWJUMP:
    		if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground ) { //You don't move on GVG grounds.
    			unit_movepos(src, x, y, 1, 0);
    			clif_slide(src,x,y);
    		}
    		status_change_end(src, SC_HIDING, INVALID_TIMER);
    		break;
    	case AM_SPHEREMINE:
    	case AM_CANNIBALIZE:
    		{
    			int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
    			//int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
    			int class_ = skill_id==AM_SPHEREMINE?1142:summons[skill_lv-1];
    			int ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
    			struct mob_data *md;
    
    			// Correct info, don't change any of this! [celest]
    			md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, ai);
    			if (md) {
    				md->master_id = src->id;
    				md->special_state.ai = (enum mob_ai)ai;
    				if( md->deletetimer != INVALID_TIMER )
    					delete_timer(md->deletetimer, mob_timer_delete);
    				md->deletetimer = add_timer (gettick() + skill_get_time(skill_id,skill_lv), mob_timer_delete, md->bl.id, 0);
    				mob_spawn (md); //Now it is ready for spawning.
    			}
    		}
    		break;
    
    	// Slim Pitcher [Celest]
    	case CR_SLIMPITCHER:
    		if (sd) {
    		int i = 0, j = 0;
    		struct skill_condition require = skill_get_requirement(sd, skill_id, skill_lv);
    		i = skill_lv%11 - 1;
    		j = pc_search_inventory(sd, require.itemid[i]);
    		if (j < 0 || require.itemid[i] <= 0 || sd->inventory_data[j] == NULL || sd->status.inventory[j].amount < require.amount[i])
    			{
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
    				return 1;
    			}
    			potion_flag = 1;
    			potion_hp = 0;
    			potion_sp = 0;
    			run_script(sd->inventory_data[j]->script,0,sd->bl.id,0);
    			potion_flag = 0;
    			//Apply skill bonuses
    			i = pc_checkskill(sd,CR_SLIMPITCHER)*10
    				+ pc_checkskill(sd,AM_POTIONPITCHER)*10
    				+ pc_checkskill(sd,AM_LEARNINGPOTION)*5
    				+ pc_skillheal_bonus(sd, skill_id);
    
    			potion_hp = potion_hp * (100+i)/100;
    			potion_sp = potion_sp * (100+i)/100;
    
    			if(potion_hp > 0 || potion_sp > 0) {
    				i = skill_get_splash(skill_id, skill_lv);
    				map_foreachinarea(skill_area_sub,
    					src->m,x-i,y-i,x+i,y+i,BL_CHAR,
    					src,skill_id,skill_lv,tick,flag|BCT_PARTY|BCT_GUILD|1,
    					skill_castend_nodamage_id);
    			}
    		} else {
    			int i = skill_get_itemid(skill_id, skill_lv);
    			struct item_data *item;
    			item = itemdb_search(i);
    			potion_flag = 1;
    			potion_hp = 0;
    			potion_sp = 0;
    			run_script(item->script,0,src->id,0);
    			potion_flag = 0;
    			i = skill_get_max(CR_SLIMPITCHER)*10;
    
    			potion_hp = potion_hp * (100+i)/100;
    			potion_sp = potion_sp * (100+i)/100;
    
    			if(potion_hp > 0 || potion_sp > 0) {
    				i = skill_get_splash(skill_id, skill_lv);
    				map_foreachinarea(skill_area_sub,
    					src->m,x-i,y-i,x+i,y+i,BL_CHAR,
    					src,skill_id,skill_lv,tick,flag|BCT_PARTY|BCT_GUILD|1,
    						skill_castend_nodamage_id);
    			}
    		}
    		break;
    
    	case HW_GANBANTEIN:
    		if (rnd()%100 < 80) {
    			int dummy = 1;
    			clif_skill_poseffect(src,skill_id,skill_lv,x,y,tick);
    			i = skill_get_splash(skill_id, skill_lv);
    			map_foreachinarea(skill_cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src);
    		} else {
    			if (sd) clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
    			return 1;
    		}
    		break;
    
    	case HW_GRAVITATION:
    		if ((sg = skill_unitsetting(src,skill_id,skill_lv,x,y,0)))
    			sc_start4(src,src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill_get_time(skill_id,skill_lv));
    		flag|=1;
    		break;
    
    	// Plant Cultivation [Celest]
    	case CR_CULTIVATION:
    		if (sd) {
    			if( map_count_oncell(src->m,x,y,BL_CHAR) > 0 )
    			{
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
    				return 1;
    			}
    			clif_skill_poseffect(src,skill_id,skill_lv,x,y,tick);
    			if (rnd()%100 < 50) {
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
    			} else {
    				TBL_MOB* md = mob_once_spawn_sub(src, src->m, x, y, "--ja--",(skill_lv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE);
    				int i;
    				if (!md) break;
    				if ((i = skill_get_time(skill_id, skill_lv)) > 0)
    				{
    					if( md->deletetimer != INVALID_TIMER )
    						delete_timer(md->deletetimer, mob_timer_delete);
    					md->deletetimer = add_timer (tick + i, mob_timer_delete, md->bl.id, 0);
    				}
    				mob_spawn (md);
    			}
    		}
    		break;
    
    	case SG_SUN_WARM:
    	case SG_MOON_WARM:
    	case SG_STAR_WARM:
    		skill_clear_unitgroup(src);
    		if ((sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0)))
    			sc_start4(src,src,type,100,skill_lv,0,0,sg->group_id,skill_get_time(skill_id,skill_lv));
    		flag|=1;
    		break;
    
    	case PA_GOSPEL:
    		if (sce && sce->val4 == BCT_SELF)
    		{
    			status_change_end(src, SC_GOSPEL, INVALID_TIMER);
    			return 0;
    		}
    		else
    		{
    			sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0);
    			if (!sg) break;
    			if (sce)
    				status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
    			sc_start4(src,src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill_get_time(skill_id,skill_lv));
    			clif_skill_poseffect(src, skill_id, skill_lv, 0, 0, tick); // PA_GOSPEL music packet
    		}
    		break;
    	case NJ_TATAMIGAESHI:
    		if (skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0))
    			sc_start(src,src,type,100,skill_lv,skill_get_time2(skill_id,skill_lv));
    		break;
    
    	case AM_RESURRECTHOMUN:	//[orn]
    		if (sd)
    		{
    			if (!merc_resurrect_homunculus(sd, 20*skill_lv, x, y))
    			{
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
    				break;
    			}
    		}
    		break;
    
    	case RK_WINDCUTTER:
    		clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
    	case NC_COLDSLOWER:
    	case NC_ARMSCANNON:
    	case RK_DRAGONBREATH:
    		i = skill_get_splash(skill_id,skill_lv);
    		map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
    			src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
    		break;
    
    	case SO_ARRULLO:
    		i = skill_get_splash(skill_id,skill_lv);
    		map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
    			src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
    		break;
    	/**
    	 * Guilotine Cross
    	 **/
    	case GC_POISONSMOKE:
    		if( !(sc && sc->data[SC_POISONINGWEAPON]) ) {
    			if( sd )
    				clif_skill_fail(sd,skill_id,USESKILL_FAIL_GC_POISONINGWEAPON,0);
    			return 0;
    		}
    		clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
    		skill_unitsetting(src, skill_id, skill_lv, x, y, flag);
    		//status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER); // 08/31/2011 - When using poison smoke, you no longer lose the poisoning weapon effect.
    		break;
    	/**
    	 * Arch Bishop
    	 **/
    	case AB_EPICLESIS:
    		if( (sg = skill_unitsetting(src, skill_id, skill_lv, x, y, 0)) ) {
    			i = sg->unit->range;
    			map_foreachinarea(skill_area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill_castend_nodamage_id);
    		}
    		break;
    	/**
    	 * Warlock
    	 **/
    	case WL_COMET:
    		if( sc ) {
    			sc->comet_x = x;
    			sc->comet_y = y;
    		}
    		i = skill_get_splash(skill_id,skill_lv);
    		map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
    		break;
    
    	case WL_EARTHSTRAIN:
    		{
    			int i, wave = skill_lv + 4, dir = map_calc_dir(src,x,y);
    			int sx = x = src->x, sy = y = src->y; // Store first caster's location to avoid glitch on unit setting
    
    			for( i = 1; i <= wave; i++ )
    			{
    				switch( dir ){
    					case 0: case 1: case 7: sy = y + i; break;
    					case 3: case 4: case 5: sy = y - i; break;
    					case 2: sx = x - i; break;
    					case 6: sx = x + i; break;
    				}
    				skill_addtimerskill(src,gettick() + (150 * i),0,sx,sy,skill_id,skill_lv,dir,flag&2);
    			}
    		}
    		break;
    	/**
    	 * Ranger
    	 **/
    	case RA_DETONATOR:
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea(skill_detonator, src->m, x-i, y-i, x+i, y+i, BL_SKILL, src);
    		clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
    		break;
    	/**
    	 * Mechanic
    	 **/
    	case NC_NEUTRALBARRIER:
    	case NC_STEALTHFIELD:
    		if( (sc->data[SC_NEUTRALBARRIER_MASTER] && skill_id == NC_NEUTRALBARRIER) || (sc->data[SC_STEALTHFIELD_MASTER] && skill_id == NC_STEALTHFIELD) ) {
    			skill_clear_unitgroup(src);
    			return 0;
    		}
    		skill_clear_unitgroup(src); // To remove previous skills - cannot used combined
    		if( (sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) {
    			sc_start2(src,src,skill_id == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skill_lv,sg->group_id,skill_get_time(skill_id,skill_lv));
    			if( sd ) pc_overheat(sd,1);
    		}
    		break;
    
    	case NC_SILVERSNIPER:
    		{
    			int class_ = 2042;
    			struct mob_data *md;
    
    			md = mob_once_spawn_sub(src, src->m, x, y, status_get_name(src), class_, "", SZ_SMALL, AI_NONE);
    			if( md )
    			{
    				md->master_id = src->id;
    				md->special_state.ai = AI_FAW;
    				if( md->deletetimer != INVALID_TIMER )
    					delete_timer(md->deletetimer, mob_timer_delete);
    				md->deletetimer = add_timer (gettick() + skill_get_time(skill_id, skill_lv), mob_timer_delete, md->bl.id, 0);
    				mob_spawn( md );
    			}
    		}
    		break;
    
    	case NC_MAGICDECOY:
    		if( sd ) clif_magicdecoy_list(sd,skill_lv,x,y);
    		break;
    
    	case SC_FEINTBOMB:
    		clif_skill_nodamage(src,src,skill_id,skill_lv,1);
    		skill_unitsetting(src,skill_id,skill_lv,x,y,0); // Set bomb on current Position
    		if( skill_blown(src,src,6,unit_getdir(src),0) )
    			skill_castend_nodamage_id(src,src,TF_HIDING,1,tick,0);
    		break;
    
    	case LG_OVERBRAND:
    		skill_overbrand(src, skill_id, skill_lv, x, y, tick, flag);
    		break;
    
    	case LG_BANDING:
    		if( sc && sc->data[SC_BANDING] )
    			status_change_end(src,SC_BANDING,INVALID_TIMER);
    		else if( (sg = skill_unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) {
    			sc_start4(src,src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill_get_time(skill_id,skill_lv));
    			if( sd ) pc_banding(sd,skill_lv);
    		}
    		clif_skill_nodamage(src,src,skill_id,skill_lv,1);
    		break;
    
    	case LG_RAYOFGENESIS:
    		if( status_charge(src,status_get_max_hp(src)*3*skill_lv / 100,0) ) {
    			i = skill_get_splash(skill_id,skill_lv);
    			map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
    				src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
    		} else if( sd )
    			clif_skill_fail(sd,skill_id,USESKILL_FAIL,0);
    		break;
    
    	case WM_DOMINION_IMPULSE:
    		i = skill_get_splash(skill_id, skill_lv);
    		map_foreachinarea( skill_ative_reverberation,
    			src->m, x-i, y-i, x+i,y+i,BL_SKILL);
    		break;
    
    	case WM_GREAT_ECHO:
    		flag|=1; // Should counsume 1 item per skill usage.
    		map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill_castend_damage_id);
    		break;
    	case GN_CRAZYWEED: {
    			int area = skill_get_splash(GN_CRAZYWEED_ATK, skill_lv);
    			short x1 = 0, y1 = 0;
    
    			for( i = 0; i < 3 + (skill_lv/2); i++ ) {
    				x1 = x - area + rnd()%(area * 2 + 1);
    				y1 = y - area + rnd()%(area * 2 + 1);
    				skill_addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skill_lv,-1,0);
    			}
    		}
    		break;
    	case GN_FIRE_EXPANSION: {
    		int i;
    		struct unit_data *ud = unit_bl2ud(src);
    
    		if( !ud ) break;
    
    		for( i = 0; i < MAX_SKILLUNITGROUP && ud->skillunit[i]; i ++ ) {
    			if( ud->skillunit[i]->skill_id == GN_DEMONIC_FIRE &&
    			   distance_xy(x, y, ud->skillunit[i]->unit->bl.x, ud->skillunit[i]->unit->bl.y) < 4 ) {
    				switch( skill_lv ) {
    					case 3:
    						ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_SMOKE_POWDER;
    						clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_SMOKE_POWDER);
    						break;
    					case 4:
    						ud->skillunit[i]->unit_id = UNT_FIRE_EXPANSION_TEAR_GAS;
    						clif_changetraplook(&ud->skillunit[i]->unit->bl, UNT_FIRE_EXPANSION_TEAR_GAS);
    						break;
    					case 5:
    						map_foreachinarea(skill_area_sub, src->m,
    										  ud->skillunit[i]->unit->bl.x - 3, ud->skillunit[i]->unit->bl.y - 3,
    										  ud->skillunit[i]->unit->bl.x + 3, ud->skillunit[i]->unit->bl.y + 3, BL_CHAR,
    										  src, CR_ACIDDEMONSTRATION, sd ? pc_checkskill(sd, CR_ACIDDEMONSTRATION) : skill_lv, tick, flag|BCT_ENEMY|1|SD_LEVEL, skill_castend_damage_id);
    						skill_delunit(ud->skillunit[i]->unit);
    						break;
    					default:
    						ud->skillunit[i]->unit->val2 = skill_lv;
    						ud->skillunit[i]->unit->group->val2 = skill_lv;
    						break;
    					}
    				}
    			}
    		}
    		break;
    
    	case SO_FIREWALK:
    	case SO_ELECTRICWALK:
    		if( sc && sc->data[type] )
    			status_change_end(src,type,INVALID_TIMER);
    		clif_skill_nodamage(src, src ,skill_id, skill_lv,
    			sc_start2(src,src, type, 100, skill_id, skill_lv, skill_get_time(skill_id, skill_lv)));
    		break;
    
    	case KO_MAKIBISHI:
    		for( i = 0; i < (skill_lv+2); i++ ) {
    			x = src->x - 1 + rnd()%3;
    			y = src->y - 1 + rnd()%3;
    			skill_unitsetting(src,skill_id,skill_lv,x,y,0);
    		}
    		break;
    
    	default:
    		ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skill_id);
    		return 1;
    	}
    
    	if( sc && sc->data[SC_CURSEDCIRCLE_ATKER] ) //Should only remove after the skill has been casted.
    		status_change_end(src,SC_CURSEDCIRCLE_ATKER,INVALID_TIMER);
    
    	if( sd )
    	{// ensure that the skill last-cast tick is recorded
    		sd->canskill_tick = gettick();
    
    		if( sd->state.arrow_atk && !(flag&1) )
    		{// consume arrow if this is a ground skill
    			battle_consume_ammo(sd, skill_id, skill_lv);
    		}
    
    		// perform skill requirement consumption
    		skill_consume_requirement(sd,skill_id,skill_lv,2);
    	}
    
    	return 0;
    }
    

    I get the impression that this only occurs with the skills that are used in the ground...

     

     

    But will not have a way to skip this error so no more server crash?

  4. map server crash randomly, look at my debug:

     

    gJmcu6V.png

     

     

    I think the problem in this skill_delunit() function, this function look like this in my source:

    int skill_delunit (struct skill_unit* unit) {
    	struct skill_unit_group *group;
    
    	nullpo_ret(unit);
    	if( !unit->alive )
    		return 0;
    	unit->alive=0;
    
    	nullpo_ret(group=unit->group);
    
    	if( group->state.song_dance&0x1 ) //Cancel dissonance effect.
    		skill_dance_overlap(unit, 0);
    
    	// invoke onout event
    	if( !unit->range )
    		map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),4);
    
    	// perform ondelete actions
    	switch (group->skill_id) {
    		case HT_ANKLESNARE: {
    				struct block_list* target = map_id2bl(group->val2);
    				if( target )
    					status_change_end(target, SC_ANKLE, INVALID_TIMER);
    			}
    			break;
    		case WZ_ICEWALL:
    			map_setgatcell(unit->bl.m,unit->bl.x,unit->bl.y,unit->val2);
    			clif_changemapcell(0,unit->bl.m,unit->bl.x,unit->bl.y,unit->val2,ALL_SAMEMAP); // hack to avoid clientside cell bug
    			skill_unitsetmapcell(unit,WZ_ICEWALL,group->skill_lv,CELL_ICEWALL,false);
    			map[unit->bl.m].icewall_num--;
    			break;
    		case SA_LANDPROTECTOR:
    			skill_unitsetmapcell(unit,SA_LANDPROTECTOR,group->skill_lv,CELL_LANDPROTECTOR,false);
    			break;
    		case HP_BASILICA:
    			skill_unitsetmapcell(unit,HP_BASILICA,group->skill_lv,CELL_BASILICA,false);
    			// Because of Basilica's range we need to specifically update the players inside when it's cancelled prematurely
    			map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,0,4);
    			break;
    		case RA_ELECTRICSHOCKER: {
    				struct block_list* target = map_id2bl(group->val2);
    				if( target )
    					status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER);
    			}
    			break;
    		case SC_MAELSTROM:
    			skill_unitsetmapcell(unit,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false);
    			break;
    		case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info)
    			if( group->val2 ) { // Someone Traped
    				struct status_change *tsc = status_get_sc( map_id2bl(group->val2));
    				if( tsc && tsc->data[SC__MANHOLE] )
    					tsc->data[SC__MANHOLE]->val4 = 0; // Remove the Unit ID
    			}
    			break;
    	}
    
    	clif_skill_delunit(unit);
    
    	unit->group=NULL;
    	map_delblock(&unit->bl); // don't free yet
    	map_deliddb(&unit->bl);
    	idb_remove(skillunit_db, unit->bl.id);
    	if(--group->alive_count==0)
    		skill_delunitgroup(group);
    
    	return 0;
    }
    

    does have a solution or just switching the emulator to solve?

     

     

  5. Skill: Rapid Throw

     

     

     

    There are times that leaves 2 skills at the same time, very fast just click and move the cursor on the enemy as he walks towards the enemy. It fixable?

     

    //= rAthena Dev Team
    //===== Current Version: =====================================
    //= $Revision: 17421 $
    //===== Last Updated: ========================================
    //= $LastChangedDate: 2013-07-17 18:38:58 -0600 (mié, 17 jul 2013) $
  6. @lilith, Thanks for answering 

     

    Have you tested it? Because here has not changed yet. 
    Not posted in DB support area  for I believe that the error is the bonus script of the source when it is defined as negative: 
     
    bBaseAtk bonus, -20; 
    bMatkRate bonus, -10;
  7. Item Script:

    5481,Hermose_Cap,Hermode Cap,5,20,,1000,,1,,1,0xFFFFFFFF,63,2,256,,1,1,478,{ bonus bAspdRate,10; bonus bBaseAtk,-20; bonus bMatkRate,-10; },{},{}
     

    S0x4hK4.png

     

    RuRw3kf.png

     

    Why the ATK and MATK are not reduced when the item is equipped? only ASPD and DEF are changed.

×
×
  • Create New...