Jump to content

Jonne

Members
  • Posts

    149
  • Joined

  • Last visited

Posts posted by Jonne

  1. Your MAX_GUILD is 25. The original formular is 16+10*6. Change it back to this and the error disappears. It's in src/common/mmo.h. The original code is:

    #define MAX_GUILD 16+10*6 // increased max guild members +6 per 1 extension levels [Lupus]
  2.  

    - Got to test this yesterday, our intended effect was for it to proc when we get hit not when we attack, any idea on how to restrict that?

     

    - Also, I just gave tick a 10 second duration, but it still doesn't kick in, I've no idea why.

     

    - Is this by any chance, the endure effect? I've yet to test this

     

    @@ -6176,6 +6185,8 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c

            return 0;

        if( sc->data[sC_RUN] || sc->data[sC_WUGDASH] )

            return 0;

        if ((pc_checkskill((TBL_PC*)bl, NPC_GMPOWER)) > 0)

            return 0;

     

    -Ah i thought when you hit something. I can change that, but not today, because I'm busy with university assigments.

    -Yes, that's the endure effect

  3.  

    if (skill = pc_checkskill(sd, NPC_GMPOWER)) {
    +            int tick;
    +            rate = skill*2 * 100;
    +            tick = skill_get_time2(status_sc2skill(SC_VOICEOFSIREN), skill);
    +            status_change_start(src, bl, SC_VOICEOFSIREN, rate, skill, 0, 0, 0, tick, 0);
    +        }
    

    Auto Attacks cancel the SC, maybe that's the case?

     

     

    - By the looks of it, since it was added as int skill_additional_effect I'm guessing that it would naturally proc on both but as observed, would only last skill*2*100, which only lasted something like 0.2 seconds in the client, it was gone as soon as it casted, at lvl 10 to boot. For some weird reason, x*skill only does x*1? Did we miss calling some stuff?

     

    - I just noticed, since youre calling get_time2 for SC_VOICEOFSIREN, maybe that's the skill level its checking for?

     

     

    1. It procs for AA after the AA, just like SK card and so on.

    2. The time is exactly the time of the skill Voice of Siren. I use skill_get_time2 with the skill level of the GM skill.

    If it does occur, either increase the "skill(level)" in skill_get_time2 or increase "tick" before giving it as parameter in the status_change_start call (better option). A second is 100.

  4.  

    - Siren doesn't work, it procs when I attack them and nothing happens, is this what you meant by creating the SC? Doesn't VOS already have it's own? Ill try and fix this tomorrow after I get off work.

     

    - Things to test / make: Endure effect, HP recovery/s [non percentile], auto 50% heal when under 10% hp, monster drop custom item id

    No, because I use the SC of Siren:

    if (skill = pc_checkskill(sd, NPC_GMPOWER)) {
    +            int tick;
    +            rate = skill*2 * 100;
    +            tick = skill_get_time2(status_sc2skill(SC_VOICEOFSIREN), skill);
    +            status_change_start(src, bl, SC_VOICEOFSIREN, rate, skill, 0, 0, 0, tick, 0);
    +        }
    

     

    Auto Attacks cancel the SC, maybe that's the case?

  5. You did not state that I was wrong in any case, you just confirmed my given input.

    I will provide the src edit for your skill, you still need to do the DB work, but this should be as stated in the Wiki.

    Also this patch is really dirty and hardcoded, but it's because this passive skill is actually so strong and I was too lazy adding an extra SC for it, etc.

     

    Edit: Using the new Pastebin: Paste: 9yf2sxdzew

  6. First note : http://rathena.org/wiki/Adding_new_skills has data on making Active / Casted skills. After reading through some of the source codes, I found close to nothing about the creation of permanent passive skills.

     

    • Second note : Passive weapon damage augment skills like Sword mastery, Two Hand Sword mastery, etc are empty skill ids, the only thing they do is have an ID and have a skill level which is then taken to battle.c to be processed like below

    		case W_FIST:
    			if((skill = pc_checkskill(sd,TK_RUN)) > 0)
    				damage += (skill * 10);
    			// No break, fallthrough to Knuckles
    		case W_KNUCKLE:
    			if((skill = pc_checkskill(sd,MO_IRONHAND)) > 0)
    				damage += (skill * 3);
    			break;
    		case W_MUSICAL:
    			if((skill = pc_checkskill(sd,BA_MUSICALLESSON)) > 0)
    				damage += (skill * 3);
    			break; 

    case w_fist means unarmed so its using tk_run "mastery" for damage increase, and if my understanding is correct, it will also increase knuckle damage o.o... but yeah, that's how it gets calculated, no informative data in skill.c at all, just an ID.

     

    • The request : So how do we add a passive skill that heals you 100 x skill level per X second? [ a passive form of tension relax that is always on. a skill version of bonus2 bHPRegenRate,n,x; item script ] The actual skill effect looks like this

    [PASSIVE] Max level 10
    - permanent endure effect
    - +100% move speed
    - +50% attack speed
    - recover 100 x skill level hp per 500 ms
    - reflect 3 x skill level of melle damage
    - reflect 4 x skill level of range damage
    - reduce damage taken by 3 x skill level [class_all]
    - heal 50% of your hp if HP falls under 1 x skill level [10% at max leve]
    - 2 x skill level chance of getting item id 30050 whenever you kill a monster / player
    - 2 x skill level chance of charming enemies when hit [voice of siren effect]
    

    • Adding this data to the wiki would be extremely informative as it does not include information about passive skills.

     

    • The skill is meant to be put on a custom class for GM events, most of these effects can be replicated through item scripts but the goal here is to make a passive skill, that way we can just switch to a class and not need to prepare items that have the special effects.

     

    It is not mentioned in the wiki because it should be quite self-explainatory. It's about the same as adding an active skill, except leaving anything related to actually using the skill out and just check for those conditions in the code where the skill is actually checked and does something. For example when auto-attacking and using sword mastery passive. So you add the skill into the skill.h, skill db and skill tree. Then you go looking for the HP regen function (pc.c or something) and while calculating the HP regen you also check for the passive skill and apply its effect.

  7. @Jonne

    I think its more resource wise to set a source variable in pc.h like *pcblockmove did

    I got lectured by brainstorm before already

    http://www.eathena.ws/board/index.php?s=&showtopic=270470&view=findpost&p=1487092

    lol my previous post ... totally forgot about this

    https://github.com/rathena/rathena/tree/master/src/custom

    I think should move every single custom script command into this file

     

    Did not know about the custom folder, thanks.

     

    Ye it is more resource-wise, but harder for the scripter to apply, imho. Just as I said, it's not the finest solution, but it should do what is needed.

  8. It's definitly source edit. I did some digging and tried out something, not sure if it's the best solution, but might fit your need. It introduces two new script commands: setvisibility and getvisibility.

     


    * setvisibility <value>{, <"npc">}
    * @param <value> the value to set it and checkf or
    * @param <"npc"> if another NPC should be targetted

     

    You set the value of the NPC to a value not 0. Only players with the character variable "npcvisibility" set to this exact value can now see the NPC. It should also not effect NPCs which have no visibility set, since it ignores the value zero. You have to put this into the OnInit event, since I didn't add a saving mechanism so it will be deleted once you reload. Thus the OnInit.

     
     
    * getvisibility {<"npc>"}
    * @param <"npc"> if another NPC should be targetted
    **/

    Self explaning, imho.

     

    An example:

    // Some NPC here
    OnInit:
    SetVisibility(1);
    End;

    Only a player with the variable "npcvisibility" set to 1 can see the npc now.

     

    The patch:

     

    diff --git a/src/map/clif.c b/src/map/clif.c
    index 2731018..099466f 100644
    --- a/src/map/clif.c
    +++ b/src/map/clif.c
    @@ -4152,11 +4152,16 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl)
      if (!vd || vd->class_ == INVISIBLE_CLASS)
      return;
    
    
    - /**
    - * Hide NPC from maya purple card.
    - **/
    - if(bl->type == BL_NPC && !((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
    - return;
    + if(bl->type == BL_NPC) {
    + /**
    + * Hide NPC from maya purple card.
    + **/
    + if (!((TBL_NPC*)bl)->chat_id && (((TBL_NPC*)bl)->sc.option&OPTION_INVISIBLE))
    + return;
    + // Only show NPC to people who have a certain variable set
    + if (((TBL_NPC*)bl)->visibility != 0 && ((TBL_NPC*)bl)->visibility == pc_readglobalreg(sd, "npcvisibility"))
    + return;
    + }
    
    
      ud = unit_bl2ud(bl);
      len = ( ud && ud->walktimer != INVALID_TIMER ) ? clif_set_unit_walking(bl,ud,buf) : clif_set_unit_idle(bl,buf,false);
    diff --git a/src/map/npc.h b/src/map/npc.h
    index ab9d084..b4b6552 100644
    --- a/src/map/npc.h
    +++ b/src/map/npc.h
    @@ -70,6 +70,7 @@ struct npc_data {
      char killer_name[NAME_LENGTH];
      } tomb;
      } u;
    + int visibility;
     };
    
    
    
    
    diff --git a/src/map/script.c b/src/map/script.c
    index eda82c7..681867f 100644
    --- a/src/map/script.c
    +++ b/src/map/script.c
    @@ -18165,6 +18165,43 @@ static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
      return SCRIPT_CMD_SUCCESS;
     }
    
    
    +/**
    + * setvisibility <value>{, <"npc">}
    + * @param <value> the value to set it and checkf or
    + * @param <"npc"> if another NPC should be targetted
    +**/
    +BUILDIN_FUNC(setvisibility) {
    + struct npc_data *nd = NULL;
    +
    + if (script_hasdata(st, 3)) {
    + nd = npc_name2id(script_getstr(st, 3));
    + ShowWarning("buildin_setvisibility: NPC '%s' not found. Using active NPC.\n", script_getstr(st, 3));
    + }
    + if (nd == NULL)
    + nd = map_id2nd(st->oid);
    +
    + nd->visibility = script_getnum(st, 2);
    + return SCRIPT_CMD_SUCCESS;
    +}
    +
    +/**
    + * getvisibility {<"npc>"}
    + * @param <"npc"> if another NPC should be targetted
    +**/
    +BUILDIN_FUNC(getvisibility) {
    + struct npc_data *nd = NULL;
    +
    + if (script_hasdata(st, 2)) {
    + nd = npc_name2id(script_getstr(st, 2));
    + ShowWarning("buildin_getvisibility: NPC '%s' not found. Using active NPC.\n", script_getstr(st, 2));
    + }
    + if (nd == NULL)
    + nd = map_id2nd(st->oid);
    +
    + script_pushint(st, nd->visibility);
    + return SCRIPT_CMD_SUCCESS;
    +}
    +
     #include "../custom/script.inc"
    
    
     // declarations that were supposed to be exported from npc_chat.c
    @@ -18648,6 +18685,8 @@ struct script_function buildin_func[] = {
      BUILDIN_DEF(vip_time,"i?"),
     #endif
      BUILDIN_DEF(bonus_script,"si???"),
    + BUILDIN_DEF(setvisibility, "i?"),
    + BUILDIN_DEF(getvisibility, "?"),
    
    
     #include "../custom/script_def.inc"
    • Upvote 2
  9. Try this. You also should add the cell to your const.txt for easier script usage. Here it would be cell number 10, but if you added another cell, it might be higher. Check the CELL_* enum in map.h

    diff --git a/src/map/battle.c b/src/map/battle.c
    index 6b7cf4b..63c1c4b 100644
    --- a/src/map/battle.c
    +++ b/src/map/battle.c
    @@ -763,6 +763,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
      if( battle_config.ksprotection && mob_ksprotected(src, bl) )
      return 0;
     
    + if (map_getcell(bl->m, bl->x, bl->y, CELL_CHKSAFECELL))
    + return 0;
    +
      if( map_getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) && skill_get_type(skill_id) != BF_MISC
      && skill_get_casttype(skill_id) == CAST_GROUND )
      return 0;
    diff --git a/src/map/map.c b/src/map/map.c
    index 2c8bf35..ced139c 100644
    --- a/src/map/map.c
    +++ b/src/map/map.c
    @@ -2718,6 +2718,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
      case CELL_NOCHAT:        map[m].cell[j].nochat = flag;        break;
      case CELL_MAELSTROM:  map[m].cell[j].maelstrom = flag;   break;
      case CELL_ICEWALL:  map[m].cell[j].icewall = flag;   break;
    + case CELL_SAFECELL:  map[m].cell[j].safecell = flag;   break;
      default:
      ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
      break;
    diff --git a/src/map/map.h b/src/map/map.h
    index c584671..26f8b52 100644
    --- a/src/map/map.h
    +++ b/src/map/map.h
    @@ -460,6 +460,7 @@ typedef enum {
      CELL_NOCHAT,
      CELL_MAELSTROM,
      CELL_ICEWALL,
    + CELL_SAFECELL
     
     } cell_t;
     
    @@ -484,6 +485,7 @@ typedef enum {
      CELL_CHKNOCHAT,
      CELL_CHKMAELSTROM,
      CELL_CHKICEWALL,
    + CELL_CHKSAFECELL
     
     } cell_chk;
     
    @@ -503,7 +505,8 @@ struct mapcell
      novending : 1,
      nochat : 1,
      maelstrom : 1,
    - icewall : 1;
    + icewall : 1,
    + safecell : 1;
     
     #ifdef CELL_NOSTACK
      unsigned char cell_bl; //Holds amount of bls in this cell.
    diff --git a/src/map/skill.c b/src/map/skill.c
    index 117c0a7..efb1aab 100644
    --- a/src/map/skill.c
    +++ b/src/map/skill.c
    @@ -2247,6 +2247,8 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
      break;
      case BL_PC: {
      struct map_session_data *sd = BL_CAST(BL_PC, target);
    + if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKSAFECELL))
    + return 0;
      if( sd->sc.data[SC_BASILICA] && sd->sc.data[SC_BASILICA]->val4 == sd->bl.id && !is_boss(src))
      return 0; // Basilica caster can't be knocked-back by normal monsters.
      if( !(flag&0x2) && src != target && sd->special_state.no_knockback )
     
    
  10.  

    or the easier way is the Attack part is a card

    slot in a drops_card into knife[3] becomes Dexterious Knife

    so can make a new card, common_card into knife[3] becomes Common Knife, with the common_card having property Attack +3

    so just have to create 7 customs cards and its done in no time

    the problem is there's no color coded anymore

    if  i would use your idea i should have a additional slot dedicated only for the rarity enchantment is this possible ??

     

    Slots will be filled up, but the item doesn't need them for the server to put them into. At least afaik

  11. Non-intrusive was meant in that way, that you do not need to patch the client to load your DLL. You are still free to hot-patch* any client-code at will.

    To make the client call your DLL functions, you have to hot-patch* the client when your DLL is loaded.

    *) basically applying hexes/patches in client's memory.

    I see. So I alter the binary code to call my functions, since it has laoded the DLL?

  12. Well there ain't much database on the src code, or you mean the running data ? like charid_db etc ?

    What do you think about the jathena implementation, do you guys think we should implement it ? too difficult to use ?

    It doesn't feel like it's too hard to use. There might be some people actually using that, but wouldn't encouraging SQL be better? Well, I didn't look deep into the code, but it seems fine, so why not ask other devs and start a poll on it?

     

    Edit: For reference: Check the npc_test_csv.txt file in the jAthena folder. It's in sample.

  13. Checkout the comment and the code, well your's will work fine, the only thing Ai4rei mentionned is that you didn't have to open the file at each action cause that is slower. (summerized).

    You could very well mimic C behaviour and specifically open(file) and close(file) and retain a reference

    Imagine doing

    .@i = 0;
    do {
     .@line$ = readline("rathena_db.txt".@i);
     .@i++;
    } while(.@line$ != "");
    

    This is line parsing each line of your db and reading it, (idk maybe to found an ID then read the rest of the line)

    So in real that will open and close the file at each loop incrementation wich is quite ugly..

    Now the issue about retain the pointer and expect people to close the file is that looking more and more of doing C, sure you won't have thread issues yet. (Like 2 people talking to the NPC it's still 1 execution at the time (that what he was saying)) but they could very well forget to close it and/or try to reopen it with or timer and such so it's an issue. (sorry if I may sound to look down but a good % of people scripting ain't expert of file descriptor issues).

     

    I think a ok solution would be to retain the FH in a pointer but to limit is life to a scope {}. //he will auto close the file when he's leaving it (a bit like perl).

    But to begin I'm sure the think you have done is fine.

    You may want to add a split function tought

    In src what Emistry started to quote is :

    sv_readdb( db_path, "rathena_db.txt",char_delimiter$,min_col_number, max_col_number, max_line_number, &parse_function);

    parse_function(char* fields[], int columns, int current){

     //fields data in each field

     //current is the line number

     //colunms is the number of col in that line

    }

    Ye it comes back to me. I didn't read through it again. Well if it still works you can try it out. Depending on what you are trying this might not be what you want. For example if you want access to the database in the src code? But otherwise this might work.

  14. Hm.

    Is there a Option to give buffs a longer Duration e.g.

    if I (Admin) have equip Item XYZ => The buff i ´ll give to other player will have a duration of 15 min.

     

    So that there is a diffrent between User Buffs and Buffs wich u get from an Admin ?

    thx for the @ all comm ^^ anyway the Item option would be greater.

    Yes that would be possible, but quite the hardcode just for buffing. I'm not home so I can't provide anything, but might give it a shot next year.

     

    OT: It feels like you're trying to add ways to cheat/abuse as admin? :P

  15. Revert the diff I gave you (but only for the skill.c) and apply this one:

    diff --git a/src/map/skill.c b/src/map/skill.c
    index 117c0a7..7d3a586 100644
    --- a/src/map/skill.c
    +++ b/src/map/skill.c
    @@ -11176,6 +11176,12 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
      wx = sd->menuskill_val>>16;
      wy = sd->menuskill_val&0xffff;
     
    + // check whether it's allowed to cast AL_WARP there
    + if (map_getcell(sd->bl.m, wx, wy, CELL_CHKNOWARPPORTAL)) {
    + skill_failed(sd);
    + return 0;
    + }
    +
      if( lv <= 0 ) return 0;
      if( lv > 4 ) lv = 4; // crash prevention
     
    
  16. It's in skill.c in skill_weaponrefine:

     

    /*==========================================
     * Weapon Refine [Celest]
     *------------------------------------------*/
    void skill_weaponrefine (struct map_session_data *sd, int idx)
    {
    nullpo_retv(sd);
     
    if (idx >= 0 && idx < MAX_INVENTORY)
    {
    int i = 0, ep = 0, per;
    int material[5] = { 0, 1010, 1011, 984, 984 };
    struct item *item;
    struct item_data *ditem = sd->inventory_data[idx];
    item = &sd->status.inventory[idx];
     
    if(item->nameid > 0 && ditem->type == IT_WEAPON)
    {
    
  17. Isn't this rather in clif_joinchatok ?

    /// Notifies the client about entering a chatroom (ZC_ENTER_ROOM).
    /// 00db <packet len>.W <chat id>.L { <role>.L <name>.24B }*
    /// role:
    ///     0 = owner (menu)
    ///     1 = normal
    void clif_joinchatok(struct map_session_data *sd,struct chat_data* cd)
    {
    int fd;
    int i,t;
     
    nullpo_retv(sd);
    nullpo_retv(cd);
     
    fd = sd->fd;
    if (!session_isActive(fd))
    return;
    t = (int)(cd->owner->type == BL_NPC);
    WFIFOHEAD(fd, 8 + (28*(cd->users+t)));
    WFIFOW(fd, 0) = 0xdb;
    WFIFOW(fd, 2) = 8 + (28*(cd->users+t));
    WFIFOL(fd, 4) = cd->bl.id;
     
    if(cd->owner->type == BL_NPC){
    WFIFOL(fd, 30) = 1;
    WFIFOL(fd, 8) = 0;
    memcpy(WFIFOP(fd, 12), ((struct npc_data *)cd->owner)->name, NAME_LENGTH);
    for (i = 0; i < cd->users; i++) {
    WFIFOL(fd, 8+(i+1)*28) = 1;
    memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
    }
    } else
    for (i = 0; i < cd->users; i++) {
    WFIFOL(fd, 8+i*28) = (i != 0 || cd->owner->type == BL_NPC);
    memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
    }
    WFIFOSET(fd, WFIFOW(fd, 2));
    }
    

    Try this maybe:

    /// Notifies the client about entering a chatroom (ZC_ENTER_ROOM).
    /// 00db <packet len>.W <chat id>.L { <role>.L <name>.24B }*
    /// role:
    ///     0 = owner (menu)
    ///     1 = normal
    void clif_joinchatok(struct map_session_data *sd,struct chat_data* cd)
    {
    int fd;
    int i,t;
     
    nullpo_retv(sd);
    nullpo_retv(cd);
     
    fd = sd->fd;
    if (!session_isActive(fd))
    return;
    t = (int)(cd->owner->type == BL_NPC);
    WFIFOHEAD(fd, 8 + (28*(cd->users+t)));
    WFIFOW(fd, 0) = 0xdb;
    WFIFOW(fd, 2) = 8 + (28*(cd->users+t));
    WFIFOL(fd, 4) = cd->bl.id;
     
    if(cd->owner->type == BL_NPC){
    char name[NAME_LENGTH+1];
    char *pos;
     
    strcpy(name, ((struct npc_data *)cd->owner)->name);
    pos = strchr(name, '#');
    if (pos != NULL) {
    *pos = '\0';
    }
    WFIFOL(fd, 30) = 1;
    WFIFOL(fd, 8) = 0;
    memcpy(WFIFOP(fd, 12), name, NAME_LENGTH);
    for (i = 0; i < cd->users; i++) {
    WFIFOL(fd, 8+(i+1)*28) = 1;
    memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
    }
    } else
    for (i = 0; i < cd->users; i++) {
    WFIFOL(fd, 8+i*28) = (i != 0 || cd->owner->type == BL_NPC);
    memcpy(WFIFOP(fd, 8+(i+t)*28+4), cd->usersd[i]->status.name, NAME_LENGTH);
    }
    WFIFOSET(fd, WFIFOW(fd, 2));
    }
    
    • Upvote 1
  18. Try this. It adds a new Cell which is called cell_nowarpportal. You can't cast warp portals onto those cells. 

    diff --git a/db/const.txt b/db/const.txt
    index 76926dc..9320e38 100644
    --- a/db/const.txt
    +++ b/db/const.txt
    @@ -388,6 +388,7 @@ cell_basilica 4
     cell_landprotector 5
     cell_novending 6
     cell_nochat 7
    +cell_nowarpportal 10
     
     //cell_gettype 0
     cell_chkwall 1
    diff --git a/src/map/map.c b/src/map/map.c
    index 2c8bf35..176d2d1 100644
    --- a/src/map/map.c
    +++ b/src/map/map.c
    @@ -2664,6 +2664,8 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk)
      return (cell.maelstrom);
      case CELL_CHKICEWALL:
      return (cell.icewall);
    + case CELL_CHKNOWARPPORTAL:
    + return (cell.nowarpportal);
     
      // special checks
      case CELL_CHKPASS:
    @@ -2718,6 +2720,8 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
      case CELL_NOCHAT:        map[m].cell[j].nochat = flag;        break;
      case CELL_MAELSTROM:  map[m].cell[j].maelstrom = flag;   break;
      case CELL_ICEWALL:  map[m].cell[j].icewall = flag;   break;
    + case CELL_NOWARPPORTAL:  map[m].cell[j].nowarpportal = flag;   break;
    +
      default:
      ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
      break;
    diff --git a/src/map/map.h b/src/map/map.h
    index c584671..56bd72c 100644
    --- a/src/map/map.h
    +++ b/src/map/map.h
    @@ -460,6 +460,7 @@ typedef enum {
      CELL_NOCHAT,
      CELL_MAELSTROM,
      CELL_ICEWALL,
    + CELL_NOWARPPORTAL,
     
     } cell_t;
     
    @@ -484,6 +485,7 @@ typedef enum {
      CELL_CHKNOCHAT,
      CELL_CHKMAELSTROM,
      CELL_CHKICEWALL,
    + CELL_CHKNOWARPPORTAL,
     
     } cell_chk;
     
    @@ -503,7 +505,8 @@ struct mapcell
      novending : 1,
      nochat : 1,
      maelstrom : 1,
    - icewall : 1;
    + icewall : 1,
    + nowarpportal : 1;
     
     #ifdef CELL_NOSTACK
      unsigned char cell_bl; //Holds amount of bls in this cell.
    diff --git a/src/map/skill.c b/src/map/skill.c
    index 117c0a7..d5ff5bd 100644
    --- a/src/map/skill.c
    +++ b/src/map/skill.c
    @@ -13397,6 +13397,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
      clif_displaymessage(sd->fd, output); //"Duel: Can't use %s in duel."
      return 0;
      }
    + if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOWARPPORTAL)) {
    + char output[128];
    + sprintf(output, msg_txt(sd, 1404), skill_get_name(AL_WARP));
    + clif_displaymessage(sd->fd, output); //"Warpportal failed."
    + return 0;
    + }
      break;
      case MO_CALLSPIRITS:
      if(sc && sc->data[SC_RAISINGDRAGON])
    
×
×
  • Create New...