-
Posts
686 -
Joined
-
Days Won
9
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Posts posted by Gidz Cross
-
-
19 hours ago, cook1e said:
Have not seen this. Its not what im actually looking for but this will do temporarily. Thanks!
-
As the title says. This can be a good feature.
-
10 hours ago, Litro Endemic said:
that because current pvp ranking system has it own point rank logic.
suppose there is 2 player A & B currently in pvp map so the flow should go like..
- player A 5 point, rank 2/2 - player B 5 point, rank 2/2 - player A kill player B - player A 6 (5 + 1) point, rank 1/2 - player B 4 (5 - 1) point, rank 2/2 - player B warp out then goes back - player A 6 point, rank 1/2 - player B 5 point, rank 2/2 - player B kill player A - player B 6 (5 + 1) point, rank 1/2 - player A 4 (5 - 1) point, rank 2/2 - player A warp out then goes back - player B 6 point, rank 1/2 - player A 5 point, rank 2/2
anyway you can debug the code, to see the point acquired by player on map.
/*========================================== * Update PVP rank for sd1 in cmp to sd2 *------------------------------------------*/ static int pc_calc_pvprank_sub(struct block_list *bl,va_list ap) { map_session_data *sd1,*sd2; sd1=(map_session_data *)bl; sd2=va_arg(ap,map_session_data *); if( pc_isinvisible(sd1) || pc_isinvisible(sd2) ) {// cannot register pvp rank for hidden GMs return 0; } + ShowDebug("pc_calc_pvprank_sub: player %s (%d:%d) %d pvp point.\n", sd1->status.name, sd1->status.account_id, sd1->status.char_id, sd1->pvp_point); + if( sd1->pvp_point > sd2->pvp_point ) sd2->pvp_rank++; return 0; } /*========================================== * Calculate new rank beetween all present players (map_foreachinallarea) * and display result *------------------------------------------*/ int pc_calc_pvprank(map_session_data *sd) { int old = sd->pvp_rank; struct map_data *mapdata = map_getmapdata(sd->bl.m); + ShowDebug("pc_calc_pvprank: player %s (%d:%d) %d pvp point.\n", sd->status.name, sd->status.account_id, sd->status.char_id, sd->pvp_point); + sd->pvp_rank=1; map_foreachinmap(pc_calc_pvprank_sub,sd->bl.m,BL_PC,sd); if(old!=sd->pvp_rank || sd->pvp_lastusers!=mapdata->users_pvp) clif_pvpset(sd,sd->pvp_rank,sd->pvp_lastusers=mapdata->users_pvp,0); return sd->pvp_rank; }
though its bit weird pvp rank timer is allocated to each player in map instead run like dynamic mob,
i mean the timer attached to map will run when there is player come to map (clif_parse_LoadEndAck ?)
and stop when there is no one in map.albeit it will send 2 times the rank packet (clif_pvpset) when player come to map and timer executed at same time, but it should be no biggie.
Oh or try use client command "/pvpinfo" in each player client to see current point, since rank is based point.
Wow. Thank you so much for these new information.
-
I have managed to solved the ranking issue but i think its quite yet missing something. But it works (partially).
Scenario:
Me kills Player 2. The Player 2 Rank will become 2/2. Warp out then goes back then the same ranking shown 2/2. But when player 2 killed me. The player 2 rank will becomes 1/2. That means the player 2 is in Rank 1 for pvp in that specific map. But when i go back to savepoint then re warp to the same map the player 2 ranking will become 2/2 when my account becomes 1/2.
Here's what i did to make the ranking works in pk_mode: 1 (conf/misc)in pc.c
// disable certain pvp functions on pk_mode [Valaris] //if( !battle_config.pk_mode && mapdata->flag[MF_PVP] && !mapdata->flag[MF_PVP_NOCALCRANK] ) { sd->pvp_point -= 5; sd->pvp_lost++; if( src && src->type == BL_PC ) { struct map_session_data *ssd = (struct map_session_data *)src; ssd->pvp_point++; ssd->pvp_won++; } //if( sd->pvp_point < 0 ) { //sd->respawn_tid = add_timer(tick+1000, pc_respawn_timer,sd->bl.id,0); //return 1|8; //} //}
This is paired with the initical post in clif.c.
Tagging @joecalis XD
Is there a proper way to activate or port PVP Ranking, Timer with PK Mode: 1 enabled? -
Is this possible? I have managed to make it work but the ranking system is not properly working. I am requesting to have PK Mode set to 1 with PVP Aura, Timer and Ranking that is properly working.
In clif.c
if(!pc_isinvisible(sd) && mapdata->flag[MF_PVP]) { //if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] if (!mapdata->flag[MF_PVP_NOCALCRANK]) sd->pvp_timer = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0); sd->pvp_rank = 0; sd->pvp_lastusers = 0; sd->pvp_point = 5; sd->pvp_won = 0; sd->pvp_lost = 0; //}
-
17 hours ago, joecalis said:
Try to change this:
if (unit->group->skill_id == PF_SPIDERWEB && unit->bl.id != srcunit->bl.id && unit->group->src_id == src->id) { //skill_delunitgroup(unit->group); // This one is instant Delete unit->limit = min(unit->limit,1000); // This one you can change "1000" to change the timing (lower number = faster deletion) unit->group->limit = unit->limit; return 1; }
to this:
if (unit->group->skill_id == PF_SPIDERWEB && unit->bl.id != srcunit->bl.id && unit->group->src_id == src->id && unit->group->val2) { //skill_delunitgroup(unit->group); // This one is instant Delete unit->limit = min(unit->limit,1000); // This one you can change "1000" to change the timing (lower number = faster deletion) unit->group->limit = unit->limit; return 1; }
Oh my goodness! YOU DA MENSH!
PERFECTION! -
19 hours ago, joecalis said:
Remove what ever code I sent before, and do this instead.
in skill.cpp
Find:
int skill_greed(struct block_list *bl, va_list ap); static int skill_cell_overlap(struct block_list *bl, va_list ap);
Change To:
int skill_greed(struct block_list *bl, va_list ap); static int skill_web_remover(struct block_list *bl, va_list ap); static int skill_cell_overlap(struct block_list *bl, va_list ap);
Find:
// Execute on all targets standing on this cell if (range == 0 && active_flag) map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
Change To:
if (skill_id == PF_SPIDERWEB) map_foreachinarea(skill_web_remover, src->m, x - 1, y - 1, x + 1, y + 1, BL_SKILL, src, unit); // Execute on all targets standing on this cell if (range == 0 && active_flag) map_foreachincell(skill_unit_effect,unit->bl.m,unit->bl.x,unit->bl.y,group->bl_flag,&unit->bl,gettick(),1);
Find:
/*========================================== * Check new skill unit cell when overlapping in other skill unit cell. * Catched skill in cell value pushed to *unit pointer. * Set (*alive) to 0 will ends 'new unit' check *------------------------------------------*/ static int skill_cell_overlap(struct block_list *bl, va_list ap)
Change To:
static int skill_web_remover(struct block_list* bl, va_list ap) { struct block_list* src; struct skill_unit* srcunit; struct skill_unit* unit; src = va_arg(ap, struct block_list*); srcunit = va_arg(ap, struct skill_unit*); unit = (struct skill_unit*)bl; if (unit == NULL || unit->group == NULL) return 0; if (unit->group->skill_id == PF_SPIDERWEB && unit->bl.id != srcunit->bl.id && unit->group->src_id == src->id) { //skill_delunitgroup(unit->group); // This one is instant Delete unit->limit = min(unit->limit,1000); // This one you can change "1000" to change the timing (lower number = faster deletion) unit->group->limit = unit->limit; return 1; } return 0; } /*========================================== * Check new skill unit cell when overlapping in other skill unit cell. * Catched skill in cell value pushed to *unit pointer. * Set (*alive) to 0 will ends 'new unit' check *------------------------------------------*/ static int skill_cell_overlap(struct block_list *bl, va_list ap)
This line you can change depending on what you prefer.
//skill_delunitgroup(unit->group); // This one is instant Delete unit->limit = min(unit->limit,1000); // This one you can change "1000" to change the timing (lower number = faster deletion) unit->group->limit = unit->limit;
If you want to make web instantly vanish remove the "//" before the skill_delunitgroup then put "//" before unit->limit and unit->group->limit
If you want to change the speed of when it disappears edit the "1000" to any number you want, it's in milliseconds.
This however deletes nearby webs even if you don't have a target and will only delete your own web
Sweet! We are getting close. Since you managed to work on the vanishing thingy. But This should only work when you trap the target. But pretty much usable until i get what i want. Thank you so much!
-
Player.conf
// When should the server prevent a player from logging out? Have no effect if prevent_logout is disabled. (Note 3) // Official servers prevent players from logging out after attacking, casting skills, and taking damage. // 0 = Players can always logout // 1 = Prevent logout on login // 2 = Prevent logout after attacking // 4 = Prevent logout after casting skill // 8 = Prevent logout after being hit prevent_logout_trigger: 10
-
Okay i found a new way to explain in a simple manner. You can spam the spider web to target. Because the previous web you used will be removed.
In the official behavior. yes you can stack the web as well but you will be limited by your ActiveInstance. Here's the video:
-
Just now, Ice Bear said:
I think you need to remove the max instance in the skill_db.yml ? did you check it ?
```
REMOVE THE ACTIVE INSTANCE? DID U TEST
- Id: 405
Name: PF_SPIDERWEB
Description: Fiber Lock
MaxLevel: 1
Type: Magic
TargetType: Attack
DamageFlags:
NoDamage: true
Range: 7
Hit: Single
HitCount: 1
- ActiveInstance: 3
Duration1: 16000
Duration2: 8000
Requires:
SpCost: 30
ItemCost:
- Item: Spiderweb
Amount: 1
Unit:
Id: Spiderweb
Interval: -1
Target: Enemy
Flag:
RemovedByFireRain: true
Status: SpiderWeb
```The thing is. I want the MaxInstace to work.
-
11 minutes ago, Ice Bear said:
```
try to change
if (sd && skill_id == PF_SPIDERWEB && !skill_pos_maxcount_check(src, skill_x, skill_y, skill_id, skill_lv, BL_PC, false)) {
to
if (sd && skill_id == PF_SPIDERWEB && !skill_pos_maxcount_check(src, ud->skillx,ud->skilly, ud->skill_id, ud->skill_lv, BL_PC, false)){
```
It works! Thanks bro. This will be my temporary solution.
Here's another video of the mod that i wanted to have.
MaxInstance still works. It can only be spam when you magnet another target since the first web that hit the target will vanish. XD
-
On 5/9/2023 at 11:46 AM, joecalis said:
in unit.cpp
Find:
// SC_MAGICPOWER needs to switch states at start of cast skill_toggle_magicpower(src, skill_id);
Change To:
// SC_MAGICPOWER needs to switch states at start of cast skill_toggle_magicpower(src, skill_id); if (sd && skill_id == PF_SPIDERWEB && !skill_pos_maxcount_check(src, skill_x, skill_y, skill_id, skill_lv, BL_PC, false)) { int oldweb = -1; int webid = 0; for (int i = 0; i < MAX_SKILLUNITGROUP && sd->ud.skillunit[i]; i++) { if (sd->ud.skillunit[i]->skill_id == skill_id) { if (webid == 0) { webid = sd->ud.skillunit[i]->group_id; oldweb = i; } else if (webid != 0 && sd->ud.skillunit[i]->group_id < webid) { webid = sd->ud.skillunit[i]->group_id; oldweb = i; } } } if (oldweb >= 0) { skill_delunitgroup(sd->ud.skillunit[oldweb]); } }
This will delete the oldest active spider web when you try to cast it while it is at max count.
You can change the maxcount in skill_db.txt to any number under 25 to raise the limit before web deletion.
Edit: Sorry I placed the code before requirement checks, but its fixed now.
I knew it. The mod requires to add something on unit.c as I understand the code what it does was to remove the older web when you reached the limit. Just like ankle snare right?
** Edit
Didn't work for me. It says skill x and y is undeclared. Maybe because im using 2020 trunk. Anyway. If this behave like ankle snare (like deleting the oldest active trap) then its not the one im looking. But can be until the proper coding.
The first video i showed was its not ignoring the ActiveInstance. In that server the ActiveInstance istance is set to 5. I can still cast 5 spider web to the ground and will have skill failed when i deploy 5 spider webs.Their spider web behavior is when the target was trapped. And for some reason the target moved to a different cell. The first web will vanished. Thats why I can spam the webs.
Maybe this is a bug but intended one. -
I know that this has been posted several times. By me and some other rA people in the past. But until now it remains a mystery (at least for me LOL) Others might already solved it and just keeping quiet. But I am this close of achieving the perfect mod.
Here's what I'm trying to achieve.As you can see. I can spam the spider web regardless of the ActiveInstance. The previous web will disappear once I set another web close to target.
Now, I mentioned that I am super close. I manage to replicate everything except for the disappearance of the previous web. Please check the vid below.
As you can see. I was limited by the ActiveInstance. Thus I cannot spam it.
I need a way to remove the previous web if its already triggered. -
3 hours ago, Mael said:
Woooah. So the usual item linking is updated.
mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " <ITEM>Doram Token<INFO>25142</INFO></ITEM>?"; into mes "Don't you want to exchange this with " + .@item_data[.@i+1] + " " + mesitemlink( 25142, false ) + "?";
But as much as I wanted to have this. I think imma pass since my trunk is old. Like 3 years ago. Thanks Mael! XD
1 hour ago, joecalis said:try this:
struct item_data * item_data = item_array[i]; sprintf(atcmd_output, "Item: '%s'/'%s' (%hu) Type: %s", // msg_txt(sd, 1277) item_data->name,createItemLink(item_data->nameid, 0, NULL).c_str(),item_data->nameid, (item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((enum e_item_ammo)item_data->look));
Eyyy! It works like a charm! Thank you so much!
-
@joecalis Hey apologies for the multiple mentions. XD
How about retaining the Item Type? I am playing with it but all my attempts are failing. So the src code retains to read msg_txt(sd, 1277) but only will display the item type. -
3 hours ago, joecalis said:
If you have itemlink commands by Cydh implemented you just have to edit
in atcommand.cpp
Find:
struct item_data * item_data = item_array[i]; sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%hu) Type: %s | Extra Effect: %s item_data->name,item_data->jname,item_data->slot,item_data->nameid, (item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((enum e_item_ammo)item_data->look), (item_data->script==NULL)? msg_txt(sd,1278) : msg_txt(sd,1279) // None / With script );
Change To:
struct item_data * item_data = item_array[i]; sprintf(atcmd_output, "Item: '%s'/'%s' (%hu)", // msg_txt(sd, 1277) item_data->name, createItemLink(item_data->nameid, 0, NULL).c_str(),item_data->nameid);
Eyyy!!! It works! Thanks mate you are AWESOME!
-
Heya. Can i request a replicated method to this @iteminfo.
So the picture shows is when you type @ii in a wild search. For example @ii Poring Card. Those information on the chat box will appear. And at the same time it will call a npc script with dialog box which shows the item with itemlink in it.
Tagging @joecalis XD
Or... The NPC dialog box isn't necessary. Just make the information on the chatbox with item link.
-
2 minutes ago, joecalis said:
in atcommand.cpp
Find:
for (j=0; j < MAX_SEARCH && item_data->mob[j].chance > 0; j++) { int dropchance = item_data->mob[j].chance;
Change To:
for (j=0; j < MAX_SEARCH && item_data->mob[j].chance > 0; j++) { int dropchance = item_data->mob[j].chance; int dropbonus = 0;
Find:
#endif if (pc_isvip(sd)) // Display item rate increase for VIP dropchance += (dropchance * battle_config.vip_drop_increase) / 100; sprintf(atcmd_output, "- %s (%d): %02.02f%%", mob_db(item_data->mob[j].id)->jname, item_data->mob[j].id, dropchance/100.);
Change To:
#endif if(sd->sc.count && sd->sc.data[SC_ITEMBOOST]) // Display drop rate increase for SC_ITEMBOOST eg. Bubblegum dropbonus += (dropchance * sd->sc.data[SC_ITEMBOOST]->val1) / 100; if (pc_isvip(sd)) // Display item rate increase for VIP dropbonus += (dropchance * battle_config.vip_drop_increase) / 100; if(dropbonus) sprintf(atcmd_output, "- %s (%d): %02.02f%% + (%02.02f%%)", mob_db(item_data->mob[j].id)->jname, item_data->mob[j].id, dropchance/100., dropbonus/100.); else sprintf(atcmd_output, "- %s (%d): %02.02f%%", mob_db(item_data->mob[j].id)->jname, item_data->mob[j].id, dropchance/100.);
Oh my goodness! Thank you for getting back with me! Gimme few minutes. Will try this!
**EDIT
It Works!-
1
-
-
On 5/1/2023 at 10:46 AM, joecalis said:
In the latest version of Rathena this is already implemented.
If you're using an older version you might have to diff patch the itemlink commands by Cydh.The older rathena versions supports the "itemlink-20190319-e6f1f21d.diff"
Then you would have to edit the atcommand.cpp in ACMD_FUNC(mobinfo)
Find:
for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) { int droprate; if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL) continue; droprate = mob->dropitem[i].p; #ifdef RENEWAL_DROP if( battle_config.atcommand_mobinfo_type ) { droprate = droprate * pc_level_penalty_mod(mob->lv - sd->status.base_level, mob->status.class_, mob->status.mode, 2) / 100; if (droprate <= 0 && !battle_config.drop_rate0item) droprate = 1; } #endif if (pc_isvip(sd)) // Display drop rate increase for VIP droprate += (droprate * battle_config.vip_drop_increase) / 100; if (item_data->slot) sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, (float)droprate / 100); else sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, (float)droprate / 100); strcat(atcmd_output, atcmd_output2); if (++j % 3 == 0) { clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); } } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1246)); // This monster has no drops. else if (j % 3 != 0) clif_displaymessage(fd, atcmd_output); // mvp if (mob->mexp) { float mvppercent, mvpremain; sprintf(atcmd_output, msg_txt(sd,1247), mob->mexp); // MVP Bonus EXP:%u clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, msg_txt(sd,1248)); // MVP Items: mvpremain = 100.0; //Remaining drop chance for official mvp drop mode j = 0; for (i = 0; i < MAX_MVP_DROP_TOTAL; i++) { if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL) continue; //Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5% mvppercent = (float)mob->mvpitem[i].p * mvpremain / 10000.0f; if(battle_config.item_drop_mvp_mode == 0) { mvpremain -= mvppercent; } if (mvppercent > 0) { j++; if (j == 1) { if (item_data->slot) sprintf(atcmd_output2, " %s[%d] %02.02f%%", item_data->jname, item_data->slot, mvppercent); else sprintf(atcmd_output2, " %s %02.02f%%", item_data->jname, mvppercent); } else { if (item_data->slot) sprintf(atcmd_output2, " - %s[%d] %02.02f%%", item_data->jname, item_data->slot, mvppercent); else sprintf(atcmd_output2, " - %s %02.02f%%", item_data->jname, mvppercent); } strcat(atcmd_output, atcmd_output2); } } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1249)); // This monster has no MVP prizes. else clif_displaymessage(fd, atcmd_output); }
Change to:
for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) { int droprate; int dropbonus = 0; if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL) continue; droprate = mob->dropitem[i].p; #ifdef RENEWAL_DROP if( battle_config.atcommand_mobinfo_type ) { droprate = droprate * pc_level_penalty_mod(mob->lv - sd->status.base_level, mob->status.class_, mob->status.mode, 2) / 100; if (droprate <= 0 && !battle_config.drop_rate0item) droprate = 1; } #endif if((sd->sc.count && sd->sc.data[SC_ITEMBOOST])) // Display drop rate increase for SC_ITEMBOOST eg. Bubblegum dropbonus += (droprate * sd->sc.data[SC_ITEMBOOST]->val1) / 100; if (pc_isvip(sd)) // Display drop rate increase for VIP dropbonus += (droprate * battle_config.vip_drop_increase) / 100; if (dropbonus) sprintf(atcmd_output2, " %s %02.02f%% + (%02.02f%%)", createItemLink(item_data->nameid, 0, NULL).c_str(), (float)droprate / 100, (float)dropbonus / 100); else sprintf(atcmd_output2, " %s %02.02f%%", createItemLink(item_data->nameid, 0, NULL).c_str(), (float)droprate / 100); strcat(atcmd_output, atcmd_output2); j++; clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1246)); // This monster has no drops. // mvp if (mob->mexp) { float mvppercent, mvpremain; sprintf(atcmd_output, msg_txt(sd,1247), mob->mexp); // MVP Bonus EXP:%u clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, msg_txt(sd,1248)); // MVP Items: clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); mvpremain = 100.0; //Remaining drop chance for official mvp drop mode j = 0; for (i = 0; i < MAX_MVP_DROP_TOTAL; i++) { if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL) continue; //Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5% mvppercent = (float)mob->mvpitem[i].p * mvpremain / 10000.0f; if(battle_config.item_drop_mvp_mode == 0) { mvpremain -= mvppercent; } if (mvppercent > 0) { j++; sprintf(atcmd_output2, " %s %02.02f%%", createItemLink(item_data->nameid, 0, NULL).c_str(), mvppercent); strcat(atcmd_output, atcmd_output2); clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); } } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1249)); // This monster has no MVP prizes. }
Hey mate! Thank you for this. I wish that this can be implemented to @whodrops as well.
*EDIT
Item linking is not necessary for @whodrops. Just the original drop rate + (bonuses) when you are on VIP or consumed Bubblegums. -
-
1 minute ago, GM Winter said:
hello how did you apply it on @kami command can you share it sir tia
Oh yeah. I just used the old diff. And viola! I might diffed it the wrong way the first time. I rediff it again just today.
-
Hi rA peeps. Is it possible to use Achievement messages to something else like announce?
-
1
-
-
Good job uploading txt version. Me i still use txt version.
-
The old diff works flawlessly! Just quick question. How do we use this to announce script? Thank you!
Oh yeah i discovered a bug using @kami command. The message will be doubled. All kami related. kamia kamib kamic
Any follow up with @kami fix? Also the /b. Thaaaaanks!Nevermind. I have fixed it theres no problem with the diff. Mabuhay!
Extended Cell PvP [1.7]
in Source Releases
Posted
Was able to make it work with my trunk. And yeah the dispell is somehow left out since the absorb spirit works with the mod. Any idea how to fix the dispell?