Aller au contenu

Photo

mod intercepting EVENT_TYPE_DYING clashes with Encased Golems


  • Veuillez vous connecter pour répondre
18 réponses à ce sujet

#1
Rolenka

Rolenka
  • Members
  • 2 257 messages
Or as they are known by the toolset, orz540cr_golem_encased.

Here's the mod: http://social.biowar...m/project/1615/

When the golem dies, it's supposed to wake up the next golem in the line. But to do this, when it dies, it doesn't send the event to creature_core like most creatures do. It sends it to orz540cr_golem_encased, which contains a specific set of instructions for the event, and then sends it onward to creature_core.

My mod is getting in the way of orz540cr_golem_encased. The next golem doesn't wake up.

The only way I can think of to fix it is to add a check for this creature, then send it to orz540cr_golem_encased if true. I can't seem to find a function that does that, however. I even tried just searching for "getcreature" on the builder wiki (it seemed a likely start to that function, if it exists).

Even if I went that route though, my mod would continue to break other creatures that function this way. Is there an alternative?

#2
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages
What about GetObjectByTag()? Although, I'm not sure how far that searches for objects in DA (perhaps too far if anything, but it's probably OK and there are shape filters).

Modifié par FollowTheGourd, 18 janvier 2010 - 06:48 .


#3
anakin5

anakin5
  • Members
  • 258 messages
You cannot override events that are handle by creature_core without calling HandleEvent somewhere. Many creatures in the single player campaign have their own event script. If you override EVENT_TYPE_DYING, you break all creatures of the game who have a special behavior on this event, like the golems.

The solution is to call HandleEvent somewhere in your script.

The part of code you are looking for is this :


void main()
{
  event ev = GetCurrentEvent();
  int nEventType = GetEventType(ev);

  /* Call the default handler before. */
  HandleEvent(ev);

  switch (nEventType)
  {
    case EVENT_TYPE_DYING:
    {
      object oKiller = GetEventObject(ev, 0);

      /* We do the job that is not done in the default handler.
        This job is rewarding the group for enemies killed by a
        non-party npc.
      */
      object oPL = GetPartyLeader();

      if ((IsObjectValid(oKiller) == TRUE)
      && (IsPartyMember(oKiller) != TRUE)
      && (IsObjectHostile(OBJECT_SELF, oPL) == TRUE))
      {
        RewardXPParty(0, XP_TYPE_COMBAT, OBJECT_SELF, oPL);

        if (GetCombatantType(OBJECT_SELF) != CREATURE_TYPE_NON_COMBATANT)
        {
          HandleEvent(ev, R"sys_treasure.ncs");
        }
      }

      break;
    }
  }
}

Modifié par anakin5, 18 janvier 2010 - 05:09 .


#4
thebigMuh

thebigMuh
  • Members
  • 98 messages
One of two things will happen with this mod when simply calling HandleEvent():



1.) HandleEvent manages to call orz540cr_golem_encased.ncs, when one golem dies the next one rises. If the killing blow was from an NPC, XP are awarded once, if it was from a PC, you get double experience, since orz540cr_golem_encased calls the creature_core script, which also awards XP.



2.) HandleEvent only calls creature_core.ncs, in which case the only effect is that a party kill rewards XP twice.



The only way I can think of that a.) rewards XP on non-party-kills b.) requires no special case handling and c.) doesn't break with other mods, is to override creature_core.ncs itself, which is more than ugly (and can't be done from a module, since the core scripts are loaded before the addins directories are checked).



Your safest bet right now is to add special case handling to your script for the encased golems.



Ciao, muh!

#5
Craig Graff

Craig Graff
  • Members
  • 608 messages

thebigMuh wrote...
Your safest bet right now is to add special case handling to your script for the encased golems.!

As anakin5 noted, that isn't "safe", simply because there are a great many creatures with custom scripts, quite a few of which may break the game in subtle or not-so-subtle ways if this event is overridden.

#6
Rolenka

Rolenka
  • Members
  • 2 257 messages

thebigMuh wrote...

One of two things will happen with this mod when simply calling HandleEvent():

1.) HandleEvent manages to call orz540cr_golem_encased.ncs, when one golem dies the next one rises. If the killing blow was from an NPC, XP are awarded once, if it was from a PC, you get double experience, since orz540cr_golem_encased calls the creature_core script, which also awards XP.

2.) HandleEvent only calls creature_core.ncs, in which case the only effect is that a party kill rewards XP twice.


A simple way to prevent double xp would be to only run my code if oKiller is not a party member.

I didn't realize you could use HandleEvent() without specifying a resource, making it find the default. I think that's what I needed. Thanks. Posted Image

Your second scenario I'll have to test once I get to that point in the game again. I would hope it would send it to the creature script first, but who knows if the interception messes with that.

As a side note, I didn't realize you could open other people's packaged modules...

#7
thebigMuh

thebigMuh
  • Members
  • 98 messages
The .dazip is a normal zip file, and the .erf files in it can be opened in the toolset, so yep we can all inspect your code ^^

Maybe there is a way to encrypt the erf files, similar to how the DLC content is locked, but that would kind of stomp all over the community aspect of modding.

Will be interesting to see which script is called by HandleEvent.

Ciao, muh!

Modifié par thebigMuh, 18 janvier 2010 - 05:13 .


#8
anakin5

anakin5
  • Members
  • 258 messages
Read the code, and you will see there is a (IsPartyMember(oKiller) != TRUE).



Xp will not be awared twice, no creature can pass the IF statement in the creature_core and in my file because no creature is at the same time, a party member and not a party member.

#9
thebigMuh

thebigMuh
  • Members
  • 98 messages
Oh yes - well, don't cook and code :)



Ciao, muh!

#10
Rolenka

Rolenka
  • Members
  • 2 257 messages

thebigMuh wrote...

The .dazip is a normal zip file, and the .erf files in it can be opened in the toolset, so yep we can all inspect your code ^^

Maybe there is a way to encrypt the erf files, similar to how the DLC content is locked, but that would kind of stomp all over the community aspect of modding.

Will be interesting to see which script is called by HandleEvent.

Ciao, muh!


Well, you could just not include the .nss file in your package. I'm not sure why you would want to keep it a secret though.

Craig Graff wrote...

thebigMuh wrote...
Your safest bet right now is to add special case handling to your script for the encased golems.!

As
anakin5 noted, that isn't "safe", simply because there are a great many
creatures with custom scripts, quite a few of which may break the game
in subtle or not-so-subtle ways if this event is overridden.


Even if I wanted to do that, I can't find a function to check for a specific creature... any ideas for if I need such a thing in the future? (or for people who've found this thread via search?)

#11
Rolenka

Rolenka
  • Members
  • 2 257 messages
Oh, and anakin5, I take it you put in GetPartyLeader() for the floaty XP numbers. I hadn't gotten around to finding which function returned the currently controlled character, thanks.

#12
thebigMuh

thebigMuh
  • Members
  • 98 messages

I can't find a function to check for a specific creature


Does

string sObjectTag = GetTag(<whatever object>);

do what you want?

Ciao, muh!

Modifié par thebigMuh, 18 janvier 2010 - 07:59 .


#13
anakin5

anakin5
  • Members
  • 258 messages
GetMainControlled()

#14
Magic

Magic
  • Members
  • 187 messages
anakin5 used GetPartyLeader() to check if the victim is hostile towards the player party. If you need the currently controlled character, this is GetMainControlled().

#15
Rolenka

Rolenka
  • Members
  • 2 257 messages
I guess I didn't read it that closely. Yeah, I deliberately did not put in a hostile check. The goal was to remove the pressure to kill everything yourself, and with the hostile check there's still the pressure to kill the blue guys with AOEs. Though at the time I wasn't sure if they had an experience value. I'll have to update the mod's description...

#16
anakin5

anakin5
  • Members
  • 258 messages
Gaining experience for killing allies ?

#17
FollowTheGourd

FollowTheGourd
  • Members
  • 572 messages

anakin5 wrote...

Gaining experience for killing allies ?

Gotta make up for them stealing your kill XP somehow... :P

#18
Magic

Magic
  • Members
  • 187 messages

Rolenka wrote...

and with the hostile check there's still the pressure to kill the blue guys with AOEs.

Why is there this pressure?

By the way, that's a nice solution you two found, redirecting the event handling and falling back to the default scripts. :)

#19
Rolenka

Rolenka
  • Members
  • 2 257 messages
Hah thanks, it was all Dhuester's work. He just wrote a guide on how it's done.



My brain is wired for this stuff, I just haven't done it since high school.



Anyway for anyone else with this problem, HandleEvent(ev); fixed the bug.