-
Content Count
204 -
Joined
-
Last visited
-
Days Won
33
Content Type
Profiles
Forums
Downloads
Staff Applications
Calendar
Everything posted by Kenpachi
-
Adding Limit or Cap Resistance, Reflect Chance, and Skill Delay
Kenpachi replied to ThyroDree's question in Source Support
Okay. First of all: I'M STUPID! Second of all: I'M STUPID! And thirdly: I'M STUPID! Change "max" to "min" and 150 back to 50.... Did I mention, that I'm stupid? ~Kenpachi -
Blast Mine will bypass 1 damage for plant monster
Kenpachi replied to ThyroDree's question in Database Requests
Hi. In src/map/battle.c find function battle_calc_misc_attack() and replace: switch(skill_id){ case HT_LANDMINE: case MA_LANDMINE: case HT_BLASTMINE: case HT_CLAYMORETRAP: case RA_CLUSTERBOMB: #ifdef RENEWAL break; #endif default: md.damage = 1; } With: switch(skill_id){ case HT_BLASTMINE: break; case HT_LANDMINE: case MA_LANDMINE: case HT_CLAYMORETRAP: case RA_CLUSTERBOMB: #ifdef RENEWAL break; #endif default: md.damage = 1; } ~Kenpachi -
[PVP Announcer] buildin_getcharid: invalid parameter (8)
Kenpachi replied to ThyroDree's question in Script Support
Hi. Replace: set .AnnounceFlag$, "bc_all"; With: set .AnnounceFlag, bc_all; In line 189, 191, 193 and 273 replace: 16|.announce With: .AnnounceFlag, .AnnounceColor$ In line 221 replace: announce strcharinfo(0) +" , Stop killing "+ rid2name(killedrid) + " !!!",0; With: announce strcharinfo(0) +" , Stop killing "+ rid2name(killedrid) + " !!!", .AnnounceFlag, .AnnounceColor$; In line 294, 295, 303, 304, 310, 311, 317, 318, 324 and 325 replace: 16 With: .AnnounceFlag, .AnnounceColor$ No you can change the color by modifying .AnnounceColor$. ~Kenpachi -
Hi. Have a look at battle_calc_defense() in src/map/battle.c. If I remember correctly, you're running your server in pre-RE mode, so I guess you're most interested in this line: damage = damage * pdef * (def1+vit_def) / 100; ~Kenpachi
-
Just in case someone else wants to know how to add the sound... Add (for the character who obtained the item): clif->soundeffect(sd, &sd->bl, "sound_file_name.wav", 0); Below this line: clif->message(sd->fd, output); Add (for party members): clif->soundeffect(p_sd, &p_sd->bl, "sound_file_name.wav", 0); Below this line: clif->message(p_sd->fd, output); The sound file is read from data\wav folder, must be in the PCM format, and the file name should have a maximum length of 23 characters including the ".wav" extension. ~Kenpachi
-
Adding Limit or Cap Resistance, Reflect Chance, and Skill Delay
Kenpachi replied to ThyroDree's question in Source Support
Okay, I misunderstood you here. The code I posted caps the total tolerance at 50%, but - if I get it right - you want to cap the additional (respectively bonus) tolerance at 50%. Now you have to be a bit more specific because the tolerances are modified by 3 different things: Skills - for example Dragonology (SA_DRAGONOLOGY) or Eucharistica (AB_EUCHARISTICA) Status changes - for example Skull Scroll (ID: 12745) (SC_SKELSCROLL) or Royal Scroll (ID: 12747) (SC_ROYALSCROLL) Equipment bonuses - for example Weeder Knife (ID: 1227) or Combat Knife (ID: 1228) If you don't want to distinguish between those 3 cases, you just have to replace the 50 with 150. This way the bonus tolerance is capped at 50% regardless of how the bones was applied. Otherwise please tell me how to handle each case. //BTW: I'll move this topic to the Source Support section. ~Kenpachi -
do i need to recompile the server? i just play ragnarok offline
Kenpachi replied to airzy's question in General Server Support
Hi. You only need to compile the servers once to create the executable files. Re-compiling is required if you change something inside the source files ("src" folder). ~Kenpachi -
[PVP Announcer] buildin_getcharid: invalid parameter (8)
Kenpachi replied to ThyroDree's question in Script Support
Hi. In line 288 replace getcharid(.@killer_gid) with .@killer_gid. Same in line 295. ~Kenpachi -
I guess you applied the changes manually and accidentally broke something. I used a untouched copy of Hercules and applied the patch file with TortoiseGit. -> No issue. ~Kenpachi
-
Hi. Unfortunately I were not able to create a plugin, because I couldn't hook at all required spots. But if you want to, you can use this patch: showdrop.patch Just tell me if something doesn't work as intended or needs modification. ~Kenpachi
-
The "someone" is confusing me. This is how I understand your description: -> Player A, B and C are in the same party. -> Player A uses @showdrop. -> Player A, B or C loots an item with a drop chance of 1% or below. -> Show message to player A, B and C. I don't think this is a good idea, since player A affects the gameplay of player B and C even if they don't want it. Even worse: They won't know about @showdrop being enabled until the first drop message is shown. If I misunderstood your description, please correct me. ~Kenpachi
-
Hi. In src/map/unit.c find function unit_walktobl() and replace: if (unit->walk_toxy_sub(bl) == 0 && (flag & 2) != 0) { set_mobstate(bl); return 1; } with: if (unit->walk_toxy_sub(bl) == 0) { if ((flag & 2) != 0) set_mobstate(bl); return 1; } And re-compile. ~Kenpachi
-
Hi. When saying "group", you mean party? ~Kenpachi
-
Hi. Here you go: I re-wrote the original script, so if you have modifications in your version, you have to apply them again. Sorry. ~Kenpachi
-
Sorry, my fault. It's ITEMINFO_VIEWSPRITE instead of ITEMINFO_VIEWID. ~Kenpachi
-
Hi. Compiles just fine for me, after adding those curly brackets. 😯 OnPCUseSkillEvent_1.5.c ~Kenpachi
-
Hi. For those errors replace: case INF_ATTACK_SKILL: struct enemyskilldata enemyskill_; enemyskill_.skill_id = skill_id; enemyskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( enemyskill, 1, 1 ); VECTOR_PUSH( enemyskill, enemyskill_ ); break; case INF_SUPPORT_SKILL: struct friendskilldata friendskill_; friendskill_.skill_id = skill_id; friendskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( friendskill, 1, 1 ); VECTOR_PUSH( friendskill, friendskill_ ); break; case INF_GROUND_SKILL: struct placeskilldata placeskill_; placeskill_.skill_id = skill_id; placeskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( placeskill, 1, 1 ); VECTOR_PUSH( placeskill, placeskill_ ); break; case INF_SELF_SKILL: struct selfskilldata selfskill_; selfskill_.skill_id = skill_id; selfskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( selfskill, 1, 1 ); VECTOR_PUSH( selfskill, selfskill_ ); break; with: case INF_ATTACK_SKILL: { struct enemyskilldata enemyskill_; enemyskill_.skill_id = skill_id; enemyskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( enemyskill, 1, 1 ); VECTOR_PUSH( enemyskill, enemyskill_ ); break; } case INF_SUPPORT_SKILL: { struct friendskilldata friendskill_; friendskill_.skill_id = skill_id; friendskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( friendskill, 1, 1 ); VECTOR_PUSH( friendskill, friendskill_ ); break; } case INF_GROUND_SKILL: { struct placeskilldata placeskill_; placeskill_.skill_id = skill_id; placeskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( placeskill, 1, 1 ); VECTOR_PUSH( placeskill, placeskill_ ); break; } case INF_SELF_SKILL: { struct selfskilldata selfskill_; selfskill_.skill_id = skill_id; selfskill_.event = aStrdup(VECTOR_INDEX(tempskill, i).event); VECTOR_ENSURE( selfskill, 1, 1 ); VECTOR_PUSH( selfskill, selfskill_ ); break; } That's just a fix for the posted error messages. There may be more issues... ~Kenpachi
-
Hi. The mob_avail.txt was merged with the mob_db.conf. See doc/mob_db.txt for more info. ~Kenpachi
-
Hi. Replace (3 times): getiteminfo(.@var1$,11) With: getiteminfo(.@var1$, ITEMINFO_VIEWID) ~Kenpachi
-
Hi. It's case-sensitive. Use "@item Shoes_". ~Kenpachi
-
Hi. npc-duplicate.c (Additional parameter for duplicateremove() the to choose if mobs spawned by duplicate should be removed, too.) ~Kenpachi
- 19 replies
-
- duplicate command
- duplicate script
- (and 3 more)
-
Magic difference between min. and max. dmg
Kenpachi replied to Zero Human's question in Source Support
Hi. If you want to change the minimum damage for specific skills, you have to modify battle_calc_magic_attack() in src/map/battle.c. If you want to change the it generally, you have to modify the MATK calculation in status_get_matk_sub() (RE) or status_base_matk_min() (pre-RE) in src/map/status.c. And to answer your question in No specific tutorial for Hercules. But there are tons of "C for beginners" guides available on the web. ~Kenpachi -
in src/map/skill.c -> skill_attack() // Change: if (damage > 0 && dmg.flag&BF_SKILL && tsd && pc->checkskill(tsd,RG_PLAGIARISM) && (!sc || !sc->data[SC_PRESERVE]) && damage < tsd->battle_status.hp // To: if (damage > 0 && dmg.flag&BF_SKILL && tsd && pc->checkskill(tsd,RG_PLAGIARISM) && (!sc || !sc->data[SC_PRESERVE]) && damage < tsd->battle_status.hp && src->type == BL_PC // Skill was cast by a character. Okay, misunderstood you here. I though you want to end the poison status when a Lord Knight casts Berserk or a Monk casts Fury. In this case I need an explanation. I don't know what you want to achieve. In src/map/pc.c -> pc_bonus() // Change: case SP_ADD_HEAL_RATE: if(sd->state.lr_flag != 2) sd->bonus.add_heal_rate += val; break; case SP_ADD_HEAL2_RATE: if(sd->state.lr_flag != 2) sd->bonus.add_heal2_rate += val; break; // To: case SP_ADD_HEAL_RATE: if(sd->state.lr_flag != 2) sd->bonus.add_heal_rate += val; sd->bonus.add_heal_rate = min(sd->bonus.add_heal_rate, 100); break; case SP_ADD_HEAL2_RATE: if(sd->state.lr_flag != 2) sd->bonus.add_heal2_rate += val; sd->bonus.add_heal2_rate = min(sd->bonus.add_heal2_rate, 100); break; // ################################################################################################### // Change: case SP_SKILL_HEAL: if(sd->state.lr_flag == 2) break; ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2); if (i == ARRAYLENGTH(sd->skillheal)) { // Better mention this so the array length can be updated. [Skotlex] ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val); break; } if (sd->skillheal[i].id == type2) sd->skillheal[i].val += val; else { sd->skillheal[i].id = type2; sd->skillheal[i].val = val; } break; case SP_SKILL_HEAL2: if(sd->state.lr_flag == 2) break; ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2); if (i == ARRAYLENGTH(sd->skillheal2)) { // Better mention this so the array length can be updated. [Skotlex] ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val); break; } if (sd->skillheal2[i].id == type2) sd->skillheal2[i].val += val; else { sd->skillheal2[i].id = type2; sd->skillheal2[i].val = val; } break; // To: case SP_SKILL_HEAL: if(sd->state.lr_flag == 2) break; ARR_FIND(0, ARRAYLENGTH(sd->skillheal), i, sd->skillheal[i].id == 0 || sd->skillheal[i].id == type2); if (i == ARRAYLENGTH(sd->skillheal)) { // Better mention this so the array length can be updated. [Skotlex] ShowDebug("script->run: bonus2 bSkillHeal reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal), type2, val); break; } if (sd->skillheal[i].id == type2) sd->skillheal[i].val += val; else { sd->skillheal[i].id = type2; sd->skillheal[i].val = val; } sd->skillheal[i].val = min(sd->skillheal[i].val, 100); break; case SP_SKILL_HEAL2: if(sd->state.lr_flag == 2) break; ARR_FIND(0, ARRAYLENGTH(sd->skillheal2), i, sd->skillheal2[i].id == 0 || sd->skillheal2[i].id == type2); if (i == ARRAYLENGTH(sd->skillheal2)) { // Better mention this so the array length can be updated. [Skotlex] ShowDebug("script->run: bonus2 bSkillHeal2 reached it's limit (%d skills per character), bonus skill %d (+%d%%) lost.\n", ARRAYLENGTH(sd->skillheal2), type2, val); break; } if (sd->skillheal2[i].id == type2) sd->skillheal2[i].val += val; else { sd->skillheal2[i].id = type2; sd->skillheal2[i].val = val; } sd->skillheal2[i].val = min(sd->skillheal2[i].val, 100); break; That's done in the functions I posted. I can't believe your status.c doesn't contain them. Well, I guess one could call them like this. ~Kenpachi
-
Hi. at_follow.diff Create a new zone in db/(pre-)re/map_zone_db.conf. For example: { name: "NoFollow" disabled_commands: { follow: 90 } } And add the maps where you want to disable @follow to npc/mapflag/zone.txt, For example: geffen mapflag zone NoFollow payon mapflag zone NoFollow yuno mapflag zone NoFollow ~Kenpachi
-
Hi. More details please. I'm not sure what you really want to do. In src/map/battle.c -> battle_calc_weapon_attack() // Change: && (sd == NULL || sd->weapontype1 == W_DAGGER || sd->weapontype1 == W_1HSWORD || sd->weapontype == W_2HSWORD) // To: && (sd == NULL || (sd->weapontype1 >= W_DAGGER && sd->weapontype1 <= W_2HAXE)) In src/map/skills.c -> skill_castend_nodamage_id() // Change: 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; // To: 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))); if (sd != NULL && (skill_id == LK_BERSERK || skill_id == MO_EXPLOSIONSPIRITS)) status_change_end(src, SC_DPOISON, INVALID_TIMER); break; In src/map/battle.c -> battle_calc_damage() // Change: if( ( sc->data[SC_PNEUMA] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG ) || sc->data[SC__MANHOLE] ) { d->dmg_lv = ATK_BLOCK; return 0; } // To: if ((sc->data[SC_PNEUMA] != NULL && (flag & (BF_MAGIC | BF_LONG)) == BF_LONG) || sc->data[SC__MANHOLE] != NULL) { if (sc->data[SC_PNEUMA] == NULL // Not Pneuma but Man Hole -> Block attack! || skill_id != HT_BLITZBEAT // Not Blitz Beat -> Block attack! || s_sd == NULL // Attacker is not a character -> Block attack! || s_sd->job != MAPID_SNIPER) { // Attacker is not a Sniper -> Block attack! d->dmg_lv = ATK_BLOCK; return 0; } } // ############################################################################################## // Change: if(sc->data[SC_NJ_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG) return 0; // To: if (sc->data[SC_NJ_TATAMIGAESHI] != NULL && (flag & (BF_MAGIC | BF_LONG)) == BF_LONG) { if (skill_id != HT_BLITZBEAT // Not Blitz Beat -> Block attack! || s_sd == NULL // Attacker is not a character -> Block attack! || s_sd->job != MAPID_SNIPER) { // Attacker is not a Sniper -> Block attack! return 0; } } Modify skill_add_heal_rate in conf/map/battle/skill.conf. I guess you want to modify the bonus stats. Therefor just search for these constants in src/map/status.c: SC_TRUESIGHT SC_MINDBREAKER SC_DELUGE SC_VIOLENTGALE SC_VOLCANO In src/map/status.c have a look at these functions: status_base_matk_min() status_base_matk_max() That's not as easy as you may think. To keep it simple, just don't apply the bMatk and bMatkRate bonuses. In src/map/pc.c -> pc_bonus() // Change: case SP_MATK_RATE: if(sd->state.lr_flag != 2) sd->matk_rate += val; break; // To: case SP_MATK_RATE: break; // ############################################################################################## // Change: case SP_EMATK: if(sd->state.lr_flag != 2) sd->bonus.ematk += val; break; // To: case SP_EMATK: break; ~Kenpachi