It is currently 25 Apr 2024, 09:28
   
Text Size

Understanding functions without examples

Moderator: CCGHQ Admins

Understanding functions without examples

Postby thefiremind » 02 Jul 2012, 23:29

I coded Ordruun Commando. Nothing difficult by using a trick: each activation increments an ObjectDC register, then when the creature is about to take damage, the damage is reduced by the amount in the register, and the amount in the register is reduced by the amount of damage (of course none of the 2 values goes under zero, I'm checking which one is greater before doing the math). All goes well, but I think that the AI doesn't understand what the ability does: I tested the card against Chandra (perfect for things like this!) and she threw burn spells at the creature even when I had plenties of white mana to spend.

So, I looked at the available functions and saw an interesting one that can be called for an object:
PreventNextDamage
The problem is, we have no examples of that. So how can we understand what parameters are required?

These are the tests I made before writing this topic:
  • Object():PreventNextDamage()
    SCRIPT_LOG.TXT says "parameter mismatch or too few parameters [expected bzS32]".
  • Object():PreventNextDamage(1)
    SCRIPT_LOG.TXT says "parameter mismatch or too few parameters [expected bzS32]".
  • Object():PreventNextDamage(1, 1)
    SCRIPT_LOG.TXT says nothing, but the game crashes when I attack with the creature (probably when the AI starts evaluating the card). This would suggest that 2 parameters is the right amount (I think), but one (or both) of them shouldn't be set to 1.
  • Object():PreventNextDamage(1, Object()), and also Object():PreventNextDamage(Object(), 1)
    Again SCRIPT_LOG.TXT says "parameter mismatch or too few parameters [expected bzS32]". So the parameters shouldn't be pointers (I think). But then, why did the game crash with (1, 1)?
I also made the hypothesis that PreventNextDamage should be called in a CONTINUOUS_ACTION since it should be the only way to tell the game when the prevention expires (end of turn in this case), but if it's like DotP2012, the game doesn't get crazy if I use a "one-shot" thing in a continuous action, it simply tries to apply the effect each time state-based effects are checked (try with regeneration and you'll end up with dozens of regeneration shields).

I'm far from being a LUA expert, I know just what I learned by modding DotP. So I ask to those who know better: is there a way to understand the functions for which we don't have any example, without trial and error? Or at least, is there a way to minimize the trial and error?
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Understanding functions without examples

Postby kevlahnota » 03 Jul 2012, 00:07

hi, can you try something like:
Object():PreventNextDamage( amount, true/false )

like Object():PreventNextDamage( 1, true )
User avatar
kevlahnota
Programmer
 
Posts: 825
Joined: 19 Jul 2010, 17:45
Location: Philippines
Has thanked: 14 times
Been thanked: 264 times

Re: Understanding functions without examples

Postby MisterBenn » 03 Jul 2012, 04:08

... could both parameters be objects? i.e. you specifiy both the provider and the beneficiary of the effect? The provider is maybe a bit redundant as it will usually be the card that carries the piece of code... then again there are a few functions like that.

Oh and I know all about trial and error! I'd never used Lua before and have had to learn the rules of the game, the terms etc as I went. I screwed around in 2010 without much success, I made 4 decks for 2012 but they all had issues and were too rough to post... I am really trying to get my act together and put something up this time around! At least the turnaround on packing the wad files is MUCH better for me this time around, I am using Gibbed's tools this time... I previously used the java wad file packer and spent about 40% of my time browsing for directories!
MisterBenn
 
Posts: 97
Joined: 19 Mar 2011, 16:19
Has thanked: 24 times
Been thanked: 11 times

Re: Understanding functions without examples

Postby thefiremind » 03 Jul 2012, 09:24

kevlahnota wrote:hi, can you try something like:
Object():PreventNextDamage( amount, true/false )

like Object():PreventNextDamage( 1, true )
I think that in LUA, true is the same as 1 and false is the same as 0, so I don't think it would change something.

MisterBenn wrote:... could both parameters be objects?
With (Object(), Object()) I get the usual error in SCRIPT_LOG.

EDIT: Hey, something new!
With (1, 0) something happens when activating the ability. The "protection from white" badge appears on the card with a "1" on top. It seems to indicate that it's ready to prevent the next damage from a white source... since COLOUR_WHITE = 1, maybe the first parameter is the colour of the source to prevent. If it's so, we discovered something great but it's not useful for Ordruun Commando, which should be shielded from any damage. I wonder what's the purpose of the second parameter, which can't be 1...

EDIT 2: No, I wasn't right...
With (0, 0) the same badge appears, but without the "1" on top. So the first parameter is the amount of damage to prevent: with 0 it actually prevents nothing. I have to try with 1 again. Maybe that badge is used just because prevention is an almost exclusive white mechanic.

EDIT 3: Now I'm puzzled... I tried with (1, 0) again, but this time I activated the ability while Chandra had a burn spell on the stack... and the game crashed. :shock:

EDIT 4: I tried to add a third parameter. And that added even more doubts: if the third parameter is another number, it seems it has no effect, and the game crashes randomly; if the third parameter is a pointer, the game doesn't crash, but no matter what's the combination of the first two parameters, the "1" on top of the badge doesn't appear, and the prevention doesn't take place (at least against red spells, if the colour is important).
I'm starting to think that PreventNextDamage is a function that the developers didn't complete properly.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Understanding functions without examples

Postby sadlyblue » 03 Jul 2012, 17:23

I have no idea how if it works.
But, the first way you tried to code it, did you use the immunity="1"? I've seen it in Dawn Elemental.
sadlyblue
 
Posts: 175
Joined: 06 Feb 2012, 13:18
Has thanked: 18 times
Been thanked: 16 times

Re: Understanding functions without examples

Postby thefiremind » 03 Jul 2012, 17:59

sadlyblue wrote:But, the first way you tried to code it, did you use the immunity="1"? I've seen it in Dawn Elemental.
I still have to try. I didn't use it because it's not total immunity as in Dawn Elemental, and DotP2013 isn't using immunity for regeneration anymore. But trying won't hurt.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Understanding functions without examples

Postby nabeshin » 14 Jul 2012, 21:56

Hi all, 1) try set filter as in protection
2) also try combo sourse/ amount - target/amount
Object():Myfunc(1,1) for translator == Myfunc(Object(),1,1,nil,nil,nil,...), you get error if coders set error handler for all parametrs
User avatar
nabeshin
 
Posts: 207
Joined: 27 Jun 2011, 20:07
Has thanked: 5 times
Been thanked: 31 times

Re: Understanding functions without examples

Postby nabeshin » 15 Jul 2012, 19:31

From old dotp.
1) You need cola
2) Read carefully
Code: Select all
function _PreventDamage( pAmount, pCombat_only )
   local combat_only
   if (pCombat_only) then
      combat_only = 1
   else
      combat_only = 0
   end
   
   Object():GetFilter():Clear()
   if (SubjectType() == SUBJECT_OBJECT) then
      Subject():PreventDamage( pAmount, combat_only )
   else
      Player():PreventDamage( pAmount, combat_only )
   end
end

function _PreventNextDamage( pAmount, pCombat_only )
   local combat_only
   if (pCombat_only) then
      combat_only = 1
   else
      combat_only = 0
   end
   
   Object():GetFilter():Clear()
   if (SubjectType() == SUBJECT_OBJECT) then
      Subject():PreventNextDamage( pAmount, combat_only, Effect() )
   else
      Player():PreventNextDamage( pAmount, combat_only, Effect() )
   end
end

function _PreventDamageF( pAmount, pCombat_only )
   local combat_only
   if (pCombat_only) then
      combat_only = 1
   else
      combat_only = 0
   end
   
   if (SubjectType() == SUBJECT_OBJECT) then
      Subject():PreventDamage( pAmount, combat_only )
   else
      Player():PreventDamage( pAmount, combat_only )
   end
end

function _PreventNextDamageF( pAmount, pCombat_only )
   local combat_only
   if (pCombat_only) then
      combat_only = 1
   else
      combat_only = 0
   end
   
   if (SubjectType() == SUBJECT_OBJECT) then
      Subject():PreventNextDamage( pAmount, combat_only, Effect() )
   else
      Player():PreventNextDamage( pAmount, combat_only, Effect() )
   end
end

-- Continous effects to prevent all amounts of damage. Either combat or all,
-- with or without a predefined filter

function PreventAllCombatDamage()
   _PreventDamage( 0, true )
end

function PreventAllCombatDamageF()
   _PreventDamageF( 0, true )
end

function PreventAllDamage()
   _PreventDamage( 0, false )
end

function PreventAllDamageToSelf()
   Object():GetFilter():Clear()
   Object():PreventDamage( 0, 0 )
end

function PreventAllDamageF()
   _PreventDamageF( 0, false )
end

-- Continous effects to prevent given amount of damage. Either combat or all,
-- with or without a predefined filter

function PreventCombatDamage( pAmount )
   _PreventDamage( pAmount, true )
end

function PreventCombatDamageF( pAmount )
   _PreventDamageF( pAmount, true )
end

function PreventDamage( pAmount )
   _PreventDamage( pAmount, false )
end

function PreventDamageF( pAmount )
   _PreventDamageF( pAmount, false )
end

-- Shield-type effects to prevent given next amount of damage. Either combat or all,
-- with or without a predefined filter

function PreventNextCombatDamage( pAmount )
   _PreventNextDamage( pAmount, true )
end

function PreventNextCombatDamageF( pAmount )
   _PreventNextDamageF( pAmount, true )
end

function PreventNextDamage( pAmount )
   _PreventNextDamage( pAmount, false )
end

function PreventNextDamageF( pAmount )
   _PreventNextDamageF( pAmount, false )
end
User avatar
nabeshin
 
Posts: 207
Joined: 27 Jun 2011, 20:07
Has thanked: 5 times
Been thanked: 31 times

Re: Understanding functions without examples

Postby nabeshin » 15 Jul 2012, 19:33

kevlahnota wrote:hi, can you try something like:
Object():PreventNextDamage( amount, true/false )

like Object():PreventNextDamage( 1, true )
:supz:
User avatar
nabeshin
 
Posts: 207
Joined: 27 Jun 2011, 20:07
Has thanked: 5 times
Been thanked: 31 times

Re: Understanding functions without examples

Postby thefiremind » 15 Jul 2012, 20:31

If I write this:
Code: Select all
    <CONTINUOUS_ACTION>
    Object():GetFilter():Clear()
    Object():PreventDamage( 1, 0 )
    </CONTINUOUS_ACTION>
    <DURATION simple_duration="UntilEOT" />
and I activate it once, it really prevents 1 damage, but it's not "one-shot": it always prevents 1 damage for each source until end of turn.

If I write this:
Code: Select all
    <CONTINUOUS_ACTION>
    Object():GetFilter():Clear()
    Object():PreventNextDamage( 1, 0, Object() )
    </CONTINUOUS_ACTION>
    <DURATION simple_duration="UntilEOT" />
the badge appears on the creature but it doesn't prevent anything, ever. So what I'm doing wrong? "Effect()" doesn't exist anymore so I can't follow the DotP2010 usage.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Understanding functions without examples

Postby codeALPHA » 15 Jul 2012, 22:02

An idea if you want to try out.
Maybe the second Object() in the PreventNextDamage() is the damage source, so the code as is prevents the next damage that an object inflicts to itself. Maybe you need to put a different object in there.
codeALPHA
 
Posts: 16
Joined: 05 Aug 2010, 06:55
Has thanked: 0 time
Been thanked: 1 time

Re: Understanding functions without examples

Postby thefiremind » 15 Jul 2012, 22:08

codeALPHA wrote:An idea if you want to try out.
Maybe the second Object() in the PreventNextDamage() is the damage source, so the code as is prevents the next damage that an object inflicts to itself. Maybe you need to put a different object in there.
It's an activated ability, not a triggered one, so I don't have any damage source to point to. I'm sure I need something else inside that parameter, but I'm starting to think that PreventNextDamage is a leftover from DotP2010 and can't be used anymore without a pointer to the effect itself.
Thanks anyway for trying to suggest something. :)

EDIT: I also tried with
Code: Select all
    <CONTINUOUS_ACTION>
    Object():GetFilter():Clear()
    Object():PreventNextDamage( 1, 0, rawget(_G, lua_effect_index) )
    </CONTINUOUS_ACTION>
where rawget(_G, lua_effect_index) is the definition of Effect() in DotP2010, but it makes the game crash exactly as if I used nil (that probably means that rawget(_G, lua_effect_index) returns nil in DotP2013).
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 721 times

Re: Understanding functions without examples

Postby pcastellazzi » 16 Jul 2012, 15:30

In lua there is no argument instrospection. My guess is PreventNextDamage is expecting a key in a table as second argument. Probably a reference to a constant in the engine itself. Also in 2013 there is a Damage object, this can also be what is expecting instead of a number.
The lights then came up and the crowd erupted in applause, because that's what the crowd does after it watches destruction on a large screen.
— Ben Kuchera, Mordern Warfare 3 review.
User avatar
pcastellazzi
 
Posts: 184
Joined: 25 Apr 2012, 00:40
Location: Montevideo, Uruguay
Has thanked: 11 times
Been thanked: 30 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 27 guests


Who is online

In total there are 27 users online :: 0 registered, 0 hidden and 27 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 27 guests

Login Form