Jump to content
  • 0

Zeny Penalty 100% of the Time


Vach

Question


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

I would like to request a simple source adjustment to allow the Zeny percentage penalty adjusted in the conf files to be applicable even outside of PVP. Is this possible?

Link to comment
Share on other sites

14 answers to this question

Recommended Posts


  • Group:  Members
  • Topic Count:  81
  • Topics Per Day:  0.02
  • Content Count:  1654
  • Reputation:   583
  • Joined:  08/09/12
  • Last Seen:  

OnPCDieEvent ?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

OnPCDieEvent ?

I was thinking about that, but I am going to save that as a last resort because I know somewhere in the source the setting you can enable in the conf file is called when someone dies, I just have to broaden it's scope of when it goes off.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  81
  • Topics Per Day:  0.02
  • Content Count:  1654
  • Reputation:   583
  • Joined:  08/09/12
  • Last Seen:  

exp.conf

// When a player dies (to another player), how much zeny should we penalize them with?
// NOTE: It is a percentage of their zeny, so 100 = 1%
zeny_penalty: 0

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

Yea, that's the setting I was talking about; but it only applies when a player dies to another player - not to anything (monsters).

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  81
  • Topics Per Day:  0.02
  • Content Count:  1654
  • Reputation:   583
  • Joined:  08/09/12
  • Last Seen:  

In pc.c, find 'pc_setdead(sd);'

//...
if( pc_issit(sd) ) {
clif_status_load(&sd->bl,SI_SIT,0);
}

pc_setdead(sd);
//...

Add this below the line and recompile

unsigned int base_penalty =0;
if(battle_config.zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty)
{
base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
if(base_penalty)
pc_payzeny(sd, base_penalty);
}

Note, it's untested ;P

Another workaround, still inf pc.c:

if (src && src->type == BL_PC)
{
struct map_session_data *ssd = (struct map_session_data *)src;
pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
npc_script_event(ssd, NPCE_KILLPC);
//...

Edit it into:

if (src && src->type == BL_PC ) || (src && src->type == BL_MOB )
{
struct map_session_data *ssd = (struct map_session_data *)src;
pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
npc_script_event(ssd, NPCE_KILLPC);

If you use the second one, everytype of penalty (exp, zeny, karma) will work on 'killed by monster' too.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  8
  • Topics Per Day:  0.00
  • Content Count:  148
  • Reputation:   46
  • Joined:  11/02/11
  • Last Seen:  

You could make a *little* optimization on your code.

unsigned int base_penalty = 0;
if (battle_config.zeny_penalty > 0 && ||>> sd->status.zeny > 0 && <<|| !map[sd->bl.m].flag.nozenypenalty) <--------------------
{
base_penalty = (unsigned int)((double)sd->status.zeny * (double)battle_config.zeny_penalty / 10000.);
pc_payzeny(sd, base_penalty);
}

:)

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

Hmmm... I'm not entirely sure which one I want to use. I understand how both work but I'm not sure if I want to blanket all deaths that were supposed to be PC only with the mobs as well. I will test and report back later.

EDIT: Doing my research I discovered none of the penalties ever occur unless you are killed by a player... and nothing else. If this is as designed, I didn't know about it.

I ended up going with your second option so that all the penalty checks are run through in case I ever decide to set an XP penalty (not likely).

DOUBLE EDIT:

Nevermind, using the second option sends piles of errors from the mapserver "randomly" for some reason. When using the first, it wouldn't compile unless I moved "unsigned int base_penalty = 0;" somewhere else in the code. It was strange, like declaring it next to the if statement was against syntax. Especially because the error was "Error 10 error C2143: syntax error : missing ';' before 'type'" ...and all I did was declare a variable.

Any insight on why doing so would make an error depending on where the variable is placed would be great, because I am stumped. Otherwise, it works if I move the declaration to the top near the other variables. Thank you.

Edited by Vach
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  57
  • Reputation:   15
  • Joined:  12/25/11
  • Last Seen:  

What kind of errors are you receiving in the second one?

Option one doesn't work, because when compiling C code, variable declarations have to be done first in a function body. Move the declaration up to the beginning of the function and it'll work.

Actually it may also work at the beginning of a block. Meaning you could move the declaration into the if-block { }.

Which compiler are you using?

Edit: For more information you can look up on C-standards. In C99 you can declare variables anywhere, similar to C++. However, as you may have noticed, it's a wise idea to declare variables at the beginning of a block to guarantee compiler portability.

Edited by Realusion
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

What kind of errors are you receiving in the second one?

Option one doesn't work, because when compiling C code, variable declarations have to be done first in a function body. Move the declaration up to the beginning of the function and it'll work.

Actually it may also work at the beginning of a block. Meaning you could move the declaration into the if-block { }.

Which compiler are you using?

Edit: For more information you can look up on C-standards. In C99 you can declare variables anywhere, similar to C++. However, as you may have noticed, it's a wise idea to declare variables at the beginning of a block to guarantee compiler portability.

In regards to the second solution, which I preferred because it sort of works within the code, I receive multiple map-server errors, including but not limited to:

  • Map server crashes (random)
  • OnPCKill events are being called by monsters killing players which causes numerous errors, including Debug messages saying scripts using the OnPCKill have no RID attached (because there wouldn't be, it's a monster)
  • Most of the time the zeny or XP isn't even penalized, and instead I lose 100z or nothing.
  • Unable to login if killed by a monster recently (random).
  • Excessive lag.

As you can see, the code is expecting only player kills, so something special would have to be programmed in.

I am using Microsoft Visual Studio 2012 Express, as recommended by the Wiki. After I moved the variable declaration everything worked fine, but I thank you for letting me know. I'm not 100% up to C-Standards, as I've been programming with C++ all my life so this is a tad different.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  57
  • Reputation:   15
  • Joined:  12/25/11
  • Last Seen:  

I just took a look at the source to find a suitable place for this change when I noticed that there isn't even a check to determine whether the person was killed by a monster or a player to apply the zeny penalty. So I went ahead and tried it in-game and indeed - in my case - being killed by a monster effectively reduced the amount of zeny I had. I'm kind of confused now.

However, I'm not using a clean rAthena revision, but then again, I don't recall making any changes which could affect this behavior. Would you please be so kind to try and reproduce this situation? Because either it only works like this on my end, or the documentation in the conf file is wrong and the zeny penalty is applied anyway, regardless of being killed by a monster or a player.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

So it works for you on a clean file? That is really confusing. I'll copy over a clean pc.c and check it out... I remember testing it before I even touched the code to make sure I wasn't wasting my time... hmmm.

From what I saw in the code, all the penalty triggers only flipped (activated) after a check if the source of death was "Player." I actually do think the conf documentation is incorrect because the XP penalty has never worked on my server.

Are you using an uo to date revision?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  57
  • Reputation:   15
  • Joined:  12/25/11
  • Last Seen:  

My revision is up-to-date, but heavily modified by myself. As I said, I don't remember making any changes that could affect this, though.

if(battle_config.death_penalty_type
 && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
 && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
 && !sd->sc.data[sC_BABY] && !sd->sc.data[sC_LIFEINSURANCE])
{

// PENALTY CHECKS ARE HERE
}

the only thing, that is checked is the map_session_data sd, which is the dead player in this case. However, there's no sign of a check on WHO killed the player. Am I just confused or is there a

if (src->type == BL_PC)

missing?

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  81
  • Topics Per Day:  0.02
  • Content Count:  1654
  • Reputation:   583
  • Joined:  08/09/12
  • Last Seen:  

There's already 'killerrid'.

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  21
  • Topics Per Day:  0.00
  • Content Count:  326
  • Reputation:   19
  • Joined:  09/27/12
  • Last Seen:  

I'm not sure why, but if I run it on clean code no penalties occur unless it is by a player. It has something to do with the following line, it somehow affects how the penalties are run:

if (src && src->type == BL_PC)
{
 struct map_session_data *ssd = (struct map_session_data *)src;
 pc_setparam(ssd, SP_KILLEDRID, sd->bl.id);
 npc_script_event(ssd, NPCE_KILLPC);

Bah, I don't know enough about the code yet, I don't feel like I could speculate.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...