ID:266006
 
I have reached a dilemma in my design process. I cannot figure out how to handle "equip-effects" in my game. What is an equip-effect? When a player equips an item that has a side-effect of increasing or decreasing a stat from being equipped; that is called an equip-effect. For example: I equip a body armor of fortitude, and my maximum health increases by 10.

However, some of these effects are only temporary and can get messed up with other such types of effects in my game. Such as when a player is inflicted with a condition called Fatigue, they suffer 25% less maximum health. If a player saves with such a condition, and then they log back in, they will no longer have that condition, but the effect will remain. Basically, when they save with that particular condition, they effectively give themselves 25% less maximum health permanently.

I'm wondering as to how I should handle Equip-effects as to not interfere with other temporary effects that I do not want saved. I do hope this was clear enough >.<
Temp variables can be of use here for effects like temporary fatigue. Since temp vars don't save one whatever they're attached to, they'll reset when you logout/login.
In my game, I call a certain proc for each variable anytime I need to use it in a formula. These procs add up the individual buffs and return the player's stat + buff. That way the base variable doesn't change.


A rough example:

mob
proc
fortitude()
var/buff
for(var/x in fortitude_buffs) // Or even do an associative list and search buffs["fortitude"]
if(x == "25%)
buff += src.fortitude*1.25
if(isnum(x))
buff += x
return (src.fortitude + buff)


In response to Kalzar
text2num() would help you greatly.
In response to Pyro_dragons
But the non-savable effect modifies a variable that IS saved.
condition
fatigue
effect(mob/a)
a.hp -= a.max_hp/25
a.max_hp -= a.max_hp/25
uneffect(mob/a)
a.hp += //?
//this is another ^ part where I am stuck

mob/var
tmp/list/conditions //a list of whatever conditions they have; non-savable
hp = 100 //savable
max_hp = 100 //savable
obj/body_armor
equip(mob/a)
a.hp += 10
a.max_hp += 10
Something along the lines of this would work great for equipment as well as any other types of effects you may want.

For your 25% less maximum health for example, you'd want a "less health" status that removes a percent of current hp (and keeps track of how much was removed since adding a % back could cause problems if stuff changes in different order). Nothing would happen for tick events, as the effect gets removed when the equipment does.

temporary effects that I do not want saved.

You could use this for those effects as well, and you could have them continue after logging out.
In response to Xioden
That is pretty much exactly what I already use for "conditions". The conditions list variable, however, is a tmp variable, so it isn't saved. I'm worried about the player saving while its effect(s) are in place, logging out, and then logging back in with no conditions whatsoever, but with reduced or increased stats (aka, a bug exploit!).

This is my "condition system". As you can see, it's pretty much identical to what you suggested.
mob/var/tmp/list/conditions
condition
var
duration
New(mob/a,dur,mob/b) //a is the victim; dur is the duration being set; b is the "caster" of the condition which is only used if the condition has a degenerative effect on A's health
if(!a.conditions) a.conditions = new
var/condition/c = locate(src.type) in a.conditions
if(c)
c.duration = dur //renewed with the new timer, not additive
del src
src.duration = dur
a.conditions += src
src.effect(a,b) //again, b is only used for degenerative effects
proc
effect()
remove(mob/a)
a.conditions -= a
if(!a.conditions.len) a.conditions = null
del src

Now for the "fatigue" condition...
condition
fatigue
effect(mob/a)
var/x = a.max_hp/4
a.max_hp -= x
a.hp -= x
spawn(src.duration)
src.remove(a,x)
remove(mob/a,x)
a.max_hp += x
a.hp += x
..()

To make it so that I don't have to continue the conditions after relogging (basically, keep them temporary), would I have to do a check in the saving procedure for this particular condition so that it saves the hp/max_hp variables correctly? Or should I just make the conditions savable, but then remove them all upon loading to achieve the same effect? I kinda like the latter option a bit better.
In response to Spunky_Girl
Spunky_Girl wrote:
That is pretty much exactly what I already use for "conditions". The conditions list variable, however, is a tmp variable, so it isn't saved. I'm worried about the player saving while its effect(s) are in place, logging out, and then logging back in with no conditions whatsoever, but with reduced or increased stats (aka, a bug exploit!).

To make it so that I don't have to continue the conditions after relogging (basically, keep them temporary), would I have to do a check in the saving procedure for this particular condition so that it saves the hp/max_hp variables correctly? Or should I just make the conditions savable, but then remove them all upon loading to achieve the same effect? I kinda like the latter option a bit better.

Probably better off making them savable, since this type of system is good for any type of temporary effects you want on stats.

Someone could log out to clear themselves of any conditions they don't like, which could also be considered a bug exploit, so its worth keeping that in mind as well if you are planning on removing some on login.
In response to Xioden
When they relog, they will be placed into their "hometown" spawn. So if they're out in the "wilderness" fighting and want to avoid conditions, then relogging isn't the way since you'd have to walk/run all the way back to where you were, and pretty much start all over.
In response to Spunky_Girl
So if they want to go back quickly then all they need to do is relog?

Interesting way to try and stop people from relogging but there will be people who still abuse it.
In response to Spunky_Girl
Ah, in that case you could always just leave conditions as they are are and duplicate it for effects that don't get removed at logout but rather, for example, when the piece of equipment is removed.
In response to Kalzar
Think of it like Guild Wars, if you've played it. There's map-traveling, and you start off in the towns/outposts and enter instances. When you relog, you will spawn in whatever town/outpost you were in last. You can map-travel to any town/outpost you've been to at any time you wish. Now apply the same concept.
In response to Xioden
Elaborate? I'm not sure if I understand what you're getting at :\
In response to Spunky_Girl
Spunky_Girl wrote:
Elaborate? I'm not sure if I understand what you're getting at :\

Scratch what I said earlier, you mentioned how it works like guild wars, so in that case I'd say just remove the temporary tag from the the list, give conditions a temporary variable, and any time you want conditions removed loop through and remove any temporary ones.
In response to Spunky_Girl
Spunky_Girl wrote:
> condition
> fatigue
> effect(mob/a)
> a.hp -= a.max_hp/25
> a.max_hp -= a.max_hp/25
> uneffect(mob/a)
> a.hp += //?
> //this is another ^ part where I am stuck


To reserve the effect, you need to do the opposite operation, i.e. adding what you've removed. Since the value removed is dynamic, you need to store it statically for later use, as its expression could hold a different value later, when you want to use it.

(Why wouldn't you save a mob's current effects?)
I wrote [link] a while ago. Obviously, you could just have it only save effects that are labeled permanent.

Also that implementation assumes that whatever is done by the effect beginning is saved in the savefile. The logic would be different if you had to re-apply the effect upon loading it.
In response to Kaioken
Yeah I gathered that and made the following changes. I didn't really want to save their conditions because of how the game works. But I made a workable alternate that achieves the same effect. :)
condition/fatigue
var/value
effect(mob/a)
src.value = a.max_hp/4
a.max_hp -= src.value
a.hp -= src.value
spawn(src.duration)
src.end(a)
remove(mob/a)
a.max_hp += src.value
a.hp += src.value
..()
It's not *directly* related to the topic, but I'd like to give you some suggestions about the way you implement this effect. First, I think the name 'fatigue' doesn't imply the person can die from it, but the way you implement it would make him die if he's within 25% of his maximal HP - why not reduce HP by 25%, too? Second, if the player does die from it, it will be hard to detect this because you affect the HP var directly... using a proc to mediate health loss is a better choice design-wise.
In response to Toadfish
I think you mistake my fatigue condition for a degenerative effect... All it does is reduce your maximum health by 25% (implied that it also reduces your current health by that same 25% value, which you should have gotten if you read my fatigue snippet). You can't die from it; you can just die sooner if you are fatigued. And to check if a player has it, I would just see if(locate(/condition/fatigue) in src.conditions) and do whatever from there.

EDIT
For example:
Someone with 100 maximum health and 50 current health, gets hit with fatigue. He will lose 100/4 maximum health and 100/4 current health, thus leaving him with 75 max health and 25 current health.
In response to Spunky_Girl
I'm not sure whether I'm missing something or it's a problem with the implementation, but take a look at your code:

    src.value = a.max_hp/4
a.max_hp -= src.value
a.hp -= src.value


Assume this case: 100 maximum HP, 25 current HP. The code would go like this:

value = (100 / 4) = 25
max_hp = (100 - value) = 75
hp = (25 - value) = 0

If you wanted to reduce HP by 25%, you would need to make a calculation separate from max HP.
Page: 1 2