Jump to content

Requesting Help to finish a script.


allomerus

Recommended Posts

Hello everybody!

 

Beware, this is going to be long.

 

I'm working on a rather large-scale mod that will introduce all my current and ulterior custom weapon models in a dungeon-like area, just to make people actually work for them. As I want every of these items to be acquired with a little sweat and a lot fo blood (mwaaahaha), I plan to make one of my daggers actually curse the player with an undispellable ability (as qualified in the CS), while also providing the player a way to « atone » for the very sin of picking it up by scrificing daedra hearts. When the atonement is finished (which implies the slaughter of hundreds of daedra), the blade grants the player the ability to devour daedra hearts for himselfm. increasing his magicka, health and fatigue by some small, to-be-determined amount.

 

While the « cursing » mechanic works flawlessly, the part of the script which allows the player to slowly make the curse weaker (it has 10 stages) does not work.

 

What I intended to do is that the player, when casting the « Sacrifice Daedra Heart » lesser power, increases a variable (HeartSacrifice) by 1. Another script is triggered when HeartSacrifice reaches a certain value, removing the greater version of the ability and adding a lesser one in its place.

 

But the HeartSacrifice value does not seem to be functional. I cannot, for an example, use the « set Heartsacrifice to x » command, because the engine does seem to think it does not exist.

 

So, basically, if someone around here is handy with scripts, I'd like you to have a look at this, and maybe tell me what I'm doing wrong. That's a week of off-work pain : (

 

People providing actual solutions will end up in my credits list, of course.

 

 

FIRST SCRIPT - Object script, tied to the blade itself (AlloThalassianStiletto)

 

As far as I know, this one works flawlessly. It's a curse-on-equip type of PITA blade-of-doom.

 

Scn AlloThalassianStilettoScr

ref Player
Short ThalStilCurseCured
Short ThalStilCurseStriken

begin OnEquip 

If ThalStilCurseStriken == 1
Return
Elseif ThalStilCurseStriken == 0
If ThalStilCurseCured == 1
	Return
	ElseIf ThalStilCurseCured == 0
		Player.AddSpellNS AlloThalStilCurse10
		Set ThalStilCurseStriken to 1
	endif
endif


end

 

Where ThalStilCurseCured is checked at the very end on the « master » script when the 10th stage of the curse is removed.

 

 

SECOND SCRIPT - Quest script, also the « Master script », the one that proceeds to the switching between stages of the curse, taunts the player in the name of another entity, and monitors the HeartSacrifice variable.

 

 

Scn AlloThalStilCurseQuest

Ref Player

Short Curse10
Short Curse9
Short Curse8
Short Curse7
Short Curse6
Short Curse5
Short Curse4
Short Curse3
Short Curse2
Short Curse1
Short HeartSacrifice
Short ThalStilCurseCured

Begin gamemode

If ( ThalStilCurseCured == 1 )
return
Elseif Player.HasSpell AlloThalStilCurse10 == 0
Return
	Elseif ( Curse10 == 1 )
	Return
		ElseIf Player.HasSpell AlloThalStilCurse10
		Player.AddSpellNS AlloThalStilSacrifice
		Message "The Sun's fury is upon you!"
		Set HeartSacrifice to 0
		Set Curse10 to 1			
	Endif

***Stuff stops working from this very point***

If ( Curse10 == 0 )
Return
	Elseif ( Curse10 == 1 )
		If ( HeartSacrifice < 10)
		Return
			Elseif ( HeartSacrifice >= 10)
			Set Curse9 to 1
			player.removespellNS AlloThalStilCurse10
			Player.addspellNS AlloThalStilCurse9
			Message "You are slowly sating the blade's thirst."
			Set Curse10 to 0
		Endif
	Endif

If ( Curse9 == 0 )
return
	Elseif ( Curse9 == 1 )
		If ( HeartSacrifice < 25)
		Return
			Elseif ( HeartSacrifice >= 25)
			Set Curse8 to 1
			Player.removespellNS AlloThalStilCurse9
			Player.addspellNS AlloThalStilCurse8
			Message "The Thalassian blade demands more souls!"
			Set Curse9 to 0
		Endif
	Endif

If ( Curse8 == 0 )
Return
	Elseif ( Curse8 == 1 )
		If ( HeartSacrifice < 45)
		Return
			Elseif ( HeartSacrifice >= 45)
			Set Curse7 to 1
			Player.removespellNS AlloThalStilCurse8
			Player.addspellNS AlloThalStilCurse7
			Message "Sacrifice again, or the Sun shall forever be your enemy!"
			Set Curse8 to 0
		Endif
	Endif

If ( Curse7 == 0 )
Return
	Elseif ( Curse7 == 1 )
		If ( HeartSacrifice < 70)
		Return
			Elseif ( HeartSacrifice >= 70)
			Set Curse6 to 1
			Player.removespellNS AlloThalStilCurse7
			Player.addspellNS AlloThalStilCurse6
			Message "Your time, your very life belongs to us."
			Set Curse7 to 0
		Endif
	Endif

If ( Curse6 == 0 )
Return
	Elseif ( Curse6 == 1 )
		If ( HeartSacrifice < 100)
		Return
			Elseif ( HeartSacrifice >= 100)
			Set Curse5 to 1
			Player.removespellNS AlloThalStilCurse6
			Player.addspellNS AlloThalStilCurse5
			Message "Fight to the death. It is your only hope."
			Set Curse6 to 0
		Endif
	Endif

If ( Curse5 == 0 )
Return
	Elseif ( Curse5 == 1 )
		If ( HeartSacrifice < 135)
		Return
			Elseif ( HeartSacrifice >= 135)
			Set Curse4 to 1
			Player.removespellNS AlloThalStilCurse5
			Player.addspellNS AlloThalStilCurse4
			Message "The Sun is a demanding master."
			Set Curse5 to 0
		Endif
	Endif

If ( Curse4 == 0 )
Return
	Elseif ( Curse4 == 1 )
		If ( HeartSacrifice < 175)
		Return
			Elseif ( HeartSacrifice >= 175)
			Set Curse3 to 1
			Player.removespellNS AlloThalStilCurse4
			Player.addspellNS AlloThalStilCurse3
			Message "Your sacrifices will be rewarded, in the end."
			Set Curse4 to 0
		Endif
	Endif

If ( Curse3 == 0 )
Return
	Elseif ( Curse3 == 1 )
		If ( HeartSacrifice <  230)
		Return
			Elseif ( HeartSacrifice >= 230)
			Set Curse2 to 1
			Player.removespellNS AlloThalStilCurse3
			Player.addspellNS AlloThalStilCurse2
			Message "You serve our vengeance well, mortal."
			Set Curse3 to 0
		Endif
	Endif

If ( Curse2 == 0 )
Return
	Elseif ( Curse2 == 1 )
		If ( HeartSacrifice < 280)
		Return
			Elseif ( HeartSacrifice >= 280)
			Set Curse1 to 1
			Player.removespellNS AlloThalStilCurse2
			Player.addspellNS AlloThalStilCurse1
			Message "You turned your doom into a crusade. Impressive."
			Set Curse2 to 0
		Endif
	Endif

If ( Curse1 == 0 )
Return
	Elseif ( Curse1 == 1 )
		If ( HeartSacrifice < 335)
		Return
			Elseif ( HeartSacrifice >= 335)
			Player.RemovespellNS AlloThalStilCurse1
			Player.RemoveSpellNS AlloThalStilSacrifice
			Player.addspellNS AlloThalStilDevour
			Message "You are free. May you devour our enemies' souls forever!"
			Set ThalStilCurseCured to 1
			Set Curse1 to 0
		Endif
Endif

End

 

Where :

 

AlloThalStilSacrifice is the script contained in the spell which sacrifices daedra hearts,

AlloThalStilDevour the script the script tied to the reward spell that allows the player to devour hearts to boost his power,

AlloThalStilCurse(x number) the curse « ability » itself.

 

 

THIRD SCRIPT - Magic effect script, that is tied to the spell that sacrifices daedra hearts.

 

Note that the part that removes the heart is perfectly functional. So it's not a matter of unmatched condition, it's really about recognizing the variable I believe.

 

Scn AlloThalStilSacrificeScr

Ref Item
short HeartSacrifice

begin ScriptEffectStart

If Player.GetEquipped AlloThalassianStiletto == 0
message "You must be wielding the Thalassian Blade"
return
Else
If Player.getequipped AlloThalassianStiletto
	Set Item to DaedraHeart
	If Player.getItemcount item == 0
		return
	Else
		If Player.getItemcount item >= 1
		Set HeartSacrifice to ( Heartsacrifice + 1 )
		removeitemNS Item 1
		Endif
	Endif
Endif
Endif

end

begin scripteffectfinish

	return

end

 

I really don't know what's wrong.

 

Please, you're my only hope!

 

Thanks a lot for your time - especially if you've just read all that text!

Edited by allomerus
Link to comment
Share on other sites

EDIT; this doesn't show any of the times i used tabs :( so I had to use " . "

 

First script.

Scn AlloThalassianStilettoScr

 

Short DoOnce ; This ensures the curse is only added once

 

Begin OnEquip

 

If DoOnce == 1

..... Return

Else

..... Player.AddSpellNS AlloThalStilCurse10

..... Set DoOnce to 1

..... SetStage cursedbladequest 10 ; create a quest to run the main script - this may not be needed. someone with more experience could tell you

endif

 

End

 

No major change. it's just shorter and easier for you or others to read at a later date

 

Next you need to create a Global. On TES CS on the top bar click Gameplay then Global. Call this HeartSacrifice. Set it as a float with a start of 0. This can be replaced with a quest if you prefer - which wont need to leave journal updates but can.

 

Scn AlloThalStilCurseQuest ; attach this script to a quest called CursedBladeQuest or change ALL references to it in the scripts

 

Float Curse

 

; make a global called HeartSacrifice

 

Begin gamemode

 

..... If (Player.HasSpell AlloThalStilCurse10) && (GetStage cursedbladequest == 10) && (Curse == 0)

......... Player.AddSpellNS AlloThalStilSacrifice

......... Message "The Sun's fury is upon you!"

......... Set HeartSacrifice to 0

......... Set Curse to 1

..... Elseif (Curse == 1) && ( HeartSacrifice >= 10)

......... player.removespellNS AlloThalStilCurse10

......... Player.addspellNS AlloThalStilCurse9

......... Message "You are slowly sating the blade's thirst."

......... Set Curse to 2

..... Elseif ( Curse == 2 ) && ( HeartSacrifice >= 25)

......... Player.removespellNS AlloThalStilCurse9

......... Player.addspellNS AlloThalStilCurse8

......... Message "The Thalassian blade demands more souls!"

......... Set Curse to 3

..... Elseif ( Curse == 3 ) && ( HeartSacrifice >= 45)

......... Player.removespellNS AlloThalStilCurse8

......... Player.addspellNS AlloThalStilCurse7

......... Message "Sacrifice again, or the Sun shall forever be your enemy!"

......... Set Curse to 4

..... Elseif ( Curse == 4 ) && ( HeartSacrifice >= 70)

......... Player.removespellNS AlloThalStilCurse7

......... Player.addspellNS AlloThalStilCurse6

......... Message "Your time, your very life belongs to us."

......... Set Curse to 5

..... Elseif ( Curse == 5 ) && ( HeartSacrifice >= 100)

......... Player.removespellNS AlloThalStilCurse6

......... Player.addspellNS AlloThalStilCurse5

......... Message "Fight to the death. It is your only hope."

......... Set Curse to 6

..... Elseif ( Curse == 6 ) && ( HeartSacrifice >= 135)

......... Player.removespellNS AlloThalStilCurse5

......... Player.addspellNS AlloThalStilCurse4

......... Message "The Sun is a demanding master."

......... Set Curse to 7

..... Elseif ( Curse == 7 ) && ( HeartSacrifice >= 175)

......... Player.removespellNS AlloThalStilCurse4

......... Player.addspellNS AlloThalStilCurse3

......... Message "Your sacrifices will be rewarded, in the end."

......... Set Curse to 8

..... Elseif ( Curse == 8 ) && ( HeartSacrifice >= 230)

......... Player.removespellNS AlloThalStilCurse3

......... Player.addspellNS AlloThalStilCurse2

......... Message "You serve our vengeance well, mortal."

......... Set Curse to 9

..... Elseif ( Curse == 9 ) && ( HeartSacrifice >= 280)

......... Player.removespellNS AlloThalStilCurse2

......... Player.addspellNS AlloThalStilCurse1

......... Message "You turned your doom into a crusade. Impressive."

......... Set Curse to 10

..... Elseif ( Curse == 10 ) && ( HeartSacrifice >= 335)

......... Player.RemovespellNS AlloThalStilCurse1

......... Player.RemoveSpellNS AlloThalStilSacrifice

......... Player.addspellNS AlloThalStilDevour

......... Message "You are free. May you devour our enemies' souls forever!"

......... Set Curse to 11

......... SetStage CurseBladeQuest 20

......... StopQuest CurseBladeQuest

..... Endif

 

End

 

Scn AlloThalStilSacrificeScr

 

Ref Item

 

begin ScriptEffectStart

 

..... If Player.GetEquipped AlloThalassianStiletto == 0

......... message "You must be wielding the Thalassian Blade"

......... return

..... ElseIf Player.getequipped AlloThalassianStiletto

......... Set Item to DaedraHeart

......... If Player.getItemcount item == 0

......... return

......... Else

......... Set HeartSacrifice to ( Heartsacrifice + 1 )

......... removeitemNS Item 1

......... Endif

..... Endif

End

 

Let me know if this works.

A few notes.

Use the TAB button!!!

notice how I Structured it using the tab button? If's within ifs are set forward as are actions. then you return back for the endif. this allows you to see which ifs go with elseif, else & endif etc. Structure makes it so much easier for you, and more importantly others to read.

 

I hope this works. BTW is there any difference in the spells??.

 

Most importantly :unsure: how do you use the white boxes that you posted the scripts in?

Edited by cfh85
Link to comment
Share on other sites

Precede your script code with a ['code'] (without the quote marks needed so it will show in this post) and end the script code block with a ['/code'] (again without the quote marks). Tabs will then work within the code tags.
Link to comment
Share on other sites

@ cfh85

 

Thanks for the info, I'll try to understand it without mucking it all up : )

 

One question thought:

 

I was told that continuous « gamemode » scripts were supposed to contain as many « return » functions as possible, so that they clutter the engine's RAM as little as possible.

 

What I know is that Oblivion's engine processes scripts entirely even thought an « if » condition is not met at the beginning, thus my tendency to fraction the 10 stages of the curse and add return blocks at the beginning of each of them.

 

If what I know is right, your proposal will cause the computer to read all the script until the quest is complete, and (note that I play on an old dinosaur with « crapbucket » graphics settings) I am very concerned with any performance hits.

Is there a way to make it lighter, or am I just rambling about stuff I don't know?

 

Thanks again!

Edited by allomerus
Link to comment
Share on other sites


Float fQuestDelayTime

Begin gamemode
Set fQuestDelayTime to 1 ; a lot f scripts use values like 0.01 which will process the script 100 times a second - once a second is enough for what you want
If Curse == 11 ;this will stop the script once you've finished (as should ending the quest I think
	return
ElseIf (Player.HasSpell AlloThalStilCurse10) && (GetStage cursedbladequest == 10) && (Curse == 0)
 Player.AddSpellNS AlloThalStilSacrifice
 Message "The Sun's fury is upon you!"
 Set HeartSacrifice to 0
 Set Curse to 1 
Elseif (Curse == 1) && ( HeartSacrifice >= 10)
 player.removespellNS AlloThalStilCurse10
 Player.addspellNS AlloThalStilCurse9
 Message "You are slowly sating the blade's thirst."
 Set Curse to 2
Elseif ( Curse == 2 ) && ( HeartSacrifice >= 25)
 Player.removespellNS AlloThalStilCurse9
 Player.addspellNS AlloThalStilCurse8
 Message "The Thalassian blade demands more souls!"
 Set Curse to 3
Elseif ( Curse == 3 ) && ( HeartSacrifice >= 45)
 Player.removespellNS AlloThalStilCurse8
 Player.addspellNS AlloThalStilCurse7
 Message "Sacrifice again, or the Sun shall forever be your enemy!"
 Set Curse to 4
Elseif ( Curse == 4 ) && ( HeartSacrifice >= 70)
 Player.removespellNS AlloThalStilCurse7
 Player.addspellNS AlloThalStilCurse6
 Message "Your time, your very life belongs to us."
 Set Curse to 5
Elseif ( Curse == 5 ) && ( HeartSacrifice >= 100)
 Player.removespellNS AlloThalStilCurse6
 Player.addspellNS AlloThalStilCurse5
 Message "Fight to the death. It is your only hope."
 Set Curse to 6
Elseif ( Curse == 6 ) && ( HeartSacrifice >= 135)
 Player.removespellNS AlloThalStilCurse5
 Player.addspellNS AlloThalStilCurse4
 Message "The Sun is a demanding master."
 Set Curse to 7
Elseif ( Curse == 7 ) && ( HeartSacrifice >= 175)
 Player.removespellNS AlloThalStilCurse4
 Player.addspellNS AlloThalStilCurse3
 Message "Your sacrifices will be rewarded, in the end."
 Set Curse to 8
Elseif ( Curse == 8 ) && ( HeartSacrifice >= 230)
 Player.removespellNS AlloThalStilCurse3
 Player.addspellNS AlloThalStilCurse2
 Message "You serve our vengeance well, mortal."
 Set Curse to 9
Elseif ( Curse == 9 ) && ( HeartSacrifice >= 280)
 Player.removespellNS AlloThalStilCurse2
 Player.addspellNS AlloThalStilCurse1
 Message "You turned your doom into a crusade. Impressive."
 Set Curse to 10
Elseif ( Curse == 10 ) && ( HeartSacrifice >= 335)
 Player.RemovespellNS AlloThalStilCurse1
 Player.RemoveSpellNS AlloThalStilSacrifice
 Player.addspellNS AlloThalStilDevour
 Message "You are free. May you devour our enemies' souls forever!"
 SetStage CurseBladeQuest 20
 StopQuest CurseBladeQuest
 Set Curse to 11
Endif

End

 

I don't think there is any benefit to splitting the script up into so many sections of 'if' s, the game still has to try to read each one to determine if they are valid. they game isn't that different from people - if it's easy for you to understand and quick for you to read and find the relevant action it should be the same for the game.

fQuestTimeDelay is used to ensure that scripts process fast enough for certain actions. Given the nature of what you're doing it can be used to slow it down. Will it hurt if the spell isn't changed for a second after the sacrifice? or 2 or 3 even?

 

I'm extremely new to modding, so I may of made so stupid mistake. Hopefully someone else with more experience can confirm or correct it

Link to comment
Share on other sites

You're not making a huge mistake, it's just that - or at least it's what I was told - the If script will be read thoroughly, unless there is a return command somewhere inside it, in which case it will return to the beginning,

 

So basically, 10 split « if » clusters using return commands will weigh less on the engine than a whole paragraph. On the other hand, of course, so many split clusters, each with their return commands, can complicate things...

 

Anyway, I'm presently reading about the CS and globals and stuff, your help is really appreciated : )

Link to comment
Share on other sites

The number of If blocks doesn't matter, so long as they are optimized and don't run too often.

 

I think the problem with HeartSacrifice is that you have actually created two separate variables, both called "HeartSacrifice". Even though they have the same name, the engine recognises them as 2 different values, as they are in 2 separate scripts.

 

To fix this, you must turn HeartSacrifice into one of 2 things:

 

A) Cross-Script Variables

B) Global Variable

 

 

A Cross Script Variable is just a variable from another script, generally a quest script. Here is an example of how it works:

 

 

 

 

First, a quest script with the variable you want. The Quest is called "Quest" (this is important)

 

Scn QuestSCRIPT

Short RunObjectScript

Begin GameMode

If Player.GetEquipped AlloThalassianStiletto
    Set RunObjectScript to 1
endif

End

 

Second is an object script that runs automatically.

 

Scn ObjectSCRIPT

Short RunNow

Begin GameMode

Set RunNow to Quest.RunObjectScript                     ;You have the name of the quest, the "." and the name of the variable. The game now recognises this variable.

If RunNow == 0
    Return
Else
    Player.UnequipItem AlloThalassianStiletto
    Set Quest.RunObjectScript to 0
endif

End

 

 

 

 

Alternatively, you can use a global variable. It is not tied to any script, and simply acts as a variable across all scripts (like timescale). To create a global variable, find "Gameplay" at the top of the screen and click on it, then click "Globals". From there you right click and hit "new".

All scripts will now work as if you had declared that variable at the start of the script. It will have the same value across all scripts.

Link to comment
Share on other sites

what scripts did you finally use? If you don't mind I'd like to use them... I'm thinking a staff that can close any oblivion gate you enter. I figure if you've sacrificed enough daedra hearts you deserve it :D
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...