Larian Banner: Baldur's Gate Patch 9
Previous Thread
Next Thread
Print Thread
Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
This seems soooooo circumvoluted, to give some random XPs to the player....
So, the script:
Code
INIT
	ITEM:__Me
	EXTERN CHARACTERTEMPLATE:%animalToSpawn=null
	
EVENTS
EVENT onuseitem
VARS
FLOAT3:_trackspositions
FLOAT3:_spawnDestination
CHARACTER:_Source
INT:_GainedXP
ON
OnUseItem(_Source,__Me)

ACTIONS
IF "c1"
IsRandom(0.4)
THEN
GetRandom(_spawnDestination,{-2;0;2},{2;0;-2},{2;0;2},{-2;0;-2},{-2;0;0},{2;0;0},{0;0;-2},{0;0;2})
GetPosition(__Me,_trackspositions)
Add(_trackspositions,_spawnDestination)
SpawnCharacter(_,%animalToSpawn,_trackspositions,0)
DisplayText(_Source,"You successfully follow the tracks",3)
//DialogStart(_,"dialog_tracks",__Me,_Source)
SetUserFlag(_Source,"usedtrackssuccess")
ELSE
GetRandomBetween(_GainedXP,1,5)
SetVar(_Source,"xpgainedfromfailure",_GainedXP)
SetUserFlag(_Source,"usedtracksfailure")
DisplayText(_Source,"You fail to follow the tracks",3)
ENDIF
ClearUserFlag(_Source,"usedtrackssuccess")
ClearUserFlag(_Source,"usedtracksfailure")
ItemDestroy(__Me)


In order to give the XPs to the player, I define a tag that is different whether the player succeeds or fails.
Then, I randomized an int variable:
Code
GetRandomBetween(_GainedXP,1,5))

that I set as a Variable on the user:
Code
SetVar(_Source,"xpgainedfromfailure",_GainedXP)


then, to the story code:
Code
IF
ObjectFlagSet("usedtracksfailure",_Source,_)
AND
GetVarInteger(_Source,"xpgainedfromfailure",_Value)
THEN

PartyAddActualExperience((CHARACTERGUID)_Source,_Value);


so, this story waits for the flag to be set. I then get the Var that holds the random int.

Then, I add that random int to the player.


GOOOOOOOOOOOOOD, please tell me there is a cleaner, easier, smoother, nicer, better way to do this, like a "giveXP" function that I can call within a script.

btw, how do I create a function ? because there is a 'callfunction" script thingy that might be handy.

And this is only randomizing the gained XPs. I can't imagine when I will have to get more variables, and use them for some stuff...

Last edited by Cromcrom; 25/09/17 05:22 AM.

Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Jun 2013
old hand
Offline
old hand
Joined: Jun 2013
What's the part you are trying to simplify?

The story editor section seems pretty simple TBH as far as story statements go, it's the charscript part that's complex.


I don't know much about functions and calling them from charscripts, so maybe someone else knows. But I'm not really sure how it would differ all that much from what you have now.

Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
for the function, something that could go like
function giverandomXPtoplayer((character)player,(int)minXP,(int)maxXP)
that I could call from charscript, instead of

in the charscript:
assign a tag to player so that osiris knows something happened
get a random number
assign that number to a variable
then in osiris:
recognize the event (tag) that leads to giving the XP then
retrieve that variable that holds the random integer XP
give those XP to the player

I am not even talking about modifying the values according to the char attributes, skill level, item equipped, bench quality, for example...
this could be really excrutiating...

There HAS to be a simpler way.


Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Dec 2016
Location: United States
member
Offline
member
Joined: Dec 2016
Location: United States
I'm not sure there's a much better way to do this. To my knowledge, Osiris can only produce random values through modulo of a random number; therefore the min value is always going to be zero (You could impose a minimum with a custom random query, but you've asked for simplicity). As a result, if you want to have random values with a higher min, you'll need to use object scripts, as you have done.

That being said, here's my 5 minute approach to it:

Object script:
Code
INIT

CHARACTER:__Me

INT:%DEMO_RandomEXP_Min
INT:%DEMO_RandomEXP_Max
INT:%DEMO_RandomEXP_Value

EVENTS
EVENT DEMO_AddRandomEXP
ON
OnFunction("DEMO_AddRandomEXP")
ACTIONS
//Set(%DEMO_RandomEXP_Min, <MinValueHere>)    //Probably best to set these in calling block before calling this function.
//Set(%DEMO_RandomEXP_Max, <MaxValueHere>)    //Probably best to set these in calling block before calling this function.
GetRandomBetween(%DEMO_RandomEXP_Value, %DEMO_RandomEXP_Min, %DEMO_RandomEXP_Max)
CharacterEvent(__Me, "DEMO_AddRandomEXP")


Story script:
Code
IF
StoryEventSet(_Char, "DEMO_AddRandomEXP")
AND
GetVarInteger(_Char, "DEMO_RandomEXP_Value", _Value)
THEN
PartyAddActualExperience(_Char, _Value);   //There are a few EXP granting calls, make sure you understand the differences between them, and use the one that best fits your intent.


The character could CallFunction("DEMO_AddRandomEXP") after setting the min and max values, and all would be taken care of.



Last edited by Ameranth; 24/09/17 09:49 PM.
Joined: Jun 2013
old hand
Offline
old hand
Joined: Jun 2013
I think the short answer is, there's no way to add experience in charscripts directly.


Did you test how you have it set up in the OP? Does it work? If so I'd just leave it alone. Unless you're worried about having to do this sort of thing a lot. But given that you're trying to do something unusual like randomized experience, that's probably going to come with the territory.



I think I'm misunderstanding the term function (I'm not a scripter, I'm a mucker) As far as I understand the CallFunction command in charscripts, it will only refer to something within a charscript.




I would probably remove everything from that charscript possible and try and do it in Osiris. The only thing you'd probably need to leave in the charscript is the tracks stuff and a flag for failure and success. You can do the randomizing in Osiris.


I could see maybe writing a generalist Osiris script if you feel you must continue with charscripts. Most likely you'd have to separate the success/fail flag from the experience one to do it though so you could reuse the experience event for any quest. Similar to what Amer did.

But you'd also have to account for level and a way to increase the general script based on that. So you could throw in a CharacterGetLevel() query in the general statement and pull that to follow along the player's progress. The best way to do that would be with the PartyAddExperience experience call, not the "ACTUAL" experience ones.




EDIT: Oh and for the 0 being used in the random query in Osiris. You could just add 1 to it via IntegerSum
IF
ObjectFlagSet("ExperienceReward",_Source,_)
AND
Random(4,_Random) // Random in Osiris uses 0, must add 1
AND
IntegerSum(_Random,1,_RandomEXP) //0-3 is now 1-4


Then pass all that stuff to the PartyAddExperience call like:
PartyAddExperience(_Source,1,1,_RandomEXP);


Last edited by SniperHF; 24/09/17 10:06 PM.
Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
Thanks lads.
I am probably just not used to D:OS2 coding yet, and was expecting stuff. The workaround wasn't that bad to discover, I will try to push through, and create my various systems.

Cheers hehe


Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Jun 2013
old hand
Offline
old hand
Joined: Jun 2013
Bouncing between object and story script can be tedious :P

I had to do so to make my Day/Night cycle in Dunamis. Took a couple months ouch

Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
Quote
Bouncing between object and story script can be tedious :P

THAT !

Thanks, Glad to have someone understanding some of my frustration. However, this D:OS2 engine is day and night (no pun intended ;-))) ) compared to the D:OS one. I can actually create stuff that seem to work ^^


Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Sep 2017
Location: Finland
journeyman
Offline
journeyman
Joined: Sep 2017
Location: Finland
How did you go about getting the game to read your scripts?

Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
Just the plain, normal procedure I guess:
attached the script to the character or item, and create an osiris story that listen when a flag is set in the script
Code
IF
ObjectFlagSet("usedtracksfailure",_Source,_)

, and fires the osiris XP giving part.
Bulky, IMHO, because in all other scripted mods I created (NWN2, MB warband, Legend of grimrock, to name the most important ones), it was usually only in one place, and I could create a function to call and make things much more cleaner and simpler.


Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Sep 2017
Location: Finland
journeyman
Offline
journeyman
Joined: Sep 2017
Location: Finland
So you attached that script to all playable characters in the game? I'm just curious about your scripting workflow - maybe I can learn from it, since I can't even get a script to work despite knowing the syntax.

My modding background is all from Skyrim, and normally I just make a quest script(it's kind of like a "global" object when you don't want to directly add scripts to other objects).

Last edited by Rasikko; 25/09/17 08:01 AM.
Joined: Jun 2013
addict
OP Offline
addict
Joined: Jun 2013
I created , for example, a boar template, and attached a script (random death) to it. Then I externally added the itemguid of the tracks I wanted to spawn when the boar disappears.
I hope this image can help you, because I don't really understand your question it seems :-(

https://imgur.com/a/Zh04J




Un chemin de 1000 lieues commence par un premier pas.

Project:
Steam workshop Frontiere
Joined: Sep 2017
Location: Finland
journeyman
Offline
journeyman
Joined: Sep 2017
Location: Finland
Yes that helps a lot, thanks for sharing. I understand what to do if I want to script individual characters, now.


Moderated by  Larian_KVN 

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