How to stop mvp from moving when ice wall was casted on it

Angelmelody

(\ /) ( . .)
Messages
772
Points
0
Age
32
Location
new_1-1,53,111
Github
Angelmelody
Emulator
In the vedio, When the mvp  was blocked by an ice wall and got hitten,the mvp was still under

chase state and won't use teleport skill ,I hope someone can help me ,thanks in-advance
default_smile.png


To view this content we will need your consent to set third party cookies.
For more detailed information, see our cookies page.
 
Last edited by a moderator:
This can't be official, MVPs teleport in official if trapped and attacked, or if attacked and don't have clear sight to attacker.

 
This is determined by the mobs rude status skill. If an MVP is unable to reach the player, by walking then they will eventually use their " rude " skill, which just so happens to be teleport.

mob_skill_db.txt located in p(re)/folder

Examples:

1039,Baphomet@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,1039,Baphomet@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
You see that Baphomet like other MVPs will teleport away. So to prevent that from happening, just remove those 2 skills and they should stay there and get beat like the meanies they are D:

 
Last edited by a moderator:
This is determined by the mobs rude status skill. If an MVP is unable to reach the player, by walking then they will eventually use their " rude " skill, which just so happens to be teleport.

mob_skill_db.txt located in p(re)/folder

Examples:

1039,Baphomet@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,1039,Baphomet@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
You see that Baphomet like other MVPs will teleport away. So to prevent that from happening, just remove those 2 skills and they should stay there and get beat like the meanies they are D:
Thanks, but I m lazy to comment out  every mvp's 'rude attack' TELEPORT skills.

Is it possible adding  a  custom option on monster_ai ?

0x800: mvp mobs wont teleport away when they are trapped by an ice wall

and how about stop mvp's moving by an icewall part? how can I reproduce that behavior

 
Last edited by a moderator:
That would be under mob.c for AI controls

/*========================================== * AI of MOB whose is near a Player *------------------------------------------*/bool mob_ai_sub_hard(struct mob_data *md, int64 tick) { struct block_list *tbl = NULL, *abl = NULL; int mode; int view_range, can_move; if(md->bl.prev == NULL || md->status.hp <= 0) return false; if (DIFF_TICK(tick, md->last_thinktime) < MIN_MOBTHINKTIME) return false; md->last_thinktime = tick; if (md->ud.skilltimer != INVALID_TIMER) return false; if(md->ud.walktimer != INVALID_TIMER && md->ud.walkpath.path_pos <= 3) return false; // Abnormalities if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE ) || md->sc.data[SC_DEEP_SLEEP] || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) { //Should reset targets. md->target_id = md->attacked_id = 0; return false; } if (md->sc.count && md->sc.data[SC_BLIND]) view_range = 3; else view_range = md->db->range2; mode = status_get_mode(&md->bl); can_move = (mode&MD_CANMOVE)&&unit->can_move(&md->bl); if (md->target_id) { //Check validity of current target. [Skotlex] tbl = map->id2bl(md->target_id); if (!tbl || tbl->m != md->bl.m || (md->ud.attacktimer == INVALID_TIMER && !status->check_skilluse(&md->bl, tbl, 0, 0)) || (md->ud.walktimer != INVALID_TIMER && !(battle_config.mob_ai&0x1) && !check_distance_bl(&md->bl, tbl, md->min_chase)) || ( tbl->type == BL_PC && ((((TBL_PC*)tbl)->state.gangsterparadise && !(mode&MD_BOSS)) || ((TBL_PC*)tbl)->invincible_timer != INVALID_TIMER) ) ) { //Unlock current target. if (mob->warpchase(md, tbl)) return true; //Chasing this target. mob->unlocktarget(md, tick-(battle_config.mob_ai&0x8?3000:0)); //Immediately do random walk. tbl = NULL; } } // Check for target change. if( md->attacked_id && mode&MD_CANATTACK ) { if( md->attacked_id == md->target_id ) { //Rude attacked check. if( !battle->check_range(&md->bl, tbl, md->status.rhw.range) && ( //Can't attack back and can't reach back. (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1) || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP] || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target. || !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) ) && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack && can_move && unit->escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape { //Escaped md->attacked_id = 0; return true; } } else if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode) || (md->sc.count && md->sc.data[SC__CHAOS]))) { int dist; if( md->bl.m != abl->m || abl->prev == NULL || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area || battle->check_target(&md->bl, abl, BCT_ENEMY) <= 0 // Attacker is not enemy of mob || (battle_config.mob_ai&0x2 && !status->check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker || (!battle->check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ... && ( // Reach check (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1) || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP] || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target. || !mob->can_reach(md, abl, dist+md->db->range3, MSS_RUSH) ) ) ) { // Rude attacked if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) && can_move && !tbl && unit->escape(&md->bl, abl, rnd()%10 +1)) { //Escaped. //TODO: Maybe it shouldn't attempt to run if it has another, valid target? md->attacked_id = 0; return true; } } else if (!(battle_config.mob_ai&0x2) && !status->check_skilluse(&md->bl, abl, 0, 0)) { //Can't attack back, but didn't invoke a rude attacked skill... } else { //Attackable if (!tbl || dist < md->status.rhw.range || !check_distance_bl(&md->bl, tbl, dist) || battle->get_target(tbl) != md->bl.id) { //Change if the new target is closer than the actual one //or if the previous target is not attacking the mob. [Skotlex] md->target_id = md->attacked_id; // set target if (md->state.attacked_count) md->state.attacked_count--; //Should we reset rude attack count? md->min_chase = dist+md->db->range3; if(md->min_chase>MAX_MINCHASE) md->min_chase=MAX_MINCHASE; tbl = abl; //Set the new target } } } //Clear it since it's been checked for already. md->attacked_id = 0; } // Processing of slave monster if (md->master_id > 0 && mob->ai_sub_hard_slavemob(md, tick)) return true; // Scan area for targets if (!tbl && mode&MD_LOOTER && md->lootitem && DIFF_TICK(tick, md->ud.canact_tick) > 0 && (md->lootitem_count < LOOTITEM_SIZE || battle_config.monster_loot_type != 1) ) { // Scan area for items to loot, avoid trying to loot if the mob is full and can't consume the items. map->foreachinrange (mob->ai_sub_hard_lootsearch, &md->bl, view_range, BL_ITEM, md, &tbl); } if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) { map->foreachinrange (mob->ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode); } else if ((mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) || (md->sc.count && md->sc.data[SC__CHAOS])) { int search_size; search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range; map->foreachinrange (mob->ai_sub_hard_changechase, &md->bl, search_size, DEFAULT_ENEMY_TYPE(md), md, &tbl); } if (!tbl) { //No targets available. if (mode&MD_ANGRY && !md->state.aggressive) md->state.aggressive = 1; //Restore angry state when no targets are available. /* bg guardians follow allies when no targets nearby */ if( md->bg_id && mode&MD_CANATTACK ) { if( md->ud.walktimer != INVALID_TIMER ) return true;/* we are already moving */ map->foreachinrange (mob->ai_sub_hard_bg_ally, &md->bl, view_range, BL_PC, md, &tbl, mode); if( tbl ) { if( distance_blxy(&md->bl, tbl->x, tbl->y) <= 3 || unit->walktobl(&md->bl, tbl, 1, 1) ) return true;/* we're moving or close enough don't unlock the target. */ } } //This handles triggering idle walk/skill. mob->unlocktarget(md, tick); return true; } //Target exists, attack or loot as applicable. if (tbl->type == BL_ITEM) { //Loot time. struct flooritem_data *fitem; if (md->ud.target == tbl->id && md->ud.walktimer != INVALID_TIMER) return true; //Already locked. if (md->lootitem == NULL) { //Can't loot... mob->unlocktarget (md, tick); return true; } if (!check_distance_bl(&md->bl, tbl, 1)) { //Still not within loot range. if (!(mode&MD_CANMOVE)) { //A looter that can't move? Real smart. mob->unlocktarget(md,tick); return true; } if (!can_move) //Stuck. Wait before walking. return true; md->state.skillstate = MSS_LOOT; if (!unit->walktobl(&md->bl, tbl, 1, 1)) mob->unlocktarget(md, tick); //Can't loot... return true; } //Within looting range. if (md->ud.attacktimer != INVALID_TIMER) return true; //Busy attacking? fitem = (struct flooritem_data *)tbl; //Logs items, taken by (L)ooter Mobs [Lupus] logs->pick_mob(md, LOG_TYPE_LOOT, fitem->item_data.amount, &fitem->item_data, NULL); if (md->lootitem_count < LOOTITEM_SIZE) { memcpy (&md->lootitem[md->lootitem_count++], &fitem->item_data, sizeof(md->lootitem[0])); } else { //Destroy first looted item... if (md->lootitem[0].card[0] == CARD0_PET) intif->delete_petdata( MakeDWord(md->lootitem[0].card[1],md->lootitem[0].card[2]) ); memmove(&md->lootitem[0], &md->lootitem[1], (LOOTITEM_SIZE-1)*sizeof(md->lootitem[0])); memcpy (&md->lootitem[LOOTITEM_SIZE-1], &fitem->item_data, sizeof(md->lootitem[0])); } if (pcdb_checkid(md->vd->class_)) { //Give them walk act/delay to properly mimic players. [Skotlex] clif->takeitem(&md->bl,tbl); md->ud.canact_tick = tick + md->status.amotion; unit->set_walkdelay(&md->bl, tick, md->status.amotion, 1); } //Clear item. map->clearflooritem (tbl); mob->unlocktarget (md,tick); return true; } //Attempt to attack. //At this point we know the target is attackable, we just gotta check if the range matches. if (md->ud.target == tbl->id && md->ud.attacktimer != INVALID_TIMER) //Already locked. return true; if (battle->check_range (&md->bl, tbl, md->status.rhw.range)) { //Target within range, engage if(tbl->type == BL_PC) mob->log_damage(md, tbl, 0); //Log interaction (counts as 'attacker' for the exp bonus) if(!(mode&MD_RANDOMTARGET)) unit->attack(&md->bl,tbl->id,1); else { // Attack once and find new random target int search_size = (view_range < md->status.rhw.range) ? view_range : md->status.rhw.range; unit->attack(&md->bl,tbl->id,0); tbl = battle->get_enemy(&md->bl, DEFAULT_ENEMY_TYPE(md), search_size); // If no target was found, keep atacking the old one if( tbl ) { md->target_id = tbl->id; md->min_chase = md->db->range3; } } return true; } //Out of range... if (!(mode&MD_CANMOVE)) { //Can't chase. Attempt an idle skill before unlocking. md->state.skillstate = MSS_IDLE; if (!mob->skill_use(md, tick, -1)) mob->unlocktarget(md,tick); return true; } if (!can_move) { //Stuck. Attempt an idle skill md->state.skillstate = MSS_IDLE; if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL)) mob->skill_use(md, tick, -1); return true; } if (md->ud.walktimer != INVALID_TIMER && md->ud.target == tbl->id && ( !(battle_config.mob_ai&0x1) || check_distance_blxy(tbl, md->ud.to_x, md->ud.to_y, md->status.rhw.range) )) //Current target tile is still within attack range. return true; //Follow up if possible. if(!mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) || !unit->walktobl(&md->bl, tbl, md->status.rhw.range, 2)) mob->unlocktarget(md,tick); return true;}
More specifically this particular section of the above code:

// Check for target change. if( md->attacked_id && mode&MD_CANATTACK ) { if( md->attacked_id == md->target_id ) { //Rude attacked check. if( !battle->check_range(&md->bl, tbl, md->status.rhw.range) && ( //Can't attack back and can't reach back. (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1) || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP] || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target. || !mob->can_reach(md, tbl, md->min_chase, MSS_RUSH) ) && md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) // If can't rude Attack && can_move && unit->escape(&md->bl, tbl, rnd()%10 +1)) // Attempt escape { //Escaped md->attacked_id = 0; return true; } } else if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode) || (md->sc.count && md->sc.data[SC__CHAOS]))) { int dist; if( md->bl.m != abl->m || abl->prev == NULL || (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area || battle->check_target(&md->bl, abl, BCT_ENEMY) <= 0 // Attacker is not enemy of mob || (battle_config.mob_ai&0x2 && !status->check_skilluse(&md->bl, abl, 0, 0)) // Cannot normal attack back to Attacker || (!battle->check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ... && ( // Reach check (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1) || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP] || md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target. || !mob->can_reach(md, abl, dist+md->db->range3, MSS_RUSH) ) ) ) { // Rude attacked if (md->state.attacked_count++ >= RUDE_ATTACKED_COUNT && !mob->skill_use(md, tick, MSC_RUDEATTACKED) && can_move && !tbl && unit->escape(&md->bl, abl, rnd()%10 +1)) { //Escaped. //TODO: Maybe it shouldn't attempt to run if it has another, valid target? md->attacked_id = 0; return true; } } else if (!(battle_config.mob_ai&0x2) && !status->check_skilluse(&md->bl, abl, 0, 0)) { //Can't attack back, but didn't invoke a rude attacked skill... } else { //Attackable if (!tbl || dist < md->status.rhw.range || !check_distance_bl(&md->bl, tbl, dist) || battle->get_target(tbl) != md->bl.id) { //Change if the new target is closer than the actual one //or if the previous target is not attacking the mob. [Skotlex] md->target_id = md->attacked_id; // set target if (md->state.attacked_count) md->state.attacked_count--; //Should we reset rude attack count? md->min_chase = dist+md->db->range3; if(md->min_chase>MAX_MINCHASE) md->min_chase=MAX_MINCHASE; tbl = abl; //Set the new target } } }
My guess, is before it attempts to say it was rude attacked you need to add a check to see if the mvp is in an icewall.state ( do we use this? ). Sadly, I'm no where near able to do that with src code :/ but i'm pretty positive this is the bit that needs to be edited to do what you want. D:

 
Last edited by a moderator:
Back
Top