I'm having a really weird issue in boost python. I'm focusing on a particular 
property/method to simplify the example. Here's the situation:

In my program, I have a class called Attack. With the following layout 
(simplified for example)

    class Attack : public Action
    {
    public:
        virtual int CalculateDamage(const std::vector<BattleCharacter*>& users, 
BattleCharacter* target, const std::vector<Actions::ActionTarget>& targets, 
BattleField *field);
    protected:
        bool Hit;
    }

I exposed Attack to python, making it overridable, as follows:

    struct AttackWrapper : Game::Battles::Actions::Attack
    {
        int AttackWrapper::CalculateDamage(const 
std::vector<Game::Battles::BattleCharacter*>& users, 
Game::Battles::BattleCharacter* target, const 
std::vector<Actions::ActionTarget>& targets, Game::Battles::BattleField *field)
        {
               return call_method<int>(self, "CalculateDamage", users, 
ptr(target), targets, ptr(field));
        }
        int AttackWrapper::CalculateDamageDefault(const 
std::vector<Game::Battles::BattleCharacter*>& users, 
Game::Battles::BattleCharacter* target, const 
std::vector<Actions::ActionTarget>& targets, Game::Battles::BattleField *field)
        {
            return this->Attack::CalculateDamage(users, target, Targets, field);
        }
    }

And the python exposing is done as follows:

    class_<Attack, AttackWrapper, boost::shared_ptr<Attack>, bases<Action> 
>("Attack")
        .def("CalculateDamage", &AttackWrapper::CalculateDamageDefault);


I initially thought everything was working fine, as I can override the 
`CalculateDamage` method within python and have it work correctly. However, 
When I want to use the normal `Attack->CalculateDamage`, the following happens:

I only call `CalculateDamage` when Hit is true, and I can confirm via break 
point when I hit this line, Hit is true:

    return call_method<int>(self, "CalculateDamage", users, ptr(target), 
targets, ptr(field));

Now, because I haven't overriden `CalculateDamage` in Python for this attack 
instance, it ends up resolving to `AttackWrapper::CalculateDamageDefault`. But 
by the time I enter AttackWrapper::CalculateDamageDefault, Hit is no longer 
true. That is, when I break on this line:

    return this->Attack::CalculateDamage(users, target, Targets, field);

Hit is false. So somewhere between 

    return call_method<int>(self, "CalculateDamage", users, ptr(target), 
targets, ptr(field));

resolving to 

    return this->Attack::CalculateDamage(users, target, Targets, field);

my property's value is lost. I have no idea what could be causing this. Has 
anyone encountered something like this before?

The attacks I'm using for testing are defined as follows:

class ScriptedAttack(Attack):
    def __init__(self, Type, ID, Name, Flags, Targs = ActionTargets.Any, 
AllowTargettingOverride = False, Power = 0, MPCost = 0, SPCost = 0, Accuracy = 
0.9, CritChance = 0.1, DefineOwnUse = False, EleWeights = None, 
StatusEffectChances = None):
        if (EleWeights == None and StatusEffectChances == None):
            Attack.__init__(self, Type, ID, Name, Flags, Targs, 
AllowTargettingOVerride, Power, MPCost, SPCost, Accuracy, CritChance, 
DefineOwnUse)
        else:
            Elemap = ElementMap()
            if (EleWeights != None):
                for Element, Weight in EleWeights.iteritems():
                    Elemap[Element] = Weight
            SEChances = SEChanceMap()
            if (StatusEffectChances != None):
                for StatusEffect, Chance in StatusEffectChances.iteritems():
                    SEChances[StatusEffect] = Chance
            Attack.__init__(self, Type, ID, Name, Flags, Elemap, Targs, 
AllowTargettingOverride, Power, MPCost, SPCost, Accuracy, CritChance, 
DefineOwnUse, SEChances)
    def Clone(self):
        return copy.deepcopy(self)

Fire = ScriptedAttack(ActionType.MagicAction, PrimaryEngine.GetUID(), "Fire", 
AttackFlags.Projectile | AttackFlags.Elemental, ActionTargets.Any, True, 32, 
14, 0, 1.0, 0.1, False, {Elements.Fire: 1.0})
Fira = ScriptedAttack(ActionType.MagicAction, PrimaryEngine.GetUID(), "Fira", 
AttackFlags.Projectile | AttackFlags.Elemental, ActionTargets.Any, True, 63, 
35, 0, 1.0, 0.1, False, {Elements.Fire: 1.0})

ActLibrary.AddAttack(Fire)
ActLibrary.AddAttack(Fira)

ActLibrary.AddAttack takes in a boost::shared_ptr<Attack> and stores it into a 
hash table. I lookup the attack and use the instance stored there to do 
CalculateDamage.

It almost seems like the object is being copied, but I have no idea why that'd 
be so.

Any help would be appreciated.

Thanks
                                          
_______________________________________________
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Reply via email to