Jump to content

Vach

Members
  • Posts

    326
  • Joined

  • Last visited

Posts posted by Vach

  1. Got it working, here is the updated function and the script I used, in case anyone wants to use it for their server.

    I would vote that this be something added to the official stuff? Better written probably. It's a neat feature anyone could use for various reasons.

    
    //setmemo(i,s,i,i) - Changes memo 1,2,3 to the string indicated, at the coords indicated.
    BUILDIN_FUNC(setmemo) {
    
    TBL_PC *sd;// = script_rid2sd(st);
    int memo;
    int x,y;
    short mapid;
    //const char* mapname; //mapindex_name2id(str)
    
    sd = script_rid2sd(st);
    if( sd == NULL ) {
    ShowError("setmemo: Error, function called with no player attached to script.\n");
    return 0;
    }
    
    memo = script_getnum(st,2);
    //mapname = script_getstr(st,3);
    mapid = mapindex_name2id(script_getstr(st,3));
    x = script_getnum(st,4);
    y = script_getnum(st,5);
    
    if( !script_getstr(st,3) == C_STR || !script_getstr(st,3) ==  C_CONSTSTR )
    {
    ShowError("setmemo: mapname sent not a string!\n");
    script_pushint(st,0);
    return 0;// data type mismatch
    }
    
    if (!mapid) {
    ShowError("setmemo: mapname sent is not in proper format (remove '.gat')");
    script_pushint(st,0);
    return 0; }
    
    if (memo > MAX_MEMOPOINTS || memo > 3) {
    ShowError("setmemo: Requested memo is higher than 3 or unavailable to player.");
    script_pushint(st,0);
    return 0; }
    
    if (!x || !y) {
    ShowError("setmemo: map x and/or y coords set to 0 or less!\n");
    script_pushint(st,0);
    return 0; }
    
    //All checks complete, commense process.
    sd->status.memo_point[memo].map = mapid;
    sd->status.memo_point[memo].x = x;
    sd->status.memo_point[memo].y = y;
    script_pushint(st,1); // 1 is success.
    return 0;
    
    }
    

    Script choice:

    
    getmapxy(@mapname$,@mapx,@mapy,0);
    if (setmemo(1,@mapname$,@mapx,@mapy) == 1) {
    mes "...";
    mes "Success!";
    close; }
    

    The problem was the use of the function embedded into setting .map, apparently it did not configure properly. I made an error report anyway.

  2. ~ Prevent Client from Closing ~

    Disregarding, that I have no idea where to begin, I need some information on the desired behavior.

    • In-game - Exit to Windows
      Assume that should remain as it always was, quit to windows.
    • Char Select - Cancel
      Used to return to the login window, but since there is not any, it quits.
    • Char Select - Connection Reset
      Used to return to the login window, but since there is not any, it quits.
    • Login - Error
      Used to return to the login window, but since there is not any, it quits.
    • Login - Connection Reset
      Used to return to the login window, but since there is not any, it quits.
    • ...
      Anything I missed?

    The in-game exit to windows is totally fine.

    As for everything else, I would think returning back to the initial (blank) login-screen would be desired behavior.

    If that's not possible at all, you could make it go back to the license accept screen - which would have to be enabled to work but could be used as a last resort.

  3. There is only 7 numbers in that entry, skill cast database entries have 8. I'm not sure how this is causing things to react on your server. Perhaps it is interpreting it as "default". I get error messages on mapserv when I screw up those lines.

  4. What's the primary difference between this code and mine, at least in terms of functionality? The only main difference I see is setting the map index to a short and checking if the short is above 0 before setting the memo map.

    Have you tested it? The function I used in my npc script was "getmapxy" to find the map name... That might be the issue.

  5. Wow thanks!

    This totally put me on the right track, I ended up writing the following function:

    //setmemo(i,s,i,i) - Changes memo 1,2,3 to the string indicated, at the coords indicated.
    BUILDIN_FUNC(setmemo) {
    TBL_PC *sd;// = script_rid2sd(st);
    int memo;
    int x,y;
    const char* mapname; //mapindex_name2id(str)
    sd = script_rid2sd(st);
    if( sd == NULL ) {
     ShowError("setmemo: Error, function called with no player attached to script.\n");
     return 0;
    }
    memo = script_getnum(st,2);
    mapname = script_getstr(st,3);
    x = script_getnum(st,4);
    y = script_getnum(st,5);
    if( !script_getstr(st,3) == C_STR || !script_getstr(st,3) ==  C_CONSTSTR )
    {
     ShowError("setmemo: mapname sent not a string!\n");
     script_pushint(st,0);
     return 0;// data type mismatch
    }
    if (memo > MAX_MEMOPOINTS || memo > 3) {
     ShowError("setmemo: Requested memo is higher than 3 or unavailable to player.");
     script_pushint(st,0);
     return 0; }
    if (!x || !y) {
     ShowError("setmemo: map x and/or y coords set to 0 or less!\n");
     script_pushint(st,0);
     return 0; }
    //All checks complete, commense process.
    sd->status.memo_point[memo].map = mapindex_name2id(mapname);
    sd->status.memo_point[memo].x = x;
    sd->status.memo_point[memo].y = y;
    script_pushint(st,1); // 1 is success.
    return 0;
    }
    

    Unfortunately, when used properly in an NPC script it crashes the server. I know it gets to the point where the variables are overwritten and that's when the map crash occurs, so it at least gets to that point.

    I was wondering if someone could point out the errors in there?

    EDIT: OH MAN THAT'S UGLY PASTED! My apologies... >_<''

  6. Thanks Annie.

    HEY EVERYBODY IN SOURCE SUPPORT! Anyone know how to do something like this?

    I'm still learning the source and making new script commands is definitely something I'm a novice at.

    The source that Annie introduced in skill.c seems like the point where the memos are called and used to warp to... I would need to edit them and keep this part of the function intact. However:

    sd->status.memo_point[#].map
    

    seems to point to the data stored with the map information. I would need a script command to edit that? What about the coordinates? Or is editing this going to blow up the server?

  7. Hmmm... I know how to make the script based warp points, using variables, but I want to be able to use the Warp Portal skill which requires the use and manipulation of the memo save data.

    The first thing I want to do is give more control of creating memos, so you don't just replace the first, but this is just the beginning.

    You're sure memos cants be modified while the player is connected? In that case I may want to move this to source support, because I would need help making a new script command... I'm hoping this isn't necessary, though.

  8. My apologies for making another post, but I have tried a few things and still need a little help.

    Can someone give me an example of putting the memo data into some variables, and then editing the memo data within the script as well? I'd like to be able to pull/edit memos whenever via a function.

    Thank you everyone.

  9. Great Idea you had! I was coding something really similar using a db.txt file too. You should add some general options as battleconfigs, like general damage cap, general damage reduction or increase, etc as I did on mine.

    Also.. I was looking through your code and noticed this.

    md.damage = md.damage += md.damage*battle_SAD(sd, target, skill_num)/100;

    Isn't the '= md.damage' redundant?

    Also this.

    int flag = map[sd->bl.m].flag.restricted?8*map[sd->bl.m].zone:0;
    map[sd->bl.m].flag.restricted && skill_db[skill_num].flag&flag
    

    if map[sd->bl.m].flag.restricted exists you asign 8*map[sd->bl.m].zone at flag otherwise 0, then on the other condition if map[sd->bl.m].flag.restricted exists and the bit value you asigned to flag is in skill_db[skill_num].flag it triggers the condition. that logic is redundant too, because in the case if map[sd->bl.m].flag.restricted doesn't exists, as you stated an && on the second condition would be redundant if the second condition don't triggers because of the 0. I think would be better just like this.

    map[sd->bl.m].flag.restricted && skill_db[skill_num].flag&(8*map[sd->bl.m].zone)
    

    Great contribution! Have a nice day!

    I'm waiting until the Code Revision Reversion goes into effect before I update again, I just wanted to let you know.

    Thanks, it still doesn't work for me :(

    Open your battle.c src file.

    Find this line

    struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag);
    

    add before

    static int battle_SAD(struct map_session_data *sd, struct block_list *target, int skill_num)
    {
    int dmg = 0;
    int flag = map[sd->bl.m].flag.restricted?8*map[sd->bl.m].zone:0;
    if((skill_db[skill_num].flag&1 && !map_flag_vs(sd->bl.m))
    || (skill_db[skill_num].flag&2 && map[sd->bl.m].flag.pvp)
    || (skill_db[skill_num].flag&4 && map_flag_gvg(sd->bl.m))
    || (skill_db[skill_num].flag&8 && map[sd->bl.m].flag.battleground)
    || (map[sd->bl.m].flag.restricted && skill_db[skill_num].flag&flag))
    {
     switch(target->type)
     {
      case BL_PC:
    dmg = skill_db[skill_num].pc_damage;
    break;
      case BL_MOB:
    if(((TBL_MOB*)target)->status.mode&MD_BOSS)
     dmg = skill_db[skill_num].boss_damage;
    else
     dmg = skill_db[skill_num].mob_damage;
    break;
      default:
    dmg = skill_db[skill_num].other_damage;
    break;
     }
    }
    return dmg;
    }
    

    Look for this line.

      	 if( sd )
    	{
    		if (skill_num && (i = pc_skillatk_bonus(sd, skill_num)))
    			ATK_ADDRATE(i);
    

    add like this

    if( sd )
      	 if( sd )
    	{
    		ATK_ADDRATE(battle_SAD(sd, target, skill_num));
    		if (skill_num && (i = pc_skillatk_bonus(sd, skill_num)))
    			ATK_ADDRATE(i);
    

    Look for this line

     if(sd) {
      //Damage bonuses
    

    Add this

     if(sd) {
    					MATK_ADDRATE(battle_SAD(sd, target, skill_num));
      //Damage bonuses
    

    Look for this line

    if (sd && (i = pc_skillatk_bonus(sd, skill_num)))
     md.damage += md.damage*i/100;
    

    Replace like this

    if (sd)
    {
     if(i = pc_skillatk_bonus(sd, skill_num))
      md.damage += md.damage*i/100;
    
     md.damage = md.damage += md.damage*battle_SAD(sd, target, skill_num)/100;
    }
    

    On skill.c src file

    Find this line

    /*==========================================
     * DB reading.
     * skill_db.txt
    
    

    Add before

    static bool skill_parse_row_skilldamage(char* split[], int columns, int current)
    {
    int i = atoi(split[0]);
    i = skill_get_index(i);
    if( !i ) // invalid skill id
     return false;
    
    skill_db[i].flag  = atoi(split[1]);
    skill_db[i].pc_damage  = atoi(split[2]);
    skill_db[i].mob_damage  = atoi(split[3]);
    skill_db[i].boss_damage  = atoi(split[4]);
    skill_db[i].other_damage = atoi(split[5]);
    return true;
    }
    

    Find this line

    sv_readdb(db_path, "skill_changematerial_db.txt"
    

    Add after

    sv_readdb(db_path, "skill_damage_db.txt"	  , ',',   5,  6, MAX_SKILL_DB, skill_parse_row_skilldamage);
    

    On skill.h src file

    Find this line

     int unit_interval;
     int unit_target;
     int unit_flag;
    

    Add after

    int flag;
    int pc_damage,mob_damage,other_damage,boss_damage;
    

    Compile and you're done. Don't forget to create your db file. It should work perfectly on the latest revision.

    So, are all these necessary for the mod to work on the current revision, or are these just your efficiency changes? I haven't had a chance to test it but I wanted to make sure before I changed everything because I keep getting revision errors and I'm trying to avoid as many as possible.

  10. Is this possible? I want to link my checkpoint system with the warp portal skill.

    This would also allow me to create a dynamic NPC dialogue in which players can pick which slot to make memos, so they can save important warps they don't want to go anywhere... and get rid of the "Save Point" one.

    I'm assuming it can be done with some SQL queries but that stuff is beyond me at the moment.

  11. Yea, I was thinking that when I posted... why not just... do it now? ...but then I had my computer troubles and ah... I digress. XD

    Anyway, to change the functionality of these skills go to skill.c and find this block:

        case AL_INCAGI:
    case AL_BLESSING:
    case MER_INCAGI:
    case MER_BLESSING:
     if (dstsd != NULL && tsc->data[sC_CHANGEUNDEAD]) {
      skill_attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);
      break;
     }
    

    This section of code is earlier in the skill call and declares individual targets using:

    clif_skill_nodamage(src,bl,skillid,skilllv,
      sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
    

    Comment out the AL_INCAGI and AL_BLESSING lines here, NOTE, this will mean you cannot target undead with them anymore.

    Then find this block:

    case AL_ANGELUS:
    case PR_MAGNIFICAT:
    case PR_GLORIA:
    case SN_WINDWALK:
    case CASH_BLESSING:
    case CASH_INCAGI:
    case CASH_ASSUMPTIO:
     if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
      clif_skill_nodamage(bl, bl, skillid, skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
     else if( sd )
      party_foreachsamemap(skill_area_sub, sd, skill_get_splash(skillid, skilllv), src, skillid, skilllv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
     break;
    

    And add:

    //  Added here for "global cast effect"
    case AL_INCAGI:
    case AL_BLESSING:
    // ---
    

    Above it. After this it is very important you go to skill_db and make Increase AGI and Blessing mimic Angelus's skill db settings (target flags, etc.)

    And that was it!

  12. My apologies to everyone for my delay in responding. I have been having computer troubles and therefore only had access to this forum via mobile devices (no code to look at).

    That's pretty awesome, thank you Euphy. The part I was talking about with getarraysize() is what it returns for an array that doesn't exist, but you increased the value for the menu later in the script (since menus start at 1). So, that worked out. Although I think in order to compensate for that I'll start all the store arrays at 1 instead of 0 just to save the modifier later.

    Thanks everyone! I am probably going to go with Euphy's afterall because it allows me the easiest time making sub-menus (because the function can just be slightly modified to be called "when ready").

×
×
  • Create New...