Jump to content

[LE] I need help with my skyrim script


Shockyyy

Recommended Posts

So I am a beginner in coding things, but I spent a whole day writing this script and trying to get it to work, it works in some way, but not fully. The main idea for the script is kind of simple: When I press a specific key on my keyboard it must spawn the creature, which i binded for this key. Also I wrote in the beginning that game will show a message when I load a save or start a new game. I compiled the script, it said that everything compiled succesfully and without any troubles. Then I opened the Creation Kit and selected Skyrim.esm and Update.esm as a master files and added a new quest, and in the quest properties I added my script and just saved it. Everything seemed fine, but the thing is that it shows the message when i load save or start a new game, but it doesn't spawn any creatures that i binded. I just don't know what I should do, but I have a feeling that I did something wrong in creation kit. Please help me, I just want to get this thing to work. (I attached the script file and also wrote it in this spoiler)

 

 

ScriptName SkyrimShockyMod extends Quest

; This Player reference is set as a property for this quest in Creation Kit
Actor Property PlayerRef Auto
FormList Property EnemyRacesList Auto
FormList Property WeaponsList Auto

float lastWeaponChangeTime = 0.0
	
Event OnInit()
	Debug.MessageBox("Less gooo")
	RegisterForSingleUpdate(5)

	; Keycodes: https://www.creationkit.com/index.php?title=Input_Script#DXScanCodes
	RegisterForKey(21) ;Y 
	RegisterForKey(79) ;Numpad1
	RegisterForKey(80) ;Numpad2
	RegisterForKey(81) ;Numpad3
	RegisterForKey(75) ;Numpad4
	RegisterForKey(76) ;Numpad5 
	RegisterForKey(77) ;Numpad6
	RegisterForKey(71) ;Numpad7
	RegisterForKey(72) ;Numpad8
	RegisterForKey(73) ;Numpad9
EndEvent

Event OnUpdate()

	; ; SET PLAYER TO RANDOM SIZE
	; float randomScale = getRandomScale()
	; PlayerRef.SetScale(randomScale)

	; ; SET RANDOM SPEED
	; float randomSpeed = utility.randomFloat(100, 3000)
	; PlayerRef.SetActorValue("SpeedMult", randomSpeed)
	; ; Temporarily modify the carryweight so that the Speed change immediately takes place
	; PlayerRef.ModActorValue("CarryWeight",0.1)
	; PlayerRef.ModActorValue("CarryWeight",-0.1)

	; ; SPAWN HORKER
	; PlayerRef.PlaceAtMe(Game.GetForm(0x00023ab1))

	; ; SPAWN RABBIT
	; PlayerRef.PlaceAtMe(Game.GetForm(0x0006DC9D))

	; ; SPAWN BEAR
	; PlayerRef.PlaceAtMe(Game.GetForm(0x00023A8A))

	; ; SPAWN CHEESE WHEEL
	 spawnItemsAtPlayer(Game.GetForm(0x00064B33), 10)
	; ; Alt Version:
	; spawnInFrontOfPlayer(Game.GetForm(0x00064B33), 15, 150, 50, 20)

	; ; SPAWN CHICKEN
	; PlayerRef.PlaceAtMe(Game.GetForm(0x000A91A0))

	; ; SPAWN RANDOM UNIT
	; spawnRandomUnit()

	RegisterForSingleUpdate(1)
EndEvent

Function RegisterForKey(int keyCode) native

Event OnKeyDown (int keyCode)
	if (KeyCode == 21) ;Y
		; SPAWN MAMMOTHS
		PlayerRef.PlaceAtMe(Game.GetForm(0x0001CA03), 10)
	elseif (KeyCode == 79) ;Numpad1
		; SPAWN CHEESE
		spawnItemsAtPlayer(Game.GetForm(0x00064B33), 10)
	elseif (KeyCode == 80) ;Numpad2
		; SPAWN DRAGON
		PlayerRef.PlaceAtMe(Game.GetForm(0x0001CA03), 10)
	elseif (KeyCode == 81) ;Numpad3
		; SPAWN BEAR
		PlayerRef.PlaceAtMe(Game.GetForm(0x00023A8A), 10) 
	elseif (KeyCode == 75) ;Numpad4
		; SPAWN GIANT
		PlayerRef.PlaceAtMe(Game.GetForm(0x00023AAE), 10)
	elseif (KeyCode == 76) ;Numpad5
		; SPAWN MUDCRAB
		PlayerRef.PlaceAtMe(Game.GetForm(0x000E4011), 10)
	elseif (KeyCode == 77) ;Numpad6
		; SPAWN WOLF
		PlayerRef.PlaceAtMe(Game.GetForm(0x00023ABE), 10)
	elseif (KeyCode == 71) ;Numpad7
		; SPAWN NAZEEM
		PlayerRef.PlaceAtMe(Game.GetForm(0x00013BBF), 10)
	elseif (KeyCode == 72) ;Numpad8
		; SPAWN BANDIT
		PlayerRef.PlaceAtMe(Game.GetForm(0x000D80B4), 10)
	elseif (KeyCode == 73) ;Numpad9
		; SPAWN TROLL
		PlayerRef.PlaceAtMe(Game.GetForm(0x00023ABA), 10) 
	endif
EndEvent

float Function getRandomScale() global
	; first, 50/50 chance of making him bigger or smaller
	; Then, get random value within bigger/smaller's respective range
	if (Utility.RandomInt(0,1))
		; Make it smaller
		return Utility.RandomFloat(0.1, 1.0)
	else
		; Make it bigger 
		return Utility.RandomFloat(1.0, 10.0)
	endif
endFunction

Function spawnItemsAtPlayer(Form itemForm, int spawnCount = 1)
	while (spawnCount > 0)
		PlayerRef.AddItem(itemForm, 1, true)
		PlayerRef.DropObject(itemForm, 1)
		spawnCount -= 1 
	endWhile
EndFunction

Function spawnInFrontOfPlayer(Form formToPlace, int spawnCount = 1, \ 
							   float distanceOffset = 250.0, float heightOffset = 25.0, float angleOffset = 0.0 )
	; Spawn a disabled cheese wheel, move it in front of player, spawn Form(s) at that location, then delete
	; horizontalOffset is how far from player it spawns, verticalOffset is how high, angle is the offset from player's current
	ObjectReference invisibleSpawner = PlayerRef.PlaceAtMe(Game.GetForm(0x00064B33), 1, true, true)
	float playerAngleZ = PlayerRef.GetAngleZ()
	float angZ = playerAngleZ + angleOffset
	float posX = PlayerRef.GetPositionX() + distanceOffset * Math.Sin(angZ)
	float posY = PlayerRef.GetPositionY() + distanceOffset * Math.Cos(angZ)
	float posZ = PlayerRef.GetPositionZ() + heightOffset
	invisibleSpawner.SetPosition(posX, posY, posZ)
	invisibleSpawner.PlaceAtMe(formToPlace, spawnCount, True, False)
	invisibleSpawner.Delete()
EndFunction

FUNCTION spawnRandomUnit()
	; This occurs OnUpdate so changes can be made after plugin is first loaded. Trading optimization for flexability.
	; Create the array of IDs. Array size cannot be a variable, since it must be defined at compile time.
	int[] randomUnitIDs = new int[38]

	; Manually populace the array (no better solution found for now)
	randomUnitIDs[0] = ID_CHICKEN
	randomUnitIDs[1] = ID_DOG
	randomUnitIDs[2] = ID_COW
	randomUnitIDs[3] = ID_GOAT
	randomUnitIDs[4] = ID_HORSE
	randomUnitIDs[5] = ID_RABBIT
	randomUnitIDs[6] = ID_MUDCRAB_SMALL
	randomUnitIDs[7] = ID_MUDCRAB_MED
	randomUnitIDs[8] = ID_MUDCRAB_LARGE
	randomUnitIDs[9] = ID_HORKER
	randomUnitIDs[10] = ID_BEAR
	randomUnitIDs[11] = ID_CHAURUS
	randomUnitIDs[12] = ID_SNOWBEAR
	randomUnitIDs[13] = ID_WOLF
	randomUnitIDs[14] = ID_ICEWOLF
	randomUnitIDs[15] = ID_SABRECAT
	randomUnitIDs[16] = ID_SNOWYSABRECAT
	randomUnitIDs[17] = ID_SKEEVER
	randomUnitIDs[18] = ID_ICEWRAITH
	randomUnitIDs[19] = ID_WEREWOLF
	randomUnitIDs[20] = ID_TROLL
	randomUnitIDs[21] = ID_FROSTTROLL
	randomUnitIDs[22] = ID_MAMMOTH
	randomUnitIDs[23] = ID_DRAGON
	randomUnitIDs[24] = ID_DRAUGR
	randomUnitIDs[25] = ID_RESTLESSDRAUGR
	randomUnitIDs[26] = ID_DRAUGROVERLORD
	randomUnitIDs[27] = ID_DWARVENSPHERE
	randomUnitIDs[28] = ID_FROSTBITESPIDER
	randomUnitIDs[29] = ID_GIANT
	randomUnitIDs[30] = ID_HAGRAVEN
	randomUnitIDs[31] = ID_SHADE
	randomUnitIDs[32] = ID_SKELETON
	randomUnitIDs[33] = ID_SKELETONARCHER
	randomUnitIDs[34] = ID_SKELETONMAGE
	randomUnitIDs[35] = ID_SPRIGGAN
	randomUnitIDs[36] = ID_WISP
	randomUnitIDs[37] = ID_NAZEEM

	int randomIndex = utility.randomInt(0, randomUnitIDs.Length - 1)
	int randomUnitID = randomUnitIDs[randomIndex]
	ObjectReference newUnit = PlayerRef.PlaceAtMe(Game.GetForm(randomUnitID))
	; newUnit.SetScale(getRandomScale())
endFUNCTION 

; UPDATE THE "randomUnitIDs" ARRAY INIT SIZE WHEN ADDING/REMOVING UNITS
int ID_CHICKEN = 0x000A91A0
int ID_DOG = 0x00023A92
int ID_COW = 0x00023A90
int ID_GOAT = 0x0002EBE2
int ID_HORSE = 0x0010982B
int ID_RABBIT = 0x0006DC9D
int ID_MUDCRAB_SMALL = 0x000E4010
int ID_MUDCRAB_MED = 0x000E4011
int ID_MUDCRAB_LARGE = 0X00021875
int ID_HORKER = 0x00021ab1
int ID_BEAR = 0x00023A8A
int ID_CHAURUS = 0x000D0872
int ID_SNOWBEAR = 0x00023A8C
int ID_WOLF = 0x00023ABE
int ID_ICEWOLF = 0x00023ABF
int ID_SABRECAT = 0x00023AB5
int ID_SNOWYSABRECAT = 0x00023AB6
int ID_SKEEVER = 0x00023AB7
int ID_ICEWRAITH = 0x00023AB3
int ID_WEREWOLF = 0x00023ABC
int ID_TROLL = 0x00023ABA
int ID_FROSTTROLL = 0x00023ABB
int ID_MAMMOTH = 0x00023AB4
int ID_DRAGON = 0x000F80FA
int ID_DRAUGR = 0x000387C0
int ID_RESTLESSDRAUGR = 0x0001FE86
int ID_DRAUGROVERLORD = 0x0001BCD6
int ID_DWARVENSPHERE = 0x000EEC5E
int ID_FROSTBITESPIDER = 0x0004203F
int ID_GIANT = 0x00023AAE
int ID_HAGRAVEN = 0x00023AB0
int ID_SHADE = 0x0009CB63
int ID_SKELETON = 0x0002D1DE
int ID_SKELETONARCHER = 0x0002D1FC
int ID_SKELETONMAGE = 0x0009362B
int ID_SPRIGGAN = 0x00023AB9
int ID_WISP = 0x00002C3C7
int ID_NAZEEM = 0x00013BBF 

 

 

Edited by Shockyyy
Link to comment
Share on other sites

For the OnKeyDown instead of using Game.GetForm I would just use the properties directly, same for the spawnRandomUnit function. For this you can use a formlist filled with actor bases, that way you can keep it dynamic. For actors, use PlaceActorAtMe(ActorBase) instead of PlaceAtMe:

Formlist Property MyActorBases Auto

FUNCTION spawnRandomUnit()
    int randomIndex = utility.randomInt(0, MyActorBases.GetSize() - 1)
    ObjectReference newUnit = PlayerRef.PlaceActorAtMe(MyActorBases.GetAt(randomIndex) as ActorBase)
    ; newUnit.SetScale(getRandomScale())
endFUNCTION 

 

Also, make sure your properties are filled. In the CK, click on your script, click on the Properties button and click Auto Fill All. If they are named the same in the script as in the CK they will automatically set. Otherwise you can set them manually by clicking on the property and then Edit Value.

Link to comment
Share on other sites

I did the Auto Fill thing and it worked! (Thank you) But not at all, it turned on this line to spawn cheese every second:

; ; SPAWN CHEESE WHEEL
	 spawnItemsAtPlayer(Game.GetForm(0x00064B33), 10)

But the binds for spawning still didn't work. Also I didn't fully understand you with this replacing Game.GetForm thing. What should I do with it? And about that spawnRandomUnit, I don't really use it, I just need the spawn thing to work.

Edited by Shockyyy
Link to comment
Share on other sites

So to do properties directly you would do something like this. Again for actors use PlaceActorAtMe. Since that function doesn't have an amount, it only places 1 actor, you could set up another function to place multiple actors:

 

Actorbase Property EncMammothWild Auto 

Event OnKeyDown (int keyCode)
    if (KeyCode == 21) ;Y
        ; SPAWN MAMMOTHS
        PlaceMultipleActorAtMe(PlayerRef, EncMammothWild, 10) ;place 10 mamoths at player.
    Endif
EndEvent

Function PlaceMultipleActorAtMe(ObjectReference Ref, Actorbase akActorBase, Int Amount) 
    While Amount > 0 
        Ref.PlaceActorAtMe(akActorBase) 
        Amount -= 1 
    EndWhile 
EndFunction

You could also use a formlist. Drag and drop the actors or items you want to spawn into a new formlist (found in the miscellaneous section of the CK). Then do something like this:

Formlist Property MyItems Auto 

Event OnKeyDown (int keyCode)
    if (KeyCode == 21) ;Y
        ; SPAWN MAMMOTHS
        PlaceMultipleAtMe(PlayerRef, MyItems.GetAt(0), 10) ;Place 10 items at the player that's index 0 of the formlist
    elseif (KeyCode == 79) ;Numpad1
        ; SPAWN CHEESE
        PlaceMultipleAtMe(PlayerRef, MyItems.GetAt(1), 10) ;Place 10 items at the player that's index 1 of the formlist
    Endif
EndEvent

Function PlaceMultipleAtMe(ObjectReference Ref, Form Item, Int Amount) 
    If Item As ActorBase ;is the item an actor?
        Actorbase akActorBase = Item as ActorBase
        While Amount > 0 
            Ref.PlaceActorAtMe(akActorBase) 
            Amount -= 1 ;subract 1 from amount. While loop will repeat until amount is 0.
        EndWhile 
    Else 
        Ref.PlaceAtMe(Item, Amount)
    Endif 
EndFunction

I changed the function so that it will detect actor bases automatically.

Link to comment
Share on other sites

...I spent a whole day writing this script and trying to get it to work, it works in some way, but not fully.

 

It's a long time since I wrote scripts, but one thing I do know is that you MUST test the script on a saved game file that has never seen your mod. Trying to fix a script and re-testing on a save that has the old version baked in won't work. I learned this at a great cost of time and frustration and several clumps of hair!

 

:smile:

Link to comment
Share on other sites

I know why your script was spawning cheese every second. In the OnInit event you register for an update after 5 seconds. In the OnUpdate event you've commented out every line but spawning the cheese and re-registering for an update after 1 second. So... every second it will spawn cheese.

 

If it is still on your script, remove the following line as it is overriding the SKSE variant.

Function RegisterForKey(int keyCode) native

With that line in your script, you'll never get your keys properly registered.

Link to comment
Share on other sites

I know why your script was spawning cheese every second.

And I know it too. It is just another function that I decided to do and it works perfectly.

About Function RegisterForKey: If I delete that line then the script will not compile. It says that RegisterForKey is not a function or does not exist.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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