|
journeyman
|
journeyman
Joined: Jul 2014
|
Well, the test I did to see that it works was as follows: 1. At the intro fight with the three skeletons, kill them all, move away from them and save. 2. Reload. New enemies have spawned on top of the corpses of the original enemies. 3. Let the new enemies move prior to killing them. Move away and save. 4. Reload. With my code above, enemies spawned at the location that the last ones dies at (not on top of the original corpses). 5. Disable the Respawn toggle. Kill the enemies, save, and then reload. They should be gone.
I suppose I still need to check if consecutive saves/reloads without killing does anything, but I expect it not to. They should be spawning a creature every time since the last generation disappears upon reload (so there is only ever 1 creature spawned per original creature). Just got around testing your version, on save,load,save,load etc. the enemies keep respawning themselves. This is because the game doesn't recognise the %spawn anymore. You should really consider using my code for a quick fix... (I don't mind, just here to help  )
Last edited by FromHolland; 03/09/14 12:29 PM.
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
When you say that they keep respawning themselves, do you mean that after death there are 1,2,3, etc. enemies with subsequent reloads? I can't test it at the moment to check myself.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
When you say that they keep respawning themselves, do you mean that after death there are 1,2,3, etc. enemies with subsequent reloads? I can't test it at the moment to check myself. yeh, if it does work correctly for you then my game is broken  And I was thinking about how to implement an on demand respawn. You can just make a Skill that respawns everything so a player can choose to respawn after a battle if they so chooses (only 1 Skill is required then instead of 2).
Last edited by FromHolland; 03/09/14 01:09 PM.
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
Apparently there has been a big mistake about my assumptions. I have been assuming that because dead spawned enemies cease to exist upon reload, the live ones would have ceased to exist as well. Now that I think about it more, that obviously doesn't make sense.
I think that I can make mine work correctly, I just need one more check to the OnInit function to see if something has already been spawned.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
I think that I can make mine work correctly, I just need one more check to the OnInit function to see if something has already been spawned.
I might be wrong, but checking is ok, but how do you un-check it if the game does not see the %spawn as a %spawn anymore if he dies...?
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
What I'm thinking is this: 1. In the OnInit function, add this part to the IF check- IF "&c5" IsEqual(%spawn, __Me)
And then in the OnDie(%spawn) function after the THEN Set(%spawn, __Me)
I'm cutting out a lot of the code, but those are the important additions. At the beginning %spawn is initialized as __Me. When it dies, %spawn is still __Me.
Upon reload, it checks the IF, sees that %spawn == __Me, and creates a spawn. In the process, it sets %spawn to the new spawned character.
If at that point the game is saved/reloaded, %spawn should still be set to the spawned character, and thus not trigger the OnInit again.
When the spawn dies, %spawn is set to equal __Me again, which will make a new spawn whenever OnInit is run again.
Edit: I think I see now. %spawn is set to null when it reloads doesn't it? My changes above didn't work; they don't even allow a single respawn to occur.
Last edited by Rhidian; 03/09/14 03:49 PM.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
Edit: I think I see now. %spawn is set to null when it reloads doesn't it? My changes above didn't work; they don't even allow a single respawn to occur.
I also found an error (big one) with my own code, and I thought I tested it before... anyways this needs fixing, will test a couple of ideas
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
edit: I think I've found a new solution, testing it now update: seems to be working, need some tweaking because you'll see the spawned characters immediately when they die. When you reload they can fight again update 2: I've set spawned chars invisible, and visible again on reload. this is not the cleanest solution but for now it's good enough
//////////////////////////////////////////////////////////////
EVENT fightmode
ON
OnInit()
ACTIONS
CharacterSetCanFight(__Me,1)
SetVisible(__Me,1)
EVENT CopyTheDead
VARS
CHARACTERTEMPLATE:_template
FLOAT3:_MyPosition
ON
OnDie(__Me,_,_,_)
ACTIONS
IF "c1&c2"
CharacterGetTemplate(__Me,_template)
GetPosition(__Me,_MyPosition)
THEN
SpawnCharacter(%Spawn,_template,_MyPosition,0)
SetVisible(%Spawn,0)
CharacterSetOffStage()
CharacterSetCanFight(%Spawn,0)
ENDIF
//////////////////////////////////////////////////////////////
Last edited by FromHolland; 03/09/14 07:49 PM.
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
I believe that I figured out what was going wrong with the code, and the new version passes all of the tests (consecutive reloads without killing, consecutive reloads with killing, killing after moving, killing with Respawn enabled/disabled). My belief is that upon Initialization, the living characters spawned via the SpawnCharacter command are given new GUIDs. Because the scripts were storing the character after they were spawned, when it came to OnInit the stored character and the living character with a new GUID are no longer equal. Thus the %spawn variable storing the spawned character is unreliable, and can only really work so long as the game isn't reloaded. My solution then was to focus everything around the original character's GUID, since that will always remain constant across different save reloads. I have the script set so that the spawned characters store the original character as a variable, which they can then check upon death (and manipulate so that the parent realizes they no longer have children). Here is version 3 of the mod, which should have everything working correctly now. http://www.mediafire.com/download/mdjb913an5t2phv/RespawningEnemiesWIPv3.zipAnd the code- Default Character changes-
INIT
INT:%canRespawn=0
CHARACTER:%parent=__Me
FLOAT3:%spawnPos=null
INT:%hasChild=0
EVENTS
EVENT RespawnCharacter
VARS
CHARACTERTEMPLATE:_root
FLOAT3:_myPos
CHARACTER:_child
ON
OnInit()
ACTIONS
IF "c1&c2&c3&c4&c5"
IsEqual(%canRespawn, 1)
CharacterIsDead(__Me)
CharacterGetTemplate(__Me, _root)
GetPosition(__Me, _myPos)
IsEqual(%hasChild, 0)
THEN
IF "c1"
IsEqual(%spawnPos, null)
THEN
Set(%spawnPos, _myPos)
ENDIF
SpawnCharacter(_child, _root, %spawnPos, 0)
SetVar(_child, "parent", __Me)
Set(%hasChild, 1)
Set(%canRespawn, 0)
ENDIF
EVENT ProgenyDeath
VARS
FLOAT3:_myPos
ON
OnDie(__Me,_,_,_)
ACTIONS
IF "!c1&c2"
IsEqual(__Me, %parent)
GetPosition(__Me, _myPos)
THEN
SetVar(%parent, "hasChild", INT:0)
SetVar(%parent, "spawnPos", _myPos)
CharacterEvent(%parent, "CheckForRespawn")
ENDIF
Note that the OnInit function is meant to be run by the original characters, while the OnDie event is meant to work for the spawned characters only. Story code-
INITSECTION
DB_RespawnEnabled(1);
KBSECTION
IF
CharacterCreationFinished(CHARACTER_NULL)
AND
CurrentLevel(_Lvl)
AND
DB_CharacterCreationLevels(_Lvl)
THEN
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnDisable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnDisable");
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)
THEN
CharacterSetEvent(_Char, "CheckForRespawn");
IF
CharacterEvent(_Char, "CheckForRespawn")
AND
DB_RespawnEnabled(1)
THEN
CharacterSetVarInteger(_Char, "canRespawn", 1);
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
I believe that I figured out what was going wrong with the code, and the new version passes all of the tests (consecutive reloads without killing, consecutive reloads with killing, killing after moving, killing with Respawn enabled/disabled). My belief is that upon Initialization, the living characters spawned via the SpawnCharacter command are given new GUIDs. Because the scripts were storing the character after they were spawned, when it came to OnInit the stored character and the living character with a new GUID are no longer equal. Thus the %spawn variable storing the spawned character is unreliable, and can only really work so long as the game isn't reloaded. My solution then was to focus everything around the original character's GUID, since that will always remain constant across different save reloads. I have the script set so that the spawned characters store the original character as a variable, which they can then check upon death (and manipulate so that the parent realizes they no longer have children). Here is version 3 of the mod, which should have everything working correctly now. http://www.mediafire.com/download/mdjb913an5t2phv/RespawningEnemiesWIPv3.zipAnd the code- Default Character changes-
INIT
INT:%canRespawn=0
CHARACTER:%parent=__Me
FLOAT3:%spawnPos=null
INT:%hasChild=0
EVENTS
EVENT RespawnCharacter
VARS
CHARACTERTEMPLATE:_root
FLOAT3:_myPos
CHARACTER:_child
ON
OnInit()
ACTIONS
IF "c1&c2&c3&c4&c5"
IsEqual(%canRespawn, 1)
CharacterIsDead(__Me)
CharacterGetTemplate(__Me, _root)
GetPosition(__Me, _myPos)
IsEqual(%hasChild, 0)
THEN
IF "c1"
IsEqual(%spawnPos, null)
THEN
Set(%spawnPos, _myPos)
ENDIF
SpawnCharacter(_child, _root, %spawnPos, 0)
SetVar(_child, "parent", __Me)
Set(%hasChild, 1)
Set(%canRespawn, 0)
ENDIF
EVENT ProgenyDeath
VARS
FLOAT3:_myPos
ON
OnDie(__Me,_,_,_)
ACTIONS
IF "!c1&c2"
IsEqual(__Me, %parent)
GetPosition(__Me, _myPos)
THEN
SetVar(%parent, "hasChild", INT:0)
SetVar(%parent, "spawnPos", _myPos)
CharacterEvent(%parent, "CheckForRespawn")
ENDIF
Note that the OnInit function is meant to be run by the original characters, while the OnDie event is meant to work for the spawned characters only. Story code-
INITSECTION
DB_RespawnEnabled(1);
KBSECTION
IF
CharacterCreationFinished(CHARACTER_NULL)
AND
CurrentLevel(_Lvl)
AND
DB_CharacterCreationLevels(_Lvl)
THEN
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnDisable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnDisable");
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)
THEN
CharacterSetEvent(_Char, "CheckForRespawn");
IF
CharacterEvent(_Char, "CheckForRespawn")
AND
DB_RespawnEnabled(1)
THEN
CharacterSetVarInteger(_Char, "canRespawn", 1);
then we arrived at the same conclusion  grats m8!
Last edited by FromHolland; 03/09/14 07:55 PM.
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
Alright, I think this mod is at the point where it is feature complete. Version 4 of the mod- http://www.mediafire.com/download/g7554qx0v4jd9e3/RespawningEnemiesV4.zipFeatures: -Enemies will respawn* where they last died (this is on by default) -Player characters receive four skills upon arriving at Cyseal Beach that toggle various functions in this mod. 1. Disable Respawning Enemies - This makes it so that when enemies are killed, they no longer respawn. 2. Enable Respawning Enemies - This makes it so that enemies who are killed will respawn. 3. Mass Respawn - This makes it so that all NPCs who are currently dead (and haven't respawned) will respawn, even if they were killed when Respawn was disabled. 4. Reset Spawn Positions - The next time that dead enemies respawn will be at where they originally died at *Respawn means that a copy of the enemy will appear where the NPC last died. The original NPC's corpse will remain in the location that they originally died at. --- Full code- Default Character changes:
INIT
INT:%canRespawn=0
CHARACTER:%parent=__Me
FLOAT3:%spawnPos=null
INT:%hasChild=0
EVENTS
EVENT RespawnCharacter
VARS
CHARACTERTEMPLATE:_root
FLOAT3:_myPos
CHARACTER:_child
ON
OnInit()
ACTIONS
IF "c1&c2&c3&c4&c5"
IsEqual(%canRespawn, 1)
CharacterIsDead(__Me)
CharacterGetTemplate(__Me, _root)
GetPosition(__Me, _myPos)
IsEqual(%hasChild, 0)
THEN
IF "c1"
IsEqual(%spawnPos, null)
THEN
Set(%spawnPos, _myPos)
ENDIF
SpawnCharacter(_child, _root, %spawnPos, 0)
SetVar(_child, "parent", __Me)
Set(%hasChild, 1)
Set(%canRespawn, 0)
ENDIF
EVENT ProgenyDeath
VARS
FLOAT3:_myPos
ON
OnDie(__Me,_,_,_)
ACTIONS
IF "!c1&c2"
IsEqual(__Me, %parent)
GetPosition(__Me, _myPos)
THEN
SetVar(%parent, "hasChild", INT:0)
SetVar(%parent, "spawnPos", _myPos)
CharacterEvent(%parent, "CheckForRespawn")
ENDIF
EVENT ResetSpawnPosition
VARS
FLOAT3:_myPos
ON
OnCharacterEvent(__Me, "ResetSpawnPosition")
ACTIONS
IF "c1"
GetPosition(__Me, _myPos)
THEN
Set(%spawnPos, _myPos)
ENDIF
Story script-
INITSECTION
DB_RespawnEnabled(1);
KBSECTION
IF
CharacterCreationFinished(CHARACTER_NULL)
AND
CurrentLevel(_Lvl)
AND
DB_CharacterCreationLevels(_Lvl)
THEN
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player1, "Shout_RespawnDisable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnEnable");
CharacterAddSkill(CHARACTER_Player2, "Shout_RespawnDisable");
CharacterAddSkill(CHARACTER_Player1, "Shout_MassRespawnEnable");
CharacterAddSkill(CHARACTER_Player2, "Shout_MassRespawnEnable");
CharacterAddSkill(CHARACTER_Player1, "Shout_ResetSpawnPosition");
CharacterAddSkill(CHARACTER_Player2, "Shout_ResetSpawnPosition");
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)
THEN
CharacterSetEvent(_Char, "CheckForRespawn");
IF
CharacterEvent(_Char, "CheckForRespawn")
AND
NOT _Char.isPlayer()
AND
DB_RespawnEnabled(1)
THEN
CharacterSetVarInteger(_Char, "canRespawn", 1);
IF
CharacterDied(_Char)
AND
NOT _Char.isPlayer()
AND
NOT DB_DeadCharacters(_Char)
THEN
DB_DeadCharacters(_Char);
IF
CharacterEvent(_Char, "CheckForRespawn")
AND
NOT DB_DeadCharacters(_Char)
THEN
DB_DeadCharacters(_Char);
IF
CharacterUsedSkill(_Char, "Shout_MassRespawnEnable", _)
THEN
MassRespawn();
PROC
MassRespawn()
AND
DB_DeadCharacters(_Char)
THEN
CharacterSetVarInteger(_Char, "canRespawn", 1);
NOT DB_DeadCharacters(_Char);
MassRespawn();
IF
CharacterDied(_Char)
AND
NOT DB_SpawnPositions(_Char)
THEN
DB_SpawnPositions(_Char);
IF
CharacterEvent(_Char, "CheckForRespawn")
AND
NOT DB_SpawnPositions(_Char)
THEN
DB_SpawnPositions(_Char);
IF
CharacterUsedSkill(_Char, "Shout_ResetSpawnPosition", _)
THEN
MassResetSpawnPosition();
PROC
MassResetSpawnPosition()
AND
DB_SpawnPositions(_Char)
THEN
CharacterSetEvent(_Char, "ResetSpawnPosition");
NOT DB_SpawnPositions(_Char);
MassResetSpawnPosition();
Lessons learned from working on this mod- 1. Main campaign charScripts (and presumably itemScripts) can be overwritten by mods. There might be some side effects, but it can be done.
2. Story scripts and charScripts/itemScripts can work together to great effect.
3. Resurrected characters don't give exp but are easier to work with, while Spawned characters give exp and are much harder to work with. Something about living spawned characters (perhaps GUID) appears to change whenever the game is loaded (or perhaps they die) such that they are no longer equal to what they were prior to game load/death.
I think I now have enough experience in charScripts/itemScripts to add a section to my tutorial thread.
Last edited by Rhidian; 03/09/14 10:30 PM.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
great fix :), and great mod. Somehow I'm unable to catch the spawned characters in any of my story scripts, but I can catch them in charscripts. Am I missing something...?
|
|
|
|
addict
|
OP
addict
Joined: Jul 2014
|
I wasn't able to catch spawned characters in Story scripts either, which is why I focused everything around the spawning character (original character). The spawned enemies don't trigger CharacterDied events at the very least.
The reason charScripts might work over Story scripts is due to either the spawned character using a charScript themselves or because it matters more for AI in combat since it allows them to be targetted.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
I wasn't able to catch spawned characters in Story scripts either, which is why I focused everything around the spawning character (original character). The spawned enemies don't trigger CharacterDied events at the very least.
The reason charScripts might work over Story scripts is due to either the spawned character using a charScript themselves or because it matters more for AI in combat since it allows them to be targetted. Yeh sadly there is no way I can think of (and I tried many  ) to catch them in story scripts. It would be great though to create and manipulate characters on the fly, like for some RTS element that I'm working on in my own mod. Will shelf that idea sadly. edit: when I create a character template and then remove the original template from the game(ie destroychar), the new character is recognised by story scripting as if it where the original one.
Last edited by FromHolland; 07/09/14 02:26 PM.
|
|
|
|
apprentice
|
apprentice
Joined: Sep 2014
|
I would love to see this project completed. Personally, I see the current status quo of a fixed number of objects in the world as problematic for two key reasons. In gameplay terms, it means that I feel a need to kill every single monster, and gainfully utilise every single item. In feel/realism, the game becomes considerably less... alive once you've been playing a while. Hey, tell Aureus he can have a holiday, there is not a single living corpse remaining in the Cyseal area. For the same reason, I'd love to see ores respawn, and further chances to pickpocket: but uh, for difficulty, perhaps not further copies of every painting, plate, and cup (without substantial balancing). My, my, the Cyseal art and homewares scene is booming. Do you have plans to remove corpses at some point? I imagine the games engine could get pretty overloaded otherwise (if an area is cleared enough times). edit: I guess I should pause to note there are some nice advantages in D:OS relative to the traditional fully respawning world, it's really nice being able to set up camp wherever you like, set up your chests in places, take over abandoned buildings, and not worry about "safe storage". Perhaps there's a best of both worlds though? 
Last edited by synra; 07/09/14 06:04 PM.
|
|
|
|
journeyman
|
journeyman
Joined: Jul 2014
|
Rhidian finished this mod, only the original corpse remains and the newly spawned characters do not leave corpses
|
|
|
|
apprentice
|
apprentice
Joined: Sep 2014
|
It appears I'm behind the times. That sounds like an excellent solution. I may just have to overcome caution and dig in 
|
|
|
|
stranger
|
stranger
Joined: Jan 2015
|
Hi all, how to install this RespawningEnemiesV4.zip mod on OS X?
|
|
|
Moderated by Bvs, ForkTong, gbnf, Issh, Kurnster, Larian_QA, LarSeb, Lar_q, Lynn, Monodon, Raze, Stephen_Larian
|
|