Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
Page 1 of 3 1 2 3
#549050 30/08/14 06:24 PM
Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
What if the enemies could respawn? What if encounters could be repeated, and massacres of entire cities undone with time?

This thread aims to do just that.

Right now I just have a very basic Story script in place to respawn all characters after some amount of time has passed-

Code
IF
CharacterDied(_Character)
AND
Time(_,_,_TH)
THEN
DB_DeadCharacters(_Character, _TH);

IF
CharacterEnteredCombat(_Character,_)
AND
_Character.isPlayer()
THEN
ProcResurrectCharacters();

PROC
ProcResurrectCharacters()
AND
Time(_,_,_TH)
AND
DB_DeadCharacters(_Character, _deadTime)
AND
IntegerSubtract(_TH, _deadTime, _delta)
AND
_delta >= 1
THEN
CharacterResurrect(_Character);
NOT DB_DeadCharacters(_Character, _deadTime);
ProcResurrectCharacters();



It kind of works, respawning (or more accurately, resurrecting) them after at least 1-2 min. has passed since their death when the players enter a new combat, but there are some issues.

#1 issue: The resurrected enemies do not give exp when defeated again (they probably don't drop more items either, but I haven't tested that much).

I have only tested it a little bit to see that it could possibly work. I'm considering having the enemies spawn a copy of themselves at their location instead of being resurrected after the time has passed.

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
Originally Posted by Rhidian
#1 issue: The resurrected enemies do not give exp when defeated again (they probably don't drop more items either, but I haven't tested that much).


If you call CharacterResurrect(), the IsResurrected flag of the character will be set to TRUE, so it will yield no XP when the char dies again. (The flag cannot be reset from scripts AFAIK)

Originally Posted by Rhidian
I have only tested it a little bit to see that it could possibly work. I'm considering having the enemies spawn a copy of themselves at their location instead of being resurrected after the time has passed.


How do you clone characters though? I haven't found any functions so far that allow creating new character objects. frown

Another possible workaround would be giving XP manually:
Code
IF
CharacterDied(_Character)
AND
DB_DeadCharacters(_Character, _)
AND
GetCharacterExperienceSomehow(_Character, _XP)
THEN
PartyAddExperience(_XP)


Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
Creating characters can be done via Character scripts (Boreas' elemental summons are set to create two additional elemental rock enemies for example), which is kind of what I was thinking of when I said that. I thought there would be a story equivalent as well, but there doesn't appear to be one so that's probably out.

Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
Updated script with (severely unbalanced) experience gain upon killing enemies again-


INIT Section-
Code

DB_ExperienceTable(1, 100);
DB_ExperienceTable(2, 300);
DB_ExperienceTable(3, 500);
DB_ExperienceTable(4, 1000);
DB_ExperienceTable(5, 1500);
DB_ExperienceTable(6, 2000);
DB_ExperienceTable(7, 2700);
DB_ExperienceTable(8, 3400);
DB_ExperienceTable(9, 4200);
DB_ExperienceTable(10, 5000);
DB_ExperienceTable(11, 6000);
DB_ExperienceTable(12, 7000);
DB_ExperienceTable(13, 8000);
DB_ExperienceTable(14, 10000);
DB_ExperienceTable(15, 11000);
DB_ExperienceTable(16, 12000);
DB_ExperienceTable(17, 13000);
DB_ExperienceTable(18, 14000);
DB_ExperienceTable(19, 15000);
DB_ExperienceTable(20, 20000);



KB Section-
Code
IF
CharacterDied(_Character)
AND
Time(_,_,_TH)
THEN
DB_DeadCharacters(_Character, _TH);

IF
CharacterEnteredCombat(_Character,_)
AND
_Character.isPlayer()
THEN
ProcResurrectCharacters();

PROC
ProcResurrectCharacters()
AND
Time(_,_,_TH)
AND
DB_DeadCharacters(_Character, _deadTime)
AND
IntegerSubtract(_TH, _deadTime, _delta)
AND
_delta >= 1
THEN
CharacterResurrect(_Character);
NOT DB_DeadCharacters(_Character, _deadTime);
ProcResurrectCharacters();


IF
CharacterDied(_Char)
AND
DB_DeathList(_Char)
AND
CharacterGetLevel(_Char, _level)
AND
DB_ExperienceTable(_level, _exp)
THEN
PartyAddExperience(_exp);
NOT DB_DeathList(_Char);

IF
CharacterDied(_Char)
THEN
DB_DeathList(_Char);



There's a little bit of a delay between killing enemies and gaining exp, but it works. Does anyone know what exactly goes into the experience points gained upon killing an enemy? I just made up random experience point values for this Proof-of-Concept test, and I would like to make them more realistic.

A bit more testing, and I discovered a few things-
If enemies die in one map (Cyseal) and combat is started in another (Homestead), then the characters are properly resurrected in the map they died on.

If an NPC starts off friendly and becomes hostile before death (city guard for example), then upon resurrection they will be friendly again.

----
Beyond the Experience point adjustment that needs to be made, what time limit would be appropriate between respawns? Right now it's just 1 minute (if I'm reading the function correctly) for testing purposes.

Joined: Aug 2014
P
stranger
Offline
stranger
P
Joined: Aug 2014
In my opinion, instead of using timers for triggering the respawn event, use the CharacterLeftRegion! laugh

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
AFAIK CharacterLeftRegion triggers don't trigger if you leave the map via unconventional means (eg. rift travel)

Also it'd require seeding the map with hundreds of region triggers for each encounter

Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
Originally Posted by Norbyte
AFAIK CharacterLeftRegion triggers don't trigger if you leave the map via unconventional means (eg. rift travel)

Also it'd require seeding the map with hundreds of region triggers for each encounter


CharacterEnteredRegion(_Char, _) should work just as well, and is more elegant than having an arbitrary number of time between respawns. It doesn't really matter when the event gets called either, so long as it does get called at some point (after the party has had a chance to move away from their last encounter).

I could still use some suggestions on what to do about the experience though. I don't think there is a way for me to see what their 'Gain' value is for an exp calculation (like what they normally give) to work properly.

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
I've just realized that the CharacterResurrect() solution isn't the best one either.
eg. If you kite orcs into Cyseal they'll resurrect in Cyseal, which is rather problematic.

Also, will this resurrect summons? (they're characters too!)

Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
I just checked a summon (Summoned Spider), and it didn't respawn. My guess is that only Global characters are able to be resurrected, especially since they can be resurrected even if they are on other maps. Of course, as it is now Player characters will respawn. I'll probably include a CharacterIsInParty check to stop that from occurring.

I don't think there's an easy way to solve the enemies-in-town problem directly. I might be able to do an indirect solution though. What if the respawning enemies was a toggle-able function? There could be two custom-skills; one to turn Respawning enemies on (where stuff that dies will respawn), and the other to turn it off (stuff that dies won't respawn). I think that I could use the CharacterUsedSkill to check/modify a Database and use that Database as a boolean for whether something should be added to the Respawning enemy list upon death.

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
Quote
My guess is that only Global characters are able to be resurrected

Most enemies are non-global generic characters however, so they won't respawn if this is true.

Quote
I don't think there's an easy way to solve the enemies-in-town problem directly. I might be able to do an indirect solution though. What if the respawning enemies was a toggle-able function? There could be two custom-skills; one to turn Respawning enemies on (where stuff that dies will respawn), and the other to turn it off (stuff that dies won't respawn). I think that I could use the CharacterUsedSkill to check/modify a Database and use that Database as a boolean for whether something should be added to the Respawning enemy list upon death.


Thats a huge hack if I've ever seen one smile

Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
What I really meant to say is that characters can resurrect if they're located within the Character panel of the Editor (ie placed within the game world). Players, enemy encounters, etc are all unique 'Characters'; changing Player 1 has no effect on Player 2. Summons on the other hand are just instances of a RootTemplate and have no specific entry in the Character panel, which is why many of them can be summoned at once.

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
No, summons are still characters internally despite not existing at world creation time.
If you place 3 skeletons for an encounter they are still three instances of the same template, just instantiated sooner than summons and referenceable via names (unlike summons).
Other than that, summons can still trigger events, and the CharacterXyz() functions handle them just fine.
The only difference is that their lifetime is tied to a cooldown. I dont see any reason why they wouldn't be characters.

Last edited by Norbyte; 31/08/14 06:01 PM.
Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
When I say the Character panel, I am referring to this:

[Linked Image]


In that picture, you can see that there are three different instances of the Pig RootTemplate Animals_Pig_A, each with different names (Animals_Pig_A_000, Animals_Pig_A_001, Animals_Pig_A_002). If a spell summoned another instance of Animals_Pig_A, that summon wouldn't be resurrectable even though the three characters in the Character panel above can. They're all characters, but summons aren't in the Character panel.

Joined: Jul 2014
journeyman
Offline
journeyman
Joined: Jul 2014
have you experimented with spawncharacter(template)?
Maybe if characterdied then getcharactertemplate and spawn that one. Don't know if thats possible though
also, I broke my own testing mod a while ago and it respawned the dead enemies when I re-entered the level somehow. I thought it had something to do with the AAA-FirstGoal, or my mod just bugged out.

Good luck m8, great idea

Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
You cannot resurrect summons by their CHARACTER_xyz name, because such name does not exist at compile time, that is true.

However consider the following code:
Code
IF 
    CharacterDied(_Summon)
THEN
    CharacterResurrect(_Summon)


This will resurrect summons too.


Originally Posted by FromHolland
have you experimented with spawncharacter(template)?
Maybe if characterdied then getcharactertemplate and spawn that one. Don't know if thats possible though


SpawnCharacter is a charscript/itemscript-only function though, you cannot use that in story scripts.

Joined: Jul 2014
journeyman
Offline
journeyman
Joined: Jul 2014
Originally Posted by Norbyte
You cannot resurrect summons by their CHARACTER_xyz name, because such name does not exist at compile time, that is true.

However consider the following code:
Code
IF 
    CharacterDied(_Summon)
THEN
    CharacterResurrect(_Summon)


This will resurrect summons too.


Originally Posted by FromHolland
have you experimented with spawncharacter(template)?
Maybe if characterdied then getcharactertemplate and spawn that one. Don't know if thats possible though


SpawnCharacter is a charscript/itemscript-only function though, you cannot use that in story scripts.
Hey Norbyte! other topic wink hows the gr2 animation export going:)? on-topic: I'm pretty sure you can as I've tested that for my own mod, using story script (the spawncharactertemplate) not sure about the getting templates through story scripting though... Im gonna double check to make sure
edit: yeh you're right, "CharacterCreateAtTrigger" is what I was looking for;)
edit2: well in theory someone can do a complicated charscript with spawncharacter and just add that to the default player charscript

Last edited by FromHolland; 31/08/14 09:15 PM.
Joined: Apr 2013
N
addict
Offline
addict
N
Joined: Apr 2013
Originally Posted by FromHolland
Hey Norbyte! other topic wink hows the gr2 animation export going:)?


Mesh / skeleton import is working fine (in Blender), animations are still somewhat broken but are progressing nicely smile
(.gr2 uses 19 different animation storage formats and not all are understood / some are weird)

Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
Originally Posted by Norbyte
You cannot resurrect summons by their CHARACTER_xyz name, because such name does not exist at compile time, that is true.

However consider the following code:
Code
IF 
    CharacterDied(_Summon)
THEN
    CharacterResurrect(_Summon)


This will resurrect summons too.


So I just tried this piece of code:
Code
IF
CharacterDied(_Char)
THEN
CharacterResurrect(_Char);


And got this result:

[Linked Image]


Roderick resurrected immediately after being killed, but neither of the two spiders summoned were resurrected even after their timer ran out.

I tested whether them dying mid-summon changed anything, and they still remained dead. For whatever reason, summons cannot be resurrected. Is there any proof to the contrary?

Edit:
Actually, I think it might just be that summons never trigger the CharacterDied event. In the combat log you can see that Roderick gets a line saying he turns into dust when he dies (most characters get some sort of line upon death). The summons, however, get no such combat line upon death even if they are killed mid-summon.

Last edited by Rhidian; 31/08/14 10:13 PM.
Joined: Jul 2014
journeyman
Offline
journeyman
Joined: Jul 2014
Originally Posted by Norbyte
Originally Posted by FromHolland
Hey Norbyte! other topic wink hows the gr2 animation export going:)?


Mesh / skeleton import is working fine (in Blender), animations are still somewhat broken but are progressing nicely smile
(.gr2 uses 19 different animation storage formats and not all are understood / some are weird)
magic, great news smile howd you do that?, as the only thing I can think of is the 3dscreenprint and those cant "capture" the skeleton(but im no coder) Good luck man, eagerly awaiting your release!
On-topic again: If there is a way to give a character a script (for all enemies) you can use the spawncharacter on the died character( CharacterGetTemplate(_Me) ) etc.
I do not know what a scriptframe is for CharacterSetScriptframe(CHARACTER _Character,STRING _Scriptframe), someone can shed some light on this?

Last edited by FromHolland; 31/08/14 10:12 PM.
Joined: Jul 2014
R
Rhidian Offline OP
addict
OP Offline
addict
R
Joined: Jul 2014
Using a skill to toggle respawn was a success smile

I made two skills and put in this code into the story:
Code
IF
CharacterUsedSkill(_Char, "Shout_RespawnEnable", _)
AND
DB_RespawnEnabled(0)
THEN
NOT DB_RespawnEnabled(0);
DB_RespawnEnabled(1);

IF
CharacterUsedSkill(_Char, "Shout_RespawnDisable", _)
AND
DB_RespawnEnabled(1)
THEN
NOT DB_RespawnEnabled(1);
DB_RespawnEnabled(0);

IF
CharacterDied(_Char)
AND
DB_RespawnEnabled(1)
THEN
CharacterResurrect(_Char);

DB_RespawnEnabled(1); was in the INIT section to enable respawning by default for the test.

I then got this result when testing ingame-

[Linked Image]

Scarlett respawned when she died the first time (because respawn was enabled). Roderick then used Disable Respawning Enemies and killed her again. She didn't resurrect that time. He then Enable Respawning Enemies, resurrects Scarlett with a scroll, and kills her one final time to find that she successfully resurrects at full health.

Page 1 of 3 1 2 3

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.5