таро

Тема в разделе "Ошибки", создана пользователем kop6en, 1 мар 2018.

  1. ФАРАЙ

    ФАРАЙ Игрок

    нитка не магия
    валя шмот не должен ломаться ни как
    хватит гореть с гтб
  2. Misconception

    Misconception Игрок

    то же самое что и при использовании госпела и род хермонда (простите за это слово, но оно шикарно)
  3. f0und3r

    f0und3r Игрок

    В чистом эмуляторе eAthena, таро которое ломает, имеет следующий список:
    Код:
    int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
    
    В моде, который здесь установлен, список такой же.

    Далее, вызывается функция (если персонаж не умер после 1к урона), она рандомит одно из 5 выше значений:
    Код:
    skill_break_equip(bl, where[rand()%5], 10000, BCT_ENEMY);
    
    В этой функции есть общие проверки типа:
    Код:
    if (sd) {
            if (sd->unbreakable_equip)
                where &= ~sd->unbreakable_equip;
            if (sd->unbreakable)
                rate -= rate*sd->unbreakable/100;
            if (where&EQP_WEAPON) {
                switch (sd->status.weapon) {
                    case W_FIST:    //Bare fists should not break :P
                    case W_1HAXE:
                    case W_2HAXE:
                    case W_MACE: // Axes and Maces can't be broken [DracoRPG]
                    case W_2HMACE:
                    case W_STAFF:
                    case W_2HSTAFF:
                    case W_BOOK: //Rods and Books can't be broken [Skotlex]
                    case W_HUUMA:
                        where &= ~EQP_WEAPON;
                }
            }
        }
    
    Из описания структуры:
    Код:
    unsigned short unbreakable_equip; //100% break resistance on certain equipment
    
    Но если честно, я потерялся в том, что Вам нужно уточнить, могу проверить / приложить исходники почему это так (эмулятор на котором будет проведено тестирования по механике совпадает с фриро).

    Листинги функций выше актуальны?
    Могу приложить файлы (ссылки) или вырезки из них.
  4. Misconception

    Misconception Игрок

    думаю и так норм

    должно ли ломать карта таро колесница предметы под протектом
    + должно ли ломать карто таро колесница предметы на которых указано свойство - неломаемый
  5. Red King

    Red King Read Only

    А можно узнать как-то как таро работает, скажем, на kro, ну или хотя бы на iro?
  6. kop6en

    kop6en Read Only

    я не эти функции запрашивал :)
  7. f0und3r

    f0und3r Игрок

    Беглый осмотр ниже без проверки "боем", если есть сомнения - завтра проверю, сейчас с ноута просто для информации.

    Если речь идет про bonus bUnbreakableArmor,0; (как у валькоармора), из документации эмулятора:
    Код:
    bonus bUnbreakableArmor,n;   Armor cannot be damaged/broken by any means (n is meaningless)
    
    Этот бонус как раз влияет на переменную выше:
    Код:
    case SP_UNBREAKABLE_ARMOR:
    if(sd->state.lr_flag!=2)
    sd->unbreakable_equip|= EQP_ARMOR;
    break;
    
    Валькоармор таро ломать не должно.

    По поводу ФП, оно делает следующее:
    Код:
    status_change_end(bl, (sc_type)(SC_STRIPWEAPON + i), INVALID_TIMER);
    sc_start(bl,(sc_type)(SC_CP_WEAPON + i),100,skilllv,skilltime);
    
    Опять же возращаясь к skill_break_equip, в нем есть список:
    Код:
    const enum sc_type scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM};
    
    Этот список эквипа не ломает.

    Для eAthena (без мода, который здесь есть):
    Код:
    int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
    {
    	struct map_session_data *sd;
    	struct status_change *sc;
    	struct status_change_entry *sce;
    	struct status_data *status;
    	struct view_data *vd;
    	int opt_flag=0, calc_flag;
    
    	nullpo_ret(bl);
    	
    	sc = status_get_sc(bl);
    	status = status_get_status_data(bl);
    
    	if(type < 0 || type >= SC_MAX || !sc || !(sce = sc->data[type]))
    		return 0;
    
    	sd = BL_CAST(BL_PC,bl);
    
    	if (sce->timer != tid && tid != INVALID_TIMER)
    		return 0;
    
    	if (tid == INVALID_TIMER) {
    		if (type == SC_ENDURE && sce->val4)
    			//Do not end infinite endure.
    			return 0;
    		if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
    			delete_timer(sce->timer,status_change_timer);
    		if (sc->opt1)
    		switch (type) {
    			//"Ugly workaround"  [Skotlex]
    			//delays status change ending so that a skill that sets opt1 fails to 
    			//trigger when it also removed one
    			case SC_STONE:
    				sce->val3 = 0; //Petrify time counter.
    			case SC_FREEZE:
    			case SC_STUN:
    			case SC_SLEEP:
    			if (sce->val1) {
    			  	//Removing the 'level' shouldn't affect anything in the code
    				//since these SC are not affected by it, and it lets us know
    				//if we have already delayed this attack or not.
    				sce->val1 = 0;
    				sce->timer = add_timer(gettick()+10, status_change_timer, bl->id, type);
    				return 1;
    			}
    		}
    	}
    
    	sc->data[type] = NULL;
    	(sc->count)--;
    
    	vd = status_get_viewdata(bl);
    	calc_flag = StatusChangeFlagTable[type];
    	switch(type){
    		case SC_WEDDING:
    		case SC_XMAS:
    		case SC_SUMMER:
    			if (!vd) break;
    			if (sd)
    			{	//Load data from sd->status.* as the stored values could have changed.
    				//Must remove OPTION to prevent class being rechanged.
    				sc->option &= type==SC_WEDDING?~OPTION_WEDDING:type==SC_XMAS?~OPTION_XMAS:~OPTION_SUMMER;
    				clif_changeoption(&sd->bl);
    				status_set_viewdata(bl, sd->status.class_);
    			} else {
    				vd->class_ = sce->val1;
    				vd->weapon = sce->val2;
    				vd->shield = sce->val3;
    				vd->cloth_color = sce->val4;
    			}
    			clif_changelook(bl,LOOK_BASE,vd->class_);
    			clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
    			clif_changelook(bl,LOOK_WEAPON,vd->weapon);
    			clif_changelook(bl,LOOK_SHIELD,vd->shield);
    			if(sd) clif_skillinfoblock(sd);
    		break;
    		case SC_RUN:
    		{
    			struct unit_data *ud = unit_bl2ud(bl);
    			bool begin_spurt = true;
    			if (ud) {
    				if(!ud->state.running)
    					begin_spurt = false;
    				ud->state.running = 0;
    				if (ud->walktimer != INVALID_TIMER)
    					unit_stop_walking(bl,1);
    			}
    			if (begin_spurt && sce->val1 >= 7 &&
    				DIFF_TICK(gettick(), sce->val4) <= 1000 &&
    				(!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
    			)
    				sc_start(bl,SC_SPURT,100,sce->val1,skill_get_time2(status_sc2skill(type), sce->val1));
    		}
    		break;
    		case SC_AUTOBERSERK:
    			if (sc->data[SC_PROVOKE] && sc->data[SC_PROVOKE]->val2 == 1)
    				status_change_end(bl, SC_PROVOKE, INVALID_TIMER);
    			break;
    
    		case SC_ENDURE:
    		case SC_DEFENDER:
    		case SC_REFLECTSHIELD:
    		case SC_AUTOGUARD:
    			{
    				struct map_session_data *tsd;
    				if( bl->type == BL_PC )
    				{ // Clear Status from others
    					int i;
    					for( i = 0; i < 5; i++ )
    					{
    						if( sd->devotion[i] && (tsd = map_id2sd(sd->devotion[i])) && tsd->sc.data[type] )
    							status_change_end(&tsd->bl, type, INVALID_TIMER);
    					}
    				}
    				else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag )
    				{ // Clear Status from Master
    					tsd = ((TBL_MER*)bl)->master;
    					if( tsd && tsd->sc.data[type] )
    						status_change_end(&tsd->bl, type, INVALID_TIMER);
    				}
    			}
    			break;
    		case SC_DEVOTION:
    			{
    				struct block_list *d_bl = map_id2bl(sce->val1);
    				if( d_bl )
    				{
    					if( d_bl->type == BL_PC )
    						((TBL_PC*)d_bl)->devotion[sce->val2] = 0;
    					else if( d_bl->type == BL_MER )
    						((TBL_MER*)d_bl)->devotion_flag = 0;
    					clif_devotion(d_bl, NULL);
    				}
    
    				status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
    				status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
    				status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
    				status_change_end(bl, SC_ENDURE, INVALID_TIMER);
    			}
    			break;
    
    		case SC_BLADESTOP:
    			if(sce->val4)
    			{
    				int tid = sce->val4;
    				struct block_list *tbl = map_id2bl(tid);
    				struct status_change *tsc = status_get_sc(tbl);
    				sce->val4 = 0;
    				if(tbl && tsc && tsc->data[SC_BLADESTOP])
    				{
    					tsc->data[SC_BLADESTOP]->val4 = 0;
    					status_change_end(tbl, SC_BLADESTOP, INVALID_TIMER);
    				}
    				clif_bladestop(bl, tid, 0);
    			}
    			break;
    		case SC_DANCING:
    			{
    				const char* prevfile = "<unknown>";
    				int prevline = 0;
    				struct map_session_data *dsd;
    				struct status_change_entry *dsc;
    				struct skill_unit_group *group;
    
    				if( sd )
    				{
    					if( sd->delunit_prevfile )
    					{// initially this is NULL, when a character logs in
    						prevfile = sd->delunit_prevfile;
    						prevline = sd->delunit_prevline;
    					}
    					else
    					{
    						prevfile = "<none>";
    					}
    					sd->delunit_prevfile = file;
    					sd->delunit_prevline = line;
    				}
    
    				if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4)))
    				{// end status on partner as well
    					dsc = dsd->sc.data[SC_DANCING];
    					if(dsc)
    					{	//This will prevent recursive loops. 
    						dsc->val2 = dsc->val4 = 0;
    						status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
    					}
    				}
    
    				if(sce->val2)
    				{// erase associated land skill
    					group = skill_id2group(sce->val2);
    
    					if( group == NULL )
    					{
    						ShowDebug("status_change_end: SC_DANCING is missing skill unit group (val1=%d, val2=%d, val3=%d, val4=%d, timer=%d, tid=%d, char_id=%d, map=%s, x=%d, y=%d, prev=%s:%d, from=%s:%d). Please report this! (#3504)\n",
    							sce->val1, sce->val2, sce->val3, sce->val4, sce->timer, tid,
    							sd ? sd->status.char_id : 0,
    							mapindex_id2name(map_id2index(bl->m)), bl->x, bl->y,
    							prevfile, prevline,
    							file, line);
    					}
    
    					sce->val2 = 0;
    					skill_delunitgroup(group);
    				}
    
    				if((sce->val1&0xFFFF) == CG_MOONLIT)
    					clif_status_change(bl,SI_MOONLIT,0,0);
    
    				status_change_end(bl, SC_LONGING, INVALID_TIMER);
    			}
    			break;
    		case SC_NOCHAT:
    			if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
    				sd->status.manner = 0;
    			if (sd && tid == INVALID_TIMER)
    			{
    				pc_onstatuschanged(sd,SP_MANNER);
    			}
    			break;
    		case SC_SPLASHER:	
    			{
    				struct block_list *src=map_id2bl(sce->val3);
    				if(src && tid != INVALID_TIMER)
    					skill_castend_damage_id(src, bl, sce->val2, sce->val1, gettick(), SD_LEVEL );
    			}
    			break;
    		case SC_CLOSECONFINE2:
    			{
    				struct block_list *src = sce->val2?map_id2bl(sce->val2):NULL;
    				struct status_change *sc2 = src?status_get_sc(src):NULL;
    				if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
    					//If status was already ended, do nothing.
    					//Decrease count
    					if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
    						status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
    				}
    			}
    		case SC_CLOSECONFINE:
    			if (sce->val2 > 0) {
    				//Caster has been unlocked... nearby chars need to be unlocked.
    				int range = 1
    					+skill_get_range2(bl, status_sc2skill(type), sce->val1)
    					+skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
    				map_foreachinarea(status_change_timer_sub, 
    					bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
    			}
    			break;
    		case SC_COMBO:
    			if( sd )
    			switch (sce->val1) {
    				case MO_COMBOFINISH:
    				case CH_TIGERFIST:
    				case CH_CHAINCRUSH:
    					clif_skillinfo(sd, MO_EXTREMITYFIST, 0);
    					break;
    				case TK_JUMPKICK:
    					clif_skillinfo(sd, TK_JUMPKICK, 0);
    					break;
    			}
    			break;
    
    		case SC_MARIONETTE:
    		case SC_MARIONETTE2:	/// Marionette target
    			if (sce->val1)
    			{	// check for partner and end their marionette status as well
    				enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
    				struct block_list *pbl = map_id2bl(sce->val1);
    				struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
    				
    				if (sc2 && sc2->data[type2])
    				{
    					sc2->data[type2]->val1 = 0;
    					status_change_end(pbl, type2, INVALID_TIMER);
    				}
    			}
    			break;
    
    		case SC_BERSERK:
    			//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
    			if(status->hp > 100 && sce->val2)
    				status_set_hp(bl, 100, 0); 
    			if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
    			{
    				sc->data[SC_ENDURE]->val4 = 0;
    				status_change_end(bl, SC_ENDURE, INVALID_TIMER);
    			}
    			sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill_get_time(LK_BERSERK, sce->val1));
    			break;
    		case SC_GOSPEL:
    			if (sce->val3) { //Clear the group.
    				struct skill_unit_group* group = skill_id2group(sce->val3);
    				sce->val3 = 0;
    				skill_delunitgroup(group);
    			}
    			break;
    		case SC_HERMODE: 
    			if(sce->val3 == BCT_SELF)
    				skill_clear_unitgroup(bl);
    			break;
    		case SC_BASILICA: //Clear the skill area. [Skotlex]
    				skill_clear_unitgroup(bl);
    				break;
    		case SC_TRICKDEAD:
    			if (vd) vd->dead_sit = 0;
    			break;
    		case SC_WARM:
    			if (sce->val4) { //Clear the group.
    				struct skill_unit_group* group = skill_id2group(sce->val4);
    				sce->val4 = 0;
    				skill_delunitgroup(group);
    			}
    			break;
    		case SC_KAAHI:
    			//Delete timer if it exists.
    			if (sce->val4 != INVALID_TIMER)
    				delete_timer(sce->val4,kaahi_heal_timer);
    			break;
    		case SC_JAILED:
    			if(tid == INVALID_TIMER)
    				break;
    		  	//natural expiration.
    			if(sd && sd->mapindex == sce->val2)
    				pc_setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
    			break; //guess hes not in jail :P
    		case SC_CHANGE:
    			if (tid == INVALID_TIMER)
    		 		break;
    			// "lose almost all their HP and SP" on natural expiration.
    			status_set_hp(bl, 10, 0);
    			status_set_sp(bl, 10, 0);
    			break;
    		case SC_AUTOTRADE:
    			if (tid == INVALID_TIMER)
    				break;
    			// Note: vending/buying is closed by unit_remove_map, no
    			// need to do it here.
    			map_quit(sd);
    			// Because map_quit calls status_change_end with tid -1
    			// from here it's not neccesary to continue
    			return 1;
    			break;
    		case SC_STOP:
    			if( sce->val2 )
    			{
    				struct block_list* tbl = map_id2bl(sce->val2);
    				sce->val2 = 0;
    				if( tbl && (sc = status_get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
    					status_change_end(tbl, SC_STOP, INVALID_TIMER);
    			}
    			break;
    		}
    
    	opt_flag = 1;
    	switch(type){
    	case SC_STONE:
    	case SC_FREEZE:
    	case SC_STUN:
    	case SC_SLEEP:
    		sc->opt1 = 0;
    		break;
    
    	case SC_POISON:
    	case SC_CURSE:
    	case SC_SILENCE:
    	case SC_BLIND:
    		sc->opt2 &= ~(1<<(type-SC_POISON));
    		break;
    	case SC_DPOISON:
    		sc->opt2 &= ~OPT2_DPOISON;
    		break;
    	case SC_SIGNUMCRUCIS:
    		sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
    		break;
    
    	case SC_HIDING:
    		sc->option &= ~OPTION_HIDE;
    		opt_flag|= 2|4; //Check for warp trigger + AoE trigger
    		break;
    	case SC_CLOAKING:
    		sc->option &= ~OPTION_CLOAK;
    		opt_flag|= 2;
    		break;
    	case SC_CHASEWALK:
    		sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
    		opt_flag|= 2;
    		break;
    	case SC_SIGHT:
    		sc->option &= ~OPTION_SIGHT;
    		break;
    	case SC_WEDDING:	
    		sc->option &= ~OPTION_WEDDING;
    		break;
    	case SC_XMAS:	
    		sc->option &= ~OPTION_XMAS;
    		break;
    	case SC_SUMMER:
    		sc->option &= ~OPTION_SUMMER;
    		break;
    	case SC_ORCISH:
    		sc->option &= ~OPTION_ORCISH;
    		break;
    	case SC_RUWACH:
    		sc->option &= ~OPTION_RUWACH;
    		break;
    	case SC_FUSION:
    		sc->option &= ~OPTION_FLYING;
    		break;
    	//opt3
    	case SC_TWOHANDQUICKEN:
    	case SC_ONEHAND:
    	case SC_SPEARQUICKEN:
    	case SC_CONCENTRATION:
    	case SC_MERC_QUICKEN:
    		sc->opt3 &= ~OPT3_QUICKEN;
    		opt_flag = 0;
    		break;
    	case SC_OVERTHRUST:
    	case SC_MAXOVERTHRUST:
    	case SC_SWOO:
    		sc->opt3 &= ~OPT3_OVERTHRUST;
    		opt_flag = 0;
    		break;
    	case SC_ENERGYCOAT:
    	case SC_SKE:
    		sc->opt3 &= ~OPT3_ENERGYCOAT;
    		opt_flag = 0;
    		break;
    	case SC_INCATKRATE: //Simulated Explosion spirits effect.
    		if (bl->type != BL_MOB)
    		{
    			opt_flag = 0;
    			break;
    		}
    	case SC_EXPLOSIONSPIRITS:
    		sc->opt3 &= ~OPT3_EXPLOSIONSPIRITS;
    		opt_flag = 0;
    		break;
    	case SC_STEELBODY:
    	case SC_SKA:
    		sc->opt3 &= ~OPT3_STEELBODY;
    		opt_flag = 0;
    		break;
    	case SC_BLADESTOP:
    		sc->opt3 &= ~OPT3_BLADESTOP;
    		opt_flag = 0;
    		break;
    	case SC_AURABLADE:
    		sc->opt3 &= ~OPT3_AURABLADE;
    		opt_flag = 0;
    		break;
    	case SC_BERSERK:
    		sc->opt3 &= ~OPT3_BERSERK;
    		opt_flag = 0;
    		break;
    //	case ???: // doesn't seem to do anything
    //		sc->opt3 &= ~OPT3_LIGHTBLADE;
    //		opt_flag = 0;
    //		break;
    	case SC_DANCING:
    		if ((sce->val1&0xFFFF) == CG_MOONLIT)
    			sc->opt3 &= ~OPT3_MOONLIT;
    		opt_flag = 0;
    		break;
    	case SC_MARIONETTE:
    	case SC_MARIONETTE2:
    		sc->opt3 &= ~OPT3_MARIONETTE;
    		opt_flag = 0;
    		break;
    	case SC_ASSUMPTIO:
    		sc->opt3 &= ~OPT3_ASSUMPTIO;
    		opt_flag = 0;
    		break;
    	case SC_WARM: //SG skills [Komurka]
    		sc->opt3 &= ~OPT3_WARM;
    		opt_flag = 0;
    		break;
    	case SC_KAITE:
    		sc->opt3 &= ~OPT3_KAITE;
    		opt_flag = 0;
    		break;
    	case SC_BUNSINJYUTSU:
    		sc->opt3 &= ~OPT3_BUNSIN;
    		opt_flag = 0;
    		break;
    	case SC_SPIRIT:
    		sc->opt3 &= ~OPT3_SOULLINK;
    		opt_flag = 0;
    		break;
    	case SC_CHANGEUNDEAD:
    		sc->opt3 &= ~OPT3_UNDEAD;
    		opt_flag = 0;
    		break;
    //	case ???: // from DA_CONTRACT (looks like biolab mobs aura)
    //		sc->opt3 &= ~OPT3_CONTRACT;
    //		opt_flag = 0;
    //		break;
    	default:
    		opt_flag = 0;
    	}
    
    	if (calc_flag&SCB_DYE)
    	{	//Restore DYE color
    		if (vd && !vd->cloth_color && sce->val4)
    			clif_changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
    		calc_flag&=~SCB_DYE;
    	}
    
    	//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
    	if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) )
    		clif_status_change(bl,StatusIconChangeTable[type],0,0);
    	else if (sd)
    		clif_status_load(bl,StatusIconChangeTable[type],0);
    
    	if(opt_flag)
    		clif_changeoption(bl);
    
    	if (calc_flag)
    		status_calc_bl(bl,calc_flag);
    
    	if(opt_flag&4) //Out of hiding, invoke on place.
    		skill_unit_move(bl,gettick(),1);
    
    	if(opt_flag&2 && sd && map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC))
    		npc_touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event.
    
    	ers_free(sc_data_ers, sce);
    	return 1;
    }
    
    int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
    {
    	struct block_list *bl;
    	struct status_change *sc;
    	struct status_change_entry *sce;
    	struct status_data *status;
    	int hp;
    
    	if(!((bl=map_id2bl(id))&&
    		(sc=status_get_sc(bl)) &&
    		(sce = sc->data[SC_KAAHI])))
    		return 0;
    
    	if(sce->val4 != tid) {
    		ShowError("kaahi_heal_timer: Timer mismatch: %d != %d\n", tid, sce->val4);
    		sce->val4 = INVALID_TIMER;
    		return 0;
    	}
    
    	status=status_get_status_data(bl);
    	if(!status_charge(bl, 0, sce->val3)) {
    		sce->val4 = INVALID_TIMER;
    		return 0;
    	}
    
    	hp = status->max_hp - status->hp;
    	if (hp > sce->val2)
    		hp = sce->val2;
    	if (hp)
    		status_heal(bl, hp, 0, 2);
    	sce->val4 = INVALID_TIMER;
    	return 1;
    }
    

    Код:
    int status_change_clear_buffs (struct block_list* bl, int type)
    {
    	int i;
    	struct status_change *sc= status_get_sc(bl);
    
    	if (!sc || !sc->count)
    		return 0;
    
    	if (type&2) //Debuffs
    	for( i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++ )
    	{
    		status_change_end(bl, (sc_type)i, INVALID_TIMER);
    	}
    
    	for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
    	{
    		if(!sc->data[i])
    			continue;
    		
    		switch (i) {
    			//Stuff that cannot be removed
    			case SC_WEIGHT50:
    			case SC_WEIGHT90:
    			case SC_COMBO:
    			case SC_SMA:
    			case SC_DANCING:
    			case SC_GUILDAURA:
    			case SC_SAFETYWALL:
    			case SC_PNEUMA:
    			case SC_NOCHAT:
    			case SC_JAILED:
    			case SC_ANKLE:
    			case SC_BLADESTOP:
    			case SC_CP_WEAPON:
    			case SC_CP_SHIELD:
    			case SC_CP_ARMOR:
    			case SC_CP_HELM:
    			case SC_STRFOOD:
    			case SC_AGIFOOD:
    			case SC_VITFOOD:
    			case SC_INTFOOD:
    			case SC_DEXFOOD:
    			case SC_LUKFOOD:
    			case SC_HITFOOD:
    			case SC_FLEEFOOD:
    			case SC_BATKFOOD:
    			case SC_WATKFOOD:
    			case SC_MATKFOOD:
    			case SC_FOOD_STR_CASH:
    			case SC_FOOD_AGI_CASH:
    			case SC_FOOD_VIT_CASH:
    			case SC_FOOD_DEX_CASH:
    			case SC_FOOD_INT_CASH:
    			case SC_FOOD_LUK_CASH:
    			case SC_EXPBOOST:
    			case SC_JEXPBOOST:
    			case SC_ITEMBOOST:
    				continue;
    				
    			//Debuffs that can be removed.
    			case SC_HALLUCINATION:
    			case SC_QUAGMIRE:
    			case SC_SIGNUMCRUCIS:
    			case SC_DECREASEAGI:
    			case SC_SLOWDOWN:
    			case SC_MINDBREAKER:
    			case SC_WINKCHARM:
    			case SC_STOP:
    			case SC_ORCISH:
    			case SC_STRIPWEAPON:
    			case SC_STRIPSHIELD:
    			case SC_STRIPARMOR:
    			case SC_STRIPHELM:
    				if (!(type&2))
    					continue;
    				break;
    			//The rest are buffs that can be removed.
    			case SC_BERSERK:
    				if (!(type&1))
    					continue;
    			  	sc->data[i]->val2 = 0;
    				break;
    			default:
    				if (!(type&1))
    					continue;
    				break;
    		}
    		status_change_end(bl, (sc_type)i, INVALID_TIMER);
    	}
    	return 0;
    }
    
    kop6en нравится это.
  8. kop6en

    kop6en Read Only

    а что вызывает у нас таро?
  9. f0und3r

    f0und3r Игрок

    Поправил код (верстка похерилась), обновите страничку
  10. f0und3r

    f0und3r Игрок

    Таро вызывает (для поломки):
    Код:
    				case 3:	// 1000 damage, random armor destroyed
    					{
    						int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
    						status_fix_damage(src, bl, 1000, 0);
    						clif_damage(src,bl,tick,0,0,1000,0,0,0);
    						if( !status_isdead(bl) )
    							skill_break_equip(bl, where[rand()%5], 10000, BCT_ENEMY);
    					}
    					break;
    

    Код:
    int skill_break_equip (struct block_list *bl, unsigned short where, int rate, int flag)
    {
    	const int where_list[4]     = {EQP_WEAPON, EQP_ARMOR, EQP_SHIELD, EQP_HELM};
    	const enum sc_type scatk[4] = {SC_STRIPWEAPON, SC_STRIPARMOR, SC_STRIPSHIELD, SC_STRIPHELM};
    	const enum sc_type scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM};
    	struct status_change *sc = status_get_sc(bl);
    	int i,j;
    	TBL_PC *sd;
    	sd = BL_CAST(BL_PC, bl);
    	if (sc && !sc->count)
    		sc = NULL;
    
    	if (sd) {
    		if (sd->unbreakable_equip)
    			where &= ~sd->unbreakable_equip;
    		if (sd->unbreakable)
    			rate -= rate*sd->unbreakable/100;
    		if (where&EQP_WEAPON) {
    			switch (sd->status.weapon) {
    				case W_FIST:	//Bare fists should not break :P
    				case W_1HAXE:
    				case W_2HAXE:
    				case W_MACE: // Axes and Maces can't be broken [DracoRPG]
    				case W_2HMACE:
    				case W_STAFF:
    				case W_2HSTAFF:
    				case W_BOOK: //Rods and Books can't be broken [Skotlex]
    				case W_HUUMA:
    					where &= ~EQP_WEAPON;
    			}
    		}
    	}
    	if (flag&BCT_ENEMY) {
    		if (battle_config.equip_skill_break_rate != 100)
    			rate = rate*battle_config.equip_skill_break_rate/100;
    	} else if (flag&(BCT_PARTY|BCT_SELF)) {
    		if (battle_config.equip_self_break_rate != 100)
    			rate = rate*battle_config.equip_self_break_rate/100;
    	}
    
    	for (i = 0; i < 4; i++) {
    		if (where&where_list[i]) {
    			if (sc && sc->count && sc->data[scdef[i]])
    				where&=~where_list[i];
    			else if (rand()%10000 >= rate)
    				where&=~where_list[i];
    			else if (!sd && !(status_get_mode(bl)&MD_BOSS)) //Cause Strip effect.
    				sc_start(bl,scatk[i],100,0,skill_get_time(status_sc2skill(scatk[i]),1));
    		}
    	}
    	if (!where) //Nothing to break.
    		return 0;
    	if (sd) {
    		for (i = 0; i < EQI_MAX; i++) {
    			j = sd->equip_index[i];
    			if (j < 0 || sd->status.inventory[j].attribute == 1 || !sd->inventory_data[j])
    				continue;
    			flag = 0;
    			switch(i) {
    				case EQI_HEAD_TOP: //Upper Head
    					flag = (where&EQP_HELM);
    					break;
    				case EQI_ARMOR: //Body
    					flag = (where&EQP_ARMOR);
    					break;
    				case EQI_HAND_R: //Left/Right hands
    				case EQI_HAND_L:
    					flag = (
    						(where&EQP_WEAPON && sd->inventory_data[j]->type == IT_WEAPON) ||
    						(where&EQP_SHIELD && sd->inventory_data[j]->type == IT_ARMOR));
    					break;
    				case EQI_SHOES:
    					flag = (where&EQP_SHOES);
    					break;
    				case EQI_GARMENT:
    					flag = (where&EQP_GARMENT);
    					break;
    				default:
    					continue;
    			}
    			if (flag) {
    				sd->status.inventory[j].attribute = 1;
    				pc_unequipitem(sd, j, 3);
    			}
    		}
    		clif_equiplist(sd);
    	}
    
    	return where; //Return list of pieces broken.
    }
    
  11. kop6en

    kop6en Read Only

    как я вижу, то диспел с таро, а он же
    status_change_clear_buffs вызывает в итоге status_change_end как у обычного диспела.

    так что заявления про то что с таро летит не диспел - можете сбросить в утиль
  12. f0und3r

    f0und3r Игрок

    Наверное это не ко мне, а к предыдущим ребятам (не читал), но напомню, что по-хорошему, нужно ориентироваться на другие исходники, есть возможность "боем" проверить необходимые Вам кейсы, главное, опишите - найду время, отпишусь о результатах (обычно день-два :D).
    kop6en нравится это.
  13. kop6en

    kop6en Read Only

    икс, иди уже сюда.
    не будь тепличным
  14. Misconception

    Misconception Игрок

    отнюдь
    тогда сразу вызывался бы деспел
    однако сначала вызывается процедура (которая не магия опятьже и проканает на линкера и на рога с линком) проверяет кучу условий и уже она стартует диспел.. че не так?
    а на выходе таки да диспел не равно карта таро пристка - таро круче
  15. kop6en

    kop6en Read Only

    я уже выше расписывал основное условие разницы это:
    что в диспеле есть строчка проверки на иммун
  16. f0und3r

    f0und3r Игрок

    Опишите кейсы которые нужно проверить "боем", в исходниках далеко не всегда все углядеть если не работать / копаться в них (особенно когда они 1к+ строк и наименования так и пытаются тебя подставить (EQI_*/EQP_*)).
  17. Misconception

    Misconception Игрок

    диспелл+
    новая формула
    ЕЩЁ еффективнее
    NEW
    ТЕПЕРЬ игнорит ГТБ !!
  18. kop6en

    kop6en Read Only

    так и смотрят два лица, окаянные.
    Мяурицо и f0und3r нравится это.
  19. f0und3r

    f0und3r Игрок

    @kop6en @Misconception доброе утро!
    протестировал первый кейс (на эмуляторе с механикой как здесь), таро по ФП, смотрим.

    P. S. Сейчас поправлю исходники чтобы вылетала только колесница, тестить будет проще (без ком :D), еще и кастомный клиент - граффити в добавок.
  20. f0und3r

    f0und3r Игрок

    @kop6en @Misconception второй тест, таро по валькосету с ФП (сорри, получился жирнее, но можно сделать некоторые выводы)

    Ну, вывод первый - щиты под ФП не ломаются, без ФП - на ура.
    Вывод второй - ломаемые вещи под ФП - ломаются, а которые не ломаются - не ломаются.

    @kop6en что нужно проверить с диспелом / диспелом от таро?