Jump to content

Scripts...


cfh85

Recommended Posts

As part of what will be a fair size mod I'm altering some door controls. Mainly for "Evil/Naughty" guilds.

I don't think it's right you should be able to enter the thieves guild HQ or Dark sanctuary if you have a bounty and are detected by someone hostile.

Ideally I would like to set it so you can never use these doors if you're detected by a guard (with or without a bounty), if you have a bounty and are detected by someone with a high responsibility, or if you're in combat (for the thieves guild atleast, maybe the DB wont mind you bringing them people to kill.

 

My current script is

Begin OnActivate

If (Player.IsActorDetected == 0) || (player.GetCrimeGold == 0)

Activate

else

Message "Someone is watching"

EndIf

End

 

Add an "in combat" function is easy, but I've no idea how to tell who's detecting me

 

Any suggestions??

Link to comment
Share on other sites

it uses || because it's okay to enter as long as either you're not detected OR you have no bounty.

 

Also I use Player.IsActorDetected to see if the player is detected. I want to know who has detected the player. If the PC is trying to enter the guild HQ with a bounty but is seen by another guild member then that shouldn't matter, or if it's a companion.

 

maybe using IsInCombat as a bit of a workaround.

 

this would mean the PC can enter the guilds with a bounty and detected as long as PC is not in combat - Guards will try to arrest you and then attack you if they detect you with a bounty.

 

 

So what I really want is a way to detect the Faction or actorID of whoever can detect the PC.

 

also as part of another script, any ideas on how to alter the damage done by arrows using a script? or a regular weapon?

 

I'm just after the basic function (there are loads to try to sort through :( ) not a complete script.

Link to comment
Share on other sites

Finding who can detect the player is a problem that plagued me too, even with the advantages of OBSE. I did figure it out, using an array containing all actors in a cell so that I could use (getdetected player) on each of them.

I couldnt find anything simpler. If you do, let me know :)

 

Modifying weapon damage also requires OBSE, or you could make copies of the weapon in the CS, each with slightly higher damage. Then, swap them out when need be.

With OBSE, just call ModAttackDamage.

 

@Scarycave

Getdetected works to see if the calling reference can detect the actor parameter. IsActorDetected returns whether the calling reference is detected by anyone.

Edited by WarRatsG
Link to comment
Share on other sites

an array??

I've seen references to them but I don't have the first clue? would this have much of an effect on game speed? I don't think I'd be a problem for doors but, there is other situations where this would come in useful

Link to comment
Share on other sites

An array is basically a database. You can put hundreds of variables into an array variable, and access each one individually with the correct key. For example:

 

 

 

Array_Var MyArray

Ref Someone

Begin GameMode

Let MyArray := ar_Construct Array            ;Array must be initialised first, either with this command or a function that returns an array.

Let MyArray[0] := PlayerRef                 ;The array is called MyArray. The key is 0. The Value is the player.

Let Someone := MyArray[0]                ;Someone == Player
Someone.AddItem f 1000000000         ;Add 1000000000 gold to "someone", the player.

End

 

 

 

You need to know that arrays will not work with "Set" and "If" commands on their own - You must use "Let" and "Eval", like this:

Let MyArray := ar_Construct Array        ;"Let x := y" is the same as saying "Set x to y"

If Eval MyArray[0] == 1                ;Notice both If AND Eval are used. Eval just allows OBSE expressions to be used.

 

Also the keys within arrays (regular arrays, not stringmap or map arrays) start at 0, then work up the way.

For a list of functions for arrays, look here.

 

 

Ok, condensed explanation of arrays is over. Down to scripting 8)

 

 

All you need to do is use the function "GetHighActors", as in:

 

Let MyArray := GetHighActors

 

This returns all actors with High-level AI processing. This automatically includes all the actors in the cell. After that, it's just a matter of checking if any of those actors can detect the player.

 

I will write you a script fragment, for you to merge into your script. I will let you figure out how to do it ;)

 

 

 

Array_var Actors                                    ;Array_Var = Array Variable
Ref TempRef                                          ;The actor being evaluated

Short Key                                             ;The array key currently being used
Short detected                                       ;You'll see what I mean.

Begin OnActivate

Let Actors := GetHighActors                  ;Returns actors in the cell, and all other actors with High-level AI processing.
Let Key := ar_Size Actors                     ;Returns how many variables are in the array.

While Key > 0                                      ;"While Loops" will repeat so long as the expression is true. In this case, this will repeat as long as "Key" is over 0.

    Let Key -= 1                                    ; "-=" means subtract and assign. "Let x -= y" means "Set x to (x - y)"
                  
    Let TempRef := Actors[Key]

    If TempRef.GetDetected Player == 0                ;Returns 1 if the calling reference can detect the player.
         Continue                                           ;Continue is like a return, but for a while loop. The script will go back up to "While Key > 0"
    ElseIf
         ;;;Any other checks.

         ;;;If player passes all checks
              Continue
         ;;;If Player fails a check
              Set Detected to 1                                 ;Would rather avoid calling Activate in this part. I have a feeling it may be a little unstable to change cells during a while loop.
              Break                                                  ;Ends the loop immediately, no point in checking anyone else.
         endif

    endif

Loop                                                                

Let Actors := ar_Null                                           ;Clean up the array, to avoid keeping unneeded data.

If Detected == 1
    MessageBox "you are being watched"
    Set Detected to 0
Else
    Activate
endif

End

 

 

 

I hope that's enough comments for you to get an idea of what I am trying to do :)

 

 

As for your question, they will only slow down the game a lot if you over-use them.

Edited by WarRatsG
Link to comment
Share on other sites

What I've got now is this

 

 

Scriptname 000CFHTGDoorScript


Array_var Actors                                    ;Array_Var = Array Variable
Ref TempRef                                          ;The actor being evaluated

Short Key                                             ;The array key currently being used
Short detected                                       ;You'll see what I mean.

Begin OnActivate
If (Player.IsActorDetected == 1)
	Let Actors := GetHighActors                  ;Returns actors in the cell, and all other actors with High-level AI processing.
	Let Key := ar_Size Actors                     ;Returns how many variables are in the array.

	While Key > 0                                      ;"While Loops" will repeat so long as the expression is true. In this case, this will repeat as long as "Key" is over 0.

	Let Key -= 1                                    ; "-=" means subtract and assign. "Let x -= y" means "Set x to (x - y)"
          
	Let TempRef := Actors[Key]

	If TempRef.GetDetected Player == 0                ;Returns 1 if the calling reference can detect the player.
		Continue                                           ;Continue is like a return, but for a while loop. The script will go back up to "While Key > 0"
	ElseIf (TempRef.GetInFaction ThievesGuild == 1) || (TempRef.GetInFaction Beggars == 1) || (TempRef.GetInFaction PlayerFaction == 1)
		Continue
	Else	;;;If Player fails a check
		Set Detected to 1                                 ;Would rather avoid calling Activate in this part. I have a feeling it may be a little unstable to change cells during a while loop.
		Break                                                  ;Ends the loop immediately, no point in checking anyone else.
	endif

	Loop

Else
	Set Detected to 0
endif

Let Actors := ar_Null                                           ;Clean up the array, to avoid keeping unneeded data.

If Detected == 1
	MessageBox "You are being watched"
	Set Detected to 0
Else
	Activate
endif

End

 

 

I decided to leave out the bounty. I figured you should never be seen by people you can't trust. I've got a similar one for the DB only they got loads of factions. Also in my mod will be a safehouse in each city. TG owned and extremely basic inside, only food, bed, table. The door is scripted so that after entering, in 3 days your bounty is gone (as long as it's not too high). I may add this script into it as atm you can't enter if you're detected at all but this would make more sense.

 

Thanks for your help. Your name is now the first one on my credits list :D

Edited by cfh85
Link to comment
Share on other sites

Your code looks good. The only thing that could possibly need fixing is the indentation of the While-Loop. It works the exact same way as If-Endif, as in:

 

While X > Y
    Let X -= 1
Loop

 

I'm just glad to have been able to help you out. I hope you've learned some useful code 8)

 

 

PS: Just noticed your quest started with a number. That causes problems for some people, but not everyone. I know this because I tried naming a quest with the prefix 01, only the quest didn't work at all until I changed it to start with AA instead.

 

Just as a heads up in case something doesn't seem to be working right and nothing seems to fix it ;)

Edited by WarRatsG
Link to comment
Share on other sites

  • Recently Browsing   0 members

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