cfh85 Posted June 7, 2012 Share Posted June 7, 2012 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 isBegin OnActivate If (Player.IsActorDetected == 0) || (player.GetCrimeGold == 0) Activate else Message "Someone is watching" EndIfEnd 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 More sharing options...
scarycave Posted June 7, 2012 Share Posted June 7, 2012 (edited) Straight off the construction wiki:GetDetected player Returns 1 if the actor is detected. You may want to change || to && Edited June 7, 2012 by scarycave Link to comment Share on other sites More sharing options...
cfh85 Posted June 8, 2012 Author Share Posted June 8, 2012 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 More sharing options...
WarRatsG Posted June 8, 2012 Share Posted June 8, 2012 (edited) 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. @ScarycaveGetdetected works to see if the calling reference can detect the actor parameter. IsActorDetected returns whether the calling reference is detected by anyone. Edited June 8, 2012 by WarRatsG Link to comment Share on other sites More sharing options...
cfh85 Posted June 9, 2012 Author Share Posted June 9, 2012 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 More sharing options...
WarRatsG Posted June 11, 2012 Share Posted June 11, 2012 (edited) 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 June 11, 2012 by WarRatsG Link to comment Share on other sites More sharing options...
cfh85 Posted June 11, 2012 Author Share Posted June 11, 2012 (edited) 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 June 11, 2012 by cfh85 Link to comment Share on other sites More sharing options...
WarRatsG Posted June 11, 2012 Share Posted June 11, 2012 (edited) 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 June 11, 2012 by WarRatsG Link to comment Share on other sites More sharing options...
Recommended Posts