Jump to content

Kenpachi

Core Developers
  • Content Count

    204
  • Joined

  • Last visited

  • Days Won

    32

Posts posted by Kenpachi


  1. Hi.

     

    Just add your code to the else if( sd ) block.

    		case PR_MAGNIFICAT:
    		case PR_GLORIA:
    		case SN_WINDWALK:
    		case CASH_BLESSING:
    		case CASH_INCAGI:
    		case CASH_ASSUMPTIO:
    		case WM_FRIGG_SONG:
    			if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
    				clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
    			else if( sd ) {
    				if (skill_id == PR_MAGNIFICAT) {
    					// Magnificat caster exclusive code.
    				}
    
    				party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
    			}
    			break;

     

     

    ~Kenpachi


  2. Hi.
     

    On 5/26/2020 at 6:47 AM, C H said:

    I cloned the latest Hercules but it seems like it is still buggy with item skill and some features added like unable to trade while character is dead.

     

    The item skill system was updated in v2020.05.31. If you still find issues, please report them or join #2709 and add some details.

    Allow trading and chat room actions when dead will be added in the next release, but you can apply #2755 yourself if you need this feature urgently.

     

     

    ~Kenpachi


  3. Hi.

     

    Example for changing a character's sprite to Acolyte:

    disguise(Job_Acolyte);
    
    // or
    
    disguise(4);

     

    From doc/script_commands.txt:

    Quote

    *disguise(<Monster ID>)
    *undisguise()

    This command disguises the current player with a monster sprite.
    The disguise lasts until undisguise() is issued or the player logs out.

    Example:

    disguise(PORING); // Disguise character as a Poring.
    next();
    undisguise(); // Return to normal character sprite.

    The description is misleading since it supports not only monster IDs, but also NPC sprite IDs or job IDs....

     

     

    ~Kenpachi


  4. Hi.

     

    From doc/script_commands.txt:

    Quote

    OnPCLoadMapEvent:

    This special label will trigger once a player steps in a map marked with
    the 'loadevent' mapflag
    and attach its RID. The fact that this label
    requires a mapflag for it to work is because, otherwise, it'd be
    server-wide and trigger every time a player would change maps. Imagine the
    server load with 1,000 players (oh the pain...)

    You have to enable this event for all maps you need.

     

    OnPCLoginEvent works fine for me.

     

     

    ~Kenpachi


  5. jRO Exclusive Monsters


    All jRO Exclusive, Event and Special Episode monsters.

    This file was originally posted by @fxfreitas at Midgard-Community.

     

    The archive contains the following monster sprites:

    • abyss_arthur (corridor of abyss special instance boss)
    • AMELIT (ghost carring a gemstone)
    • ANGLERFISH (Mini-boss)
    • CHAOS_DEVIL_DRAGON
    • deviruchi_w (a white deviruchi, event)
    • domovoi (custom pet, based on RO2 domovoi)
    • ECHIDNA
    • EMELIT (ghost carring a gemstone)
    • giant_deviruchi (event monster)
    • giant_deviruchi_w (event monster)
    • headless_mule (remake of original brasilis monster, last kRO already implemented)
    • HERA (Episode Monster)
    • j_taini (tiny, event monster and pet)
    • kraken_baby (marse edit)
    • LILITH (Episode Monster)
    • M_DARK_KNIGHT (Mercenary monster)
    • M_FLAME_KNIGHT (Mercenary monster)
    • M_ICE_KNIGHT (Mercenary monster)
    • M_LIGHT_KNIGHT (Mercenary monster)
    • M_STONE_KNIGHT (Mercenary monster)
    • merman_se (merman edit)
    • METAL_DRAGON (Pet and dungeon monster)
    • MYTHLIT (ghost carring a gemstone)
    • pad_fafnir (Can't Move, Can't Attack)
    • pad_helheim (Can't Move, Can't Attack)
    • pad_horai (Can't Move, Can't Attack)
    • pad_ifrit (Can't Move, Can't Attack)
    • pad_kinggold (Can't Move, Can't Attack)
    • pad_kingmetal (Can't Move, Can't Attack)
    • pad_leviathan (Can't Move, Can't Attack)
    • pad_muspelheim (Can't Move, Can't Attack)
    • pad_mythlit (Can't Move, Can't Attack)
    • pad_niraikanai (Can't Move, Can't Attack)
    • pad_shangrila (Can't Move, Can't Attack)
    • pad_tamadora (Pet)
    • pad_zaerog (Can't Move, Can't Attack)
    • pad_zerog (Can't Move, Can't Attack)
    • poseidon (strouf edit)
    • RUBYLIT (ghost carring a gemstone)
    • SAPPHLIT (ghost carring a gemstone)
    • seiren (obeaune edit)
    • SIREN (Episode Monster)
    • tacnu (Mini-boss)
    • TOPALIT (ghost carring a gemstone)

     


  6. Hi.

     

    That's a training dummy. 😄

    Spawn is located in npc/re/mobs/towns.txt.

    //== Prontera, Training Dummy Area =========================
    prontera,251,77,0,0	monster	Lv 50	2409,1,5000,0,0
    prontera,259,77,0,0	monster	Lv 50	2409,1,5000,0,0
    prontera,251,66,0,0	monster	Lv 100	2410,1,5000,0,0
    prontera,259,66,0,0	monster	Lv 100	2410,1,5000,0,0
    prontera,251,55,0,0	monster	Lv 150	2411,1,5000,0,0
    prontera,259,55,0,0	monster	Lv 150	2411,1,5000,0,0

     

     

    ~Kenpachi


  7. Hi.

     

    More than one itemskill() invocation per item is not support due to the mechanics of server-client-communication.

    When using the item, the first itemskill() invocation makes the server send a packet (ZC_AUTORUN_SKILL) to the client.

    Now the item's script isn't attached to the character anymore and thus the second itemskill() invocation can't be executed.

     

    Use sc_start() for the first skill, to "fix" this.

     

    I have to investigate how Aegis handles this, since there are official items which cast more than one skill. For example Angeling Potion (ID=12350).

    item Angeling_Potion
    	event OnConsume:
    		SkillToMe AL_BLESSING 5
    		Skill AL_ANGELUS 5
    	return

     

     

    ~Kenpachi


  8. Hi.

     

    The error is caused by this line:

    setd getd("$@PVPKill"+$@PVPcounter),getcharid(3);

    The value of $@PVPcounter is 1. Thus getd("$@PVPKill"+$@PVPcounter) returns the value of a variable with name $@PVPKill1.

    Since $@PVPKill1 is not a string variable, a number is returned and causes an error in setd().

     

    I assume your intention was to set $@PVPKill1 to the return value of getcharid(3).

    setd("$@PVPKill" + $@PVPcounter, getcharid(3));

     

     

    ~Kenpachi


  9. Hi.

     

    In src/map/script.c:

     

    Add this:

    BUILDIN(get_unique_id)
    {
    	struct map_session_data* sd = script_rid2sd(st);
    
    	if (sd == NULL)
    	{
    		script_pushint(st,0);
    		return false;
    	}
    
    	script_pushint(st, sockt->session[sd->fd]->gepard_info.unique_id);
    
    	return true;
    }

    Below:

    BUILDIN(resethate)
    {
    	struct map_session_data *sd;
    
    	if (script_hasdata(st, 2))
    		sd = script->id2sd(st, script_getnum(st, 2));
    	else
    		sd = script->rid2sd(st);
    
    	if (sd != NULL)
    		pc->resethate(sd);
    
    	return true;
    }

     

    And add this:

    BUILDIN_DEF(get_unique_id, ""),

    Below:

    BUILDIN_DEF(openlapineddukddakboxui, "i"),

     

    Don't forget to re-compile.

     

     

    ~Kenpachi


  10. Hi.

     

    Add this:

    	if (.@item_id < 5001 || (.@item_id > 5859 && .@item_id < 30000) || .@item_id > 31000) {
    		dispbottom("---------------[Morpho Helper]---------------");
    		dispbottom(" ");
    		dispbottom("Sorry, this headgear was not designed for this headgear slot.");
    		dispbottom(" ");
    		end;
    	}

    Below:

    	if ((.@keyword$ == "upper" || .@keyword$ == "middle" || .@keyword$ == "lower") && .@view_id <= 0) {
    		dispbottom("---------------[Morpho Helper]---------------");
    		dispbottom(" ");
    		dispbottom("Invalid headgear ID.");
    		dispbottom(" ");
    		end;
    	}

     

     

    ~Kenpachi


  11. The only timer related modification I found in this PR is that now 0 is passed for data when assigning ud->walktimer.

    Prior to this PR, the amount of added ticks was passed.

    • From:
      ud->walktimer = timer->add(timer->gettick()+i,unit->walktoxy_timer,bl->id,i);
      To:
      ud->walktimer = timer->add(timer->gettick() + timer_delay, unit->walk_toxy_timer, bl->id, 0); //TODO: check if unit->walk_toxy_timer uses any intptr data

       

    • From:
      ud->walktimer = timer->add(tick+i,unit->walktoxy_timer,id,i);
      To:
      ud->walktimer = timer->add(tick + timer_delay, unit->walk_toxy_timer, id, 0);

     

     

    unit_walk_toxy_timer() doesn't use the data parameter, but at least unit_stop_walking() uses the TimerData->data field.

    I can't tell if those changes are causing the error, yet. Unfortunately I'm unable to get that error popping up while debugging. 😥

     

     

    ~Kenpachi


  12. Hi.

     

    @4144

    The failed assertion for deleting unit_walk_toxy_timer timers was reported to me several times since https://github.com/HerculesWS/Hercules/pull/2546 was merged.
     

    • https://herc.ws/board/topic/18060-mob-bug/#comment-94997
       
    • From Discord:
      Quote

      Fiction 18.03.2020

      I don't know if this is a bug, but some mobs spam the map-server with an error
      https://prnt.sc/rin813

       

    • From PM:
      Quote
      
      [Error]: timer_do_delete error : function mismatch [179](nil)(unknown timer function) != 0x5609b422dfc0(unit_walk_toxy_timer)
      [Error]: --- failed assertion --------------------------------------------
      [Error]: timer.c:398: '0' in function `timer_do_delete'
      [Error]: ./map-server(+0x24a8ef) [0x5609b42448ef]
      [Error]: ./map-server(+0x2560dc) [0x5609b42500dc]
      [Error]: ./map-server(+0x23bbfa) [0x5609b4235bfa]
      [Error]: ./map-server(+0x23847a) [0x5609b423247a]
      [Error]: ./map-server(+0x2392c9) [0x5609b42332c9]
      [Error]: ./map-server(+0xf7cd2) [0x5609b40f1cd2]
      [Error]: ./map-server(+0xf4e4e) [0x5609b40eee4e]
      [Error]: ./map-server(+0xfac26) [0x5609b40f4c26]
      [Error]: ./map-server(+0xf4528) [0x5609b40ee528]
      [Error]: ./map-server(+0xed7b7) [0x5609b40e77b7]
      [Error]: --- end failed assertion ----------------------------------------

       

     

     

     

    ~Kenpachi


  13. Hi.

     

    Add this:

    // Required item ID/amount for morphing.
    .morpho_req_id = 501;
    .morpho_req_amount = 1;

    Below:

    // Equip IDs - Change these to the ID numbers of the hat you wish to designate as the Morphing hat
    .top_morpho = 25092;
    .mid_morpho = 25093;
    .low_morpho = 25094;

     

    And replace:

    	if (.@keyword$ == "upper" || .@keyword$ == "middle" || .@keyword$ == "lower") {
    		if (.@keyword$ == "upper") {
    			morpho_id_top = .@item_id;
    			setlook(LOOK_HEAD_TOP, .@view_id);
    		}

    With:

    	if (.@keyword$ == "upper" || .@keyword$ == "middle" || .@keyword$ == "lower") {
    		if (countitem(.morpho_req_id) < .morpho_req_amount) {
    			dispbottom("---------------[Morpho Helper]---------------");
    			dispbottom(" ");
    			dispbottom("You need " + .morpho_req_amount + "x " + getitemname(.morpho_req_id) + " for morphing.");
    			dispbottom(" ");
    			end;
    		}
    
    		delitem(.morpho_req_id, .morpho_req_amount);
    
    		if (.@keyword$ == "upper") {
    			morpho_id_top = .@item_id;
    			setlook(LOOK_HEAD_TOP, .@view_id);
    		}

     

     

    ~Kenpachi


  14. Hi.

     

    //members id
    getpartymember(getcharid(CHAR_ID_PARTY), 1);

    You have to use type 2 instead of 1 to get the account ID of all party members instead of their char IDs.
    (The getunits() command will collect the GID of found units, which is the account ID for player type units. (BL_PC))

    Additionally you should immediately save the IDs  and the member count to prevent other scripts from interfering with your data.

    // Get party data.
    getpartymember(getcharid(CHAR_ID_PARTY), 2);
    .@p_mem_cnt = $@partymembercount;
    copyarray(.@p_mem_aid[0], $@partymemberaid[0], .@p_mem_cnt);


                                                                                                                                                                                                                                                                                                                                

     

    .@range= 10;

    This should be 5 for a 10x10 area. When setting this to 10, your area is 20x20.

     

                                                                                                                                                                                                                                                                                                                                

     

    .@count = getunits((BL_MOB | BL_PC), .@units, -1, .@m$, max(0, .@x - .@range), max(0, .@y - .@range), .@x + .@range, .@y + .@range);

    Any reason to get monster type units (BL_MOB), too? 😯 If you only want to heal party members you should only collect player type units (BL_PC).

    Also better use false for <limit>. -1 works, too, but is less readable.

    .@count = getunits(BL_PC, .@units, false, .@m$, max(0, .@x - .@range), max(0, .@y - .@range), .@x + .@range, .@y + .@range);


                                                                                                                                                                                                                                                                                                                                


     

    And finally you have to add a nested loop to your loop to compare the account IDs. (Loop through found units and for each iteration loop through party members.)

    for (.@i = 0; .@i < .@count; .@i++) {
    	dispbottom(".@units[" + .@i + "]: " + .@units[.@i]); //debug - print the user id (getunits)
    
    	for (.@j = 0; .@j < .@p_mem_cnt; .@j++) {
    		dispbottom(".@p_mem_aid[" + .@j + "]: " + .@p_mem_aid[.@j]); //debug - print the user id (getpartymember)
    
    		if (.@units[.@i] == .@p_mem_aid[.@j]) {
    			dispbottom("Party member found. Try healing!"); //debug - party member found
    
    			if (attachrid(.@p_mem_aid[.@j])) {
    				percentheal(.@porcent, .@porcent);
    				specialeffect(310, AREA, playerattached());
    			}
    		}
    	}
    }

     

     

    That's just a quick draft. Syntax errors are for free. 😋


    ~Kenpachi


  15. Hi.

     

    In src/map/skill.c in function skill_castend_nodamage_id() find this block:

    case RK_CRUSHSTRIKE:
    case ALL_ODINS_POWER:
    case SU_FRESHSHRIMP:
    case SU_ARCLOUSEDASH:
    	clif->skill_nodamage(src,bl,skill_id,skill_lv,
    		sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
    	break;
    // Works just like the above list of skills, except animation caused by
    // status must trigger AFTER the skill cast animation or it will cancel
    // out the status's animation.
    case SU_STOOP:

     

    And replace:

    clif->skill_nodamage(src,bl,skill_id,skill_lv,
    	sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
    break;

    With:

    // End EDP if Assassin Cross uses LK_BERSERK or MO_EXPLOSIONSPIRITS.
    if (sd != NULL && sd->job == MAPID_ASSASSIN_CROSS && sd->sc.data[SC_EDP] != NULL
        && (skill_id == LK_BERSERK || skill_id == MO_EXPLOSIONSPIRITS)) {
    	status_change_end(&sd->bl, SC_EDP, INVALID_TIMER);
    }
    
    int fail = sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
    clif->skill_nodamage(src, bl, skill_id, skill_lv, fail);
    break;

     

     

    ~Kenpachi

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.