Code Monkey home page Code Monkey logo

xobse's Introduction

GitHub release (latest by date) Appveyor Build status

MSBuild Release

This is a community maintained up-to-date fork of Oblivion Script Extender (OBSE).

Download

Download the latest OBSE

Changelogs and all releases are provided in the releases section.

Installation

The instructions for installing and running OBSE differ based on whether you are using a retail or Steam version of the game.

IF YOU PURCHASED A RETAIL (NON-STEAM) VERSION OF OBLIVION:

  1. Copy obse_1_2_416.dll, obse_editor_1_2.dll, obse_loader.exe and the Data folder to your Oblivion directory. This is usually in your Program Files folder, and should contain files called "Oblivion.exe" and "OblivionLauncher.exe".
  2. Run oblivion by running obse_loader.exe from the Oblivion directory.

If you use a desktop shortcut to launch Oblivion normally, just update the shortcut to point to obse_loader.exe instead of oblivion.exe.

IF YOU ARE USING THE STEAM VERSION OF OBLIVION:

  1. Copy obse_1_2_416.dll, obse_editor_1_2.dll, obse_steam_loader.dll and the Data folder to your Oblivion directory. This is usually "C:\Program Files\Valve\Steam\SteamApps\common\oblivion".
  2. Launch Oblivion via Steam or by running Oblivion.exe. OBSE will automatically be run along with Oblivion when launched. To disable this, rename or move obse_steam_loader.dll. You do not need to use obse_loader.exe unless you are running the editor.

IF USING STEAM PROTON ON LINUX (replace Point 2. from previous paragraph):

  1. Backup OblivionLauncher.exe and rename obse_loader.exe to OblivionLauncher.exe
  2. Start the game from inside Steam Note this is needed only when using a Linux Steam and Proton. Using Windows Steam inside Wine should work out of the box,

IF YOU ARE USING MOD ORGANIZER 2:

Mod organizer user need to use special instruction to allow OBSE to function properly. Follow the instruction on this page: https://github.com/ModOrganizer2/modorganizer/wiki/Running-Oblivion-OBSE-with-MO2

RUNNING TES:CONSTRUCTION SET WITH OBSE:

Scripts written with these new commands must be written via the TESConstructionSet launched with obse_loader. Open a command prompt window, navigate to your oblivion install folder, and type "obse_loader -editor". The normal editor can open plugins with these extended scripts fine, it just can't recompile them and will give errors if you try.

WARNING: It's unadvised to install Oblivion to Program Files

Support

More information on running Oblivion and OBSE with Linux and Wine (or Proton) can be found on the UESP Oblivion Linux page. It should work out of the box for most people.

For support, contact us in the xOBSE Discord server. For bug reports and other problems, create a new GitHub issue.

As this is a community supported release don't report to the original programmers bugs that are present within this fork.

Description

Oblivion Script Extender (OBSE) is a modder's resource that expands the scripting capabilities of The Elder Scroll 4: Oblivion. It does so without modifying the executable files on disk, so there are no permanent side effects.

For documentation on how to write scripts utilizing OBSE , see CS Wiki and obse_command_doc.html .

Creating OBSE Plugins (for developers)

To create an OBSE plugin you may want to look the example project. If the plugin you want to create define commands you need to request an opcode range to use. Reach us on the Discord server.

Here there is a list of already allocated ranges.

FAQ / Troubleshooting

Can I update OBSE mid play-through?

  • Yes, and you are encouraged to do so.

My antivirus says there's a virus in obse_loader.exe, what's that about?

  • That's a false positive. We already contacted Microsoft about it but it will likely happen again in the future, so you need to add the file to exclusions of your AV.

Are old mods/plugins still compatible?

  • Yes. We keep a focus on backwards compatibility with precedent mods and plugins. Despite that a beta may introduce unintendend errors that we will try to rectify as soon as possible.

Oblivion doesn't launch after running obse_loader.exe:

  • Make sure you've copied the OBSE files to your oblivion folder. That folder should also contain oblivion.exe.
  • Check the file obse_loader.log in your oblivion folder for errors.

obse_loader.log tells me it couldn't find a checksum:

  • You may have a version of Oblivion that isn't supported. I have the english official patch v1.2.0.416. Localized versions with different executables or different patches may not work, but many have been successful. If there's enough legitimate demand for it, I can add support for other versions in the future.
  • Your Oblivion install may be corrupt. Hacks or no-cd patches may also change the checksum of the game, making it impossible to detect the installed version.
  • In case this happen create a new GitHub issue

The OBSE loader tells me I need to use the autopatcher:

  • Go to to OBSE website (http://obse.silverlock.org) and download autopatcher, which will walk you through the update process. You will need the latest patch from Bethesda, as well as your original Oblivion DVD.

OBSE doesn't launch with the Direct2Drive version:

  • The Direct2Drive version of the Oblivion executable has additional DRM applied, which would be illegal for us to bypass. We cannot support this version. If you own a retail version of Oblivion, please use the autopatcher to extract a usable executable.
  • Note that if you are interested in buying a digitally distributed version of Oblivion, the GOG version and the Steam version are supported. (GOG Version preferred)

Crashes or other strange behavior:

  • Let me know how you made it crash, and I'll see about fixing it.

Xbox 360 or PS3 version?

  • Impossible.

Running OBSE and Oldblivion at the same time:

  • Copy your oldblivion support files in to the Oblivion folder (oldblivion.dll, oldblivion.cfg, shaders.sdp), then run the loader with the -old command argument.

How do I change the script editor font?

  • Hold F12 or F12 while opening the script editor. F12 will default to Lucida Console 9pt, and F11 will show a font picker dialog box.

Can I modify and release my own version of OBSE based on the released source code?

  • This is highly discouraged. Each command must be assigned a unique and constant opcode from 0x1000-0x7FFF. Bethesda started adding commands at 0x1000, and OBSE started adding at 0x1400. If you add new commands yourself, they may conflict with later releases of OBSE. The suggested method for extending OBSE is to write a plugin. If this does not meet your needs, please email the contact addresses listed below. If you want a feature directly inside OBSE, or want to work improving OBSE, contribution can be done by forking the repository, and opening a Pull Request. Acceptance of the pull request is conditioned to a review.

How do I write a plugin for OBSE?

  • Start with the obse_plugin_example project in the OBSE source distribution. Currently the documentation for the plugin API can be found in the source distribution under obse/obse/PluginAPI.h. Note that due to the opcode allocation issues discussed above, you will need to request an opcode range for your plugin by emailing the contact addresses at the bottom of the readme. Also note that plugins must have their source code available. The OBSE team has spent a very long time developing and documenting the interface to Oblivion's internals, so we request that plugin developers also share their findings with the public. This will also help us make sure that we keep Oblivion as stable as possible even when using third-party plugins.

How do I use OBSE with 3D Analyze?

  • Run normal Oblivion with 3DA once, then quit. Set up any configuration options you need at this point. This should create a config_DX.ini file in the Oblivion folder. Then, copy dat3.000 from the 3DA folder in to the Oblivion folder as well, and rename it to d3d9.dll. This makes Oblivion use 3DA all the time, so now just use obse_loader.exe like normal. If you buy an actual video card and want to disable 3DA, delete the new d3d9.dll from the Oblivion folder.

I'm using the Steam version of Oblivion and OBSE doesn't seem to be working:

  • Go to your Steam Settings page, pick the "In-game" tab, and make sure the "Enable Steam Community In-Game" box is checked.
  • Sometimes even with the In Game overlay active the Steam version of Oblivion may fail to load the obse_steam_loader.dll. Starting steam as admin may resolve it.
  • A more reliable mechanism may be provided in the future

Credits

OBSE was created and maintained by Ian Patterson, Stephen Abel, Paul Connelly, and Madeesh Kannan (ianpatt, behippo, scruggsywuggsy the ferret, and shadeMe)

Additional contributions from Timeslip, The J, DragoonWraith, SkyRanger-1, badhair, JRoush and kyoma.

The home page for OBSE is http://obse.silverlock.org/

This version is maintained by llde and shadeMe

Thanks

Thanks to the xNVSE people korri123 (aka Kormákur), lStewieAl, jazzisparis, iranrmrf, maletsna (c6), and carxt (aka karut) that with their fork inspired me to take over this

Thanks to Ershin (Oblivion Display Tweaks, Loot Menu) that reported a serious bug in the Event Framework

Thanks to Laulajatar and KatAwful for documentation fixes and help with bug reports

Thanks to EchoEclipseWolf for decoding bits

Thanks to all people who reported bugs.

A special thanks to ianpatt that allowed us to mantain this fork.

xobse's People

Contributors

ashemedai avatar calebtt avatar echoeclipsewolf avatar fox2code avatar ir4ne avatar kuroko137 avatar laulajatar avatar llde avatar lordnyriox avatar shademe avatar yemowtronoc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xobse's Issues

OnInit script block

Begin OnInit <optional: initMode>
   ; modes: 1 - once per script, 2 - per session load, 3 - per game load
   ; initialize script/variables here
End

Temporary variables

Are resetted every game load (newgames/savegame load/ game restart)

requested by forli

sv_Replace issue

From QQuix post:

Investigating a report from forli, I’ve found something weird with sv_replace related to replacing %’s:

let s := ">> 0%%<<"
sv_Replace " 0%%%%|OO" s
print s ; OK – prints “>>OO<<”
printc $s ; OK – prints “>>OO<<”

but
let s := ">> 0%%<<"
sv_Replace " 0%%|OO" s
print s ; prints “>>OO<<”
printc $s ; ERROR “Too few args for format specifier”

Since it complained about too few args, I tried adding a dummy arg and it did not throw the error
printc $s 99 ; prints “>>OO<<”

But the result shouldn’t be “>>OO%<<”? ( as the last pair of % should be joined in a single % and not replaced)

The same problem occurs with sv_construct and MessageBoxEX.

My feeling is that, in the second example, sv_replace leaves an unprintable something in the string which Print does not care about, but commands that uses format strings do not like.

IsInventoryObject / CanBePickedUp

Considering this can be found out using currently-existing functions I guess it should be of really low priority, but it would be convenient. Specially because we can't make UDFs with optional parameters.

<bool> <reference>.IsInventoryObject <objectID:ref>

GetFirstRef/GetNextRef within While loops

According to documentation:

GetFirstRef - returns the first reference in the current cell. (Snip) This function should be used only within a Label...Goto loop and GetNextRef.

I haven't had any trouble after testing this within While loops in repeated occasions. Is there any reason for this to be meant to be used exclusively within a Label-Goto loop, or is that part of the documentation simply outdated?

Allow String_var in dialogues

Conversations, Topics and Response texts can only use dynamic strings when using GameSettings (and many mods like Enhanced Economy alter the GameSettings for this reason, but this may dangerous).
I wonder if OBSE could hook/patch the game code and make these texts support String_Var too.

Standardization of sourcecode

This source is passed beetween many hands, everyone with his style of programming.

We have inconsistences beetween how things are done: most of the time functions use pointers, sometime (as in HasSpell) use references, or difference about getting Actors* from TESObjectREFR*
sometimes directly casted ((Actor_)thisObj for example) other times a TESObjectREFR is dynamic-casted to Actor_.

@shadeMe I suggest that when possible we should review the various difference and adopt one of them as standard.
What do you think?

GetDisease is unimplemented

@shadeMe I saw various dialogue (expecially hellos) making use of GetDisease.
I know that it was never implemented for scripts. But it was implemented for dialogue condition?

Out-of-context format specifiers can cause CTDs

At least when formatted strings with some extended specifiers are passed as arguments to non-EX versions of functions such as MessageBox.

It would be convenient if the compiler were patched to disallow this but, if that is not worth the effort (because I am aware I'm talking about a consequence of misusing nearly fully deprecated functionality after all), adding a simple note in the docs would still help make people aware of this risk.

sv_IsNumber

Don't know why nobody ever requested this: is the passed string a number?

Currently we have 2 "string to number" commands:

  • sv_ToNumeric, which parse the string from left to right and stops as soon as it find an invalid char, then it returns the number read so far, and we don't know if the conversion succeed up to the end.
  • ToNumber / #, which return the number read (if succeed) or 0 if there's an invalid char, but the string may actually be exactly "0", so when it returns 0 we can't be sure it's an error.

So, both commands don't give clues about the result of the conversion, so we have to use a check like this one:
If Eval (strVar == $(#strVar))
If "#" conversion succeed, $ will return the original string. Only exception: it doesn't work if original string is "00" (or more zeroes), which is still a valid number. Also, a double ToNumber/ToString is an unnecessary waste of time.

Declaration and initialization of variables

I noticed the compiler doesn't complains when I type something like this:

scn someScript

Short someVar := 5
Float anotherVar := 4.25

The variables remain 0, so the assignments are ignored, but the compiler says nothing.
I even tried with other types, and it seems String_Var and/or Array_Var freeze the script at runtime.

You may make the complier recognize the error, but I have a better idea (if possible, of course): implements a working declaration+initialization as above. It could be useful for special variables like fQuestDelayTime.

GetBaseAV2 badly implemented.

I've read very old posts where people said it worked differently for them, but for me it seems to include fortify abilities just like GetBaseAV.

Precedence of parentheses during evaluation involving string literals

I suspect normal precedence rules may not even apply to quotation marks in general, but parentheses appear to behave as though they didn't precede them under some circumstances during evaluation. This isn't the case during assignment. It is also not the case for brackets.

Specifics

This compiles just fine:

if eval svTest == "( )"
  Let svTest := " )"
endif

On the other hand, the compiler complains about mismatched parentheses when I try anything like this:

if eval svTest == " )"
endif

I tested and confirmed this behaviour in CS, CS + OBSE, GameMode & Function blocks, with/without compiler override, and with/without eval.

I apologise in advance for the title's technical inaccuracy if it just so happens this has nothing to do with actual precedence rules. I also apologise if I made any mistakes as the GitHub newbie that I am.

Undocumented commands

These compile but aren't documented anywhere. I noticed SetPlayerSkeletonPath is in the wiki though, along with some other ones that aren't in the html command doc that is bundled in the archive. I'm going to try to list them up here later.

GetCurrentFrameIndex
SetPlayerSkeletonPath (I tested it only once in-game, it just CTD)

IsRagdolling

Would be nice to have an easy way to detect if an actor got into ragdoll state through PushActorAway. If GetKnockedState is incapable of detecting other situations where an actor is ragdolling, it might be a good idea to implement something more general, like an IsRagdoll function, to use it in conjunction with GetKnockedState when necessary.

Non-redirected functions passed as args to redirected functions are auto-redirected

Really sorry for the long title. It should be clear, though (I hope). When using this syntax to call a function...

ref.FunctionName <Expression(s)>

...any non-redirected function calls made as part of an OBSE expression and passed as arguments to that function are called on the same reference as the function in question (ref, in this case).

Example:

Let refVar := UrielSeptimRef
if GetSelf == PlayerRef
   refVar.Call SomeFunction (GetBaseObject)
   ;GetBaseObject in this context returns UrielSeptim, NOT Player.
endif

I guess for most people with an object-oriented programming background this is merely expected behaviour, but most modders don't have such a background. Redirecting function calls was already doable before OBSE, but it was the implementation of OBSE expressions that allowed modders to experience this behaviour, so I believe this is another bit of relevant info that is worth a mention in the docs. Perhaps in the existing section covering Considerations for using OBSE expressions.

GetFirstRef with form type filter ignores deleted references

As the title says, using GetFirstRef (and other cell scan commands) with a form type filter (other than 0/None) makes the command ignore references marked for deletion, but still not deleted.

Since altering this behaviour may alter the behaviour of existing scripts, I propose to add another optional parameter includeDeletedRefs:int, which allow the commands to include those references.

sv_ToNumeric doesn't accept array entries

Make sv_ToNumeric accept array entries as parameter (like "let MyNumber := sv_ToNumeric MyArray[0]" ). Currently accepts only string vars ("Let MyNumber := sv_ToNumeric MyString).

OnMurder-related question

Is there any known hook that could be used to fire the OnMurder event when the Kill function is called without passing the optional ActorID argument to it?

As it is now, I presume OnMurder is meant to fire only when a normal murder is triggered, and possibly also when an 'artificial' murder is caused by the vanilla Kill command. I was thinking It would be handy that the Kill command were a surefire way to fire the OnMurder event because, even then, passing 0 to the event's Killer argument would make it possible to differentiate a plain Kill call from an actual murder. This would bestow on modders the ability to determine if an actor was killed by the Kill command, specifically.

Normally this change would break older mods that register OnMurder handlers but, given the current circumstances, this particular event is not firing for any mod right now (see #3) so changing these mechanics in a next update shouldn't be a problem as long as the documentation is properly updated to reflect these changes.

Alternatively, and still assuming this entire idea is feasible, an additional OnKill event could be implemented for this only purpose.

EDIT: I guess passing a special value to OnDeath events for this particular case would be another option but, considering OnDeath does work, that would be way more likely to break something.

EventHandlerExists

We have SetEventHandler and RemoveEventHandler... but not a single method to check whatever an event handler exists.
SetEventHandler doesn't overwrite existing event handlers, so calling it multiple times with the same parameters will effectively register the same handler multiple times (and so the event will call the function multiple times).
Since we can't check whatever an event handler has already been registered, we're forced to destroy any possible existing handler with RemoveEventHandler and then registering it (again, if it was removed).

<bool> EventHandlerExists <eventName::string> <function::ref> <filter1> <filter2>
where and are optional.

PostLoadGame handler misfire on Steam

Doesnt' fire the first time a savegame is loaded in the session, generally fire after reload.
Maybe it happen also for PostLoadGame callbacks? They are strictly related

Steam loader issues

The current steam loader implementation doesn't work consistently. Update it to the implementation the other xSE projects (I'll need to consult with Ian first).

String_var commands for Strings

Many sv_* commands actually only work with String_var (and not strings), so if we have a string built with concatenation or as a result of a command/function, these commands force us to store the string in a String_var in order to use them, but it could be useful to use them on the fly.

Example:
Let pos := sv_Find "e", $actor ;search for character 'e' in actor's name

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.