• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ [Nostalrius/Sabrehaven] Magic fields don't always do collision damage

X X X

Newb
Joined
Jul 26, 2015
Messages
148
Reaction score
13
Expected behavior: anytime a player steps onto a magic field, they are supposed to take instant damage and there should be an effect, and the condition starts over.
Actual behavior: If a player is logged out with a condition (kicked, xlog, /r), when they log back in, they will no longer take instant damage from stepping on magic fields
Patterns: If this 'bug' occurs, the player can use 'exana pox' and then fields will start doing instant damage again.
Errors?: no errors in console.
Changes: no changes to the poison field item, no changes to movements, no changes to sources.

My attempt to trace the problem through code:
the field item ID itself looks like all other fields, has a type, count, and damage which is the instant damage:
Code:
TypeID      = 2121
Name        = "poison gas"
Flags       = {CollisionEvent,Unmove,Avoid,MagicField,Expire}
Attributes  = {AvoidDamageTypes=POISON,Brightness=2,LightColor=104,ExpireTarget=0,TotalExpireTime=250}
MagicField  = {Type=POISON,Count=100,Damage=5}

When a player steps on it, it uses the function "onStepInField"
XML:
<movevent event="StepIn" itemid="2121"  function="onStepInField" />

Movements.cpp tells us where to look for the onStepInField function:
C++:
bool MoveEvent::loadFunction(const pugi::xml_attribute& attr)
{
    const char* functionName = attr.as_string();
    if (strcasecmp(functionName, "onstepinfield") == 0) {
        stepFunction = StepInField;
//break
uint32_t MoveEvent::StepInField(Creature* creature, Item* item, const Position&)
{
    MagicField* field = item->getMagicField();
    if (field) {
        field->onStepInField(creature);
        return 1;
    }

    return LUA_ERROR_ITEM_NOT_FOUND;
}

This function is in combat.cpp, line 1889. For the sake of not making this so long I wont post the whole thing but you can see that all it does is add the condition to the player.

The function for AddCondition in condition.cpp looks like this:

C++:
void ConditionDamage::addCondition(Creature* creature, const Condition* addCondition)
{
    if (addCondition->getType() != conditionType) {
        return;
    }

    const ConditionDamage& conditionDamage = static_cast<const ConditionDamage&>(*addCondition);

    if (hit_damage) {
        doDamage(creature, -conditionDamage.hit_damage); //this is where the player should take instant damage from
    }

    if (!updateCondition(addCondition)) {
        return;
    }

    owner = conditionDamage.owner;
    cycle = conditionDamage.cycle;
    count = conditionDamage.count;
    max_count = conditionDamage.max_count;
}

EDIT---I was wrong, the problem occurs for ALL magic fields. Edited post
 
Last edited:
Back
Top