Git Product home page Git Product logo

nwn.framework.lite's Introduction

NWN.Framework.Lite

NWN.Framework.Lite is an unopinionated framework for writing Neverwinter Nights code in C#.

Its intention is to provide you with minimal structure to your project while being dead simple to learn. We give you what you need to get started and then get out of your way.

Getting Started

  1. Find NWN.Framework.Lite on the Nuget feed and install it into your project.
  2. Create a class where your code will be written.
  3. Create a method like the following
// This method will be run whenever the script "sit" is run. In our example module, this happens when a player clicks a chair.
// Script names must adhere to the NWN restrictions (alphanumeric with some special characters and no longer than 16 characters)
// The method name is arbitrary and can be called whatever you want.
// Methods must be public and static so that the framework can pick them up when the module loads.
[ScriptHandler("sit")]
public static void SitOnAChair()
{
    var player = NWScript.GetLastUsedBy();
    var chair = NWScript.OBJECT_SELF;
    
    AssignCommand(player, () => ActionSit(chair));
}
  1. Configure your NWNX server with the following environment variables. Setting up an NWNX server is outside the scope of this guide. More information can be found in the Additional Resources section of this guide.
NWNX_DOTNET_ASSEMBLY=/nwn/home/dotnet/NWN.Framework.Lite 
NWNX_DOTNET_ENTRYPOINT=NWN.Framework.Lite.Internal
  1. Add the script "sit" to the OnUsed event of a placeable chair.
  2. Build the project and run the NWNX server
  3. Log in and click the chair. Your character should sit down.

And that's it!

Additional Resources

[NWNX Unified] - The NWNX project which has guides on setting up a server.

[NWN Lexicon] - Contains a wealth of useful information about NWScript.

[NWN Managed] - An alternative, opinionated framework.

Contributing

We welcome all contributions via Pull Request. Please read the following as they serve as our guiding principles on this project. We expect all contributions to adhere to these guidelines.

  1. The Lite framework is intended to be exactly as it sounds - light and unobtrusive. There are no fancy frameworks to learn. Install the package and go.
  2. We don't provide everything and the kitchen sink. There's some glue code, the NWScript and NWNX methods, and assorted enumerations. On the rare occasion we will also provide conversions of commonly used NWScript functions found in include files.

nwn.framework.lite's People

Contributors

milliorn avatar zunath avatar

Watchers

 avatar  avatar  avatar

nwn.framework.lite's Issues

Plugin 'NWNX_Administration' failed event 'SetPlayOption'

example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | E [03:12:12] [NWNXLib] [Events.cpp:56] Plugin 'NWNX_Administration' failed event 'SetPlayOption'. Error: Tried to extract an argument from an empty argument stack.
example-server_1  | ASSERTION FAILURE
example-server_1  |   Summary: (spBefore == spAfter) failed at (../../../Plugins/DotNET/DotNETExports.cpp:103)
example-server_1  |   Message: spBefore=0, spAfter=14
example-server_1  |   Backtrace:
example-server_1  |     /nwn/nwnx/NWNX_Core.so(_ZN7NWNXLib8Platform13GetStackTraceB5cxx11Eh+0x3a) [0x7f743baaf37a]
example-server_1  |     /nwn/nwnx/NWNX_Core.so(_ZN7NWNXLib6Assert12FailInternalEPKcS2_iS2_+0xbe) [0x7f743ba283ee]
example-server_1  |     /nwn/nwnx//NWNX_DotNET.so(_ZN7NWNXLib6Assert4FailIJiiEEEvPKcS3_iS3_DpT_+0x46) [0x7f7434bb0036]
example-server_1  |     /nwn/nwnx//NWNX_DotNET.so(<UNKNOWN>) [0x7f7434bad4ca]
example-server_1  |     ./nwserver-linux(_ZN10CNWSModule12EventHandlerEjjPvjj+0x26f) [0x5570398928ff]
example-server_1  |     ./nwserver-linux(_ZN15CServerAIMaster11UpdateStateEv+0x4e7) [0x557039907ee7]
example-server_1  |     ./nwserver-linux(_ZN21CServerExoAppInternal8MainLoopEv+0x1b2) [0x55703991d492]
example-server_1  |     ./nwserver-linux(<UNKNOWN>) [0x5570396c0b15]
example-server_1  |     /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xeb) [0x7f743b45409b]
example-server_1  |     ./nwserver-linux(_start+0x2a) [0x5570396c46da]
using System;
using System.Globalization;
using NWN.Framework.Lite;
using NWN.Framework.Lite.Enum;
using NWN.Framework.Lite.NWNX;
using NWN.Framework.Lite.NWNX.Enum;

namespace Source.Module
{
    class Load
    {
        // This method will be run whenever the script "x2_mod_def_load" is run. 
        // In our example module, this happens when the server finishes loading the module file.
        // Script names must adhere to the NWN restrictions (alphanumeric with some special characters and no longer than 16 characters)
        // The method name is arbitrary and can be called whatever you want.
        // Methods must be public and static so that the framework can pick them up when the module loads.
        [ScriptHandler("x2_mod_def_load")]
        public static void OnModuleLoad()
        {
            PrintBootTime();
            InitMonkWeapons();
            InitModuleVariables();
            InitWeatherSystem();
            InitAdministration();
        }

        private static void InitAdministration()
        {
            Administration.SetPlayOption(AdministrationOption.EnforceLegalCharacters, 1);
            Administration.SetPlayOption(AdministrationOption.ExamineChallengeRating, 1);
            Administration.SetPlayOption(AdministrationOption.ExamineEffects, 1);
            Administration.SetPlayOption(AdministrationOption.ItemLevelRestrictions, 1);
            Administration.SetPlayOption(AdministrationOption.PauseAndPlay, 0);
            Administration.SetPlayOption(AdministrationOption.PvpSetting, 2);
            Administration.SetPlayOption(AdministrationOption.RestoreSpellUses, 1);
            Administration.SetPlayOption(AdministrationOption.UseMaxHitpoints, 1);
            Administration.SetPlayOption(AdministrationOption.ValidateSpells, 1);
            Administration.SetPlayOption(AdministrationOption.UseMaxHitpoints, 1);
        }

        private static void InitMonkWeapons()
        {
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.Dart);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.HandAxe);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.LightHammer);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.LightMace);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.QuarterStaff);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.Sickle);
            Weapon.SetWeaponIsMonkWeapon(BaseItemType.Shuriken);
            Weapon.SetWeaponUnarmed(BaseItemType.Dart);
            Weapon.SetWeaponUnarmed(BaseItemType.Shuriken);
        }

        private static void InitWeatherSystem()
        {
            uint area = NWScript.GetFirstArea();
            while (NWScript.GetIsObjectValid(area))
            {
                if (!NWScript.GetIsAreaInterior(area))
                {
                    InitFog(area);
                    InitSkyboxes(area);
                    InitSunMoonColors(area);
                    InitArea(area);
                }
                area = NWScript.GetNextArea();
            }
        }

        private static void InitArea(uint area)
        {
            Area.SetWindPower(area, Random.Next(0, 2));
            Area.SetWeatherChance(area, (WeatherEffectType)Random.Next(0, 2), Random.Next(0, 100));
            Area.SetShadowOpacity(area, Random.Next(0, 100));
        }

        private static void InitSunMoonColors(uint area)
        {
            Area.SetSunMoonColors(area, ColorType.MoonAmbient, Random.Next(0, 16));
            Area.SetSunMoonColors(area, ColorType.MoonDiffuse, Random.Next(0, 16));
            Area.SetSunMoonColors(area, ColorType.SunAmbient, Random.Next(0, 16));
            Area.SetSunMoonColors(area, ColorType.SunDiffuse, Random.Next(0, 16));
        }

        private static void InitFog(uint area)
        {
            NWScript.SetFogAmount(FogType.All, Random.Next(0, 12), area);
            NWScript.SetFogColor(FogType.All, (FogColorType)Random.Next(0, 16), area);
        }

        private static void InitSkyboxes(uint area)
        {
            if (NWScript.GetSkyBox(area) == SkyboxType.None)
            {
                NWScript.SetSkyBox((SkyboxType)Random.Next(4));

                if (NWScript.GetSkyBox(area) == SkyboxType.GrassStorm)
                {
                    NWScript.SetWeather(area, WeatherType.Rain);
                }
                if (NWScript.GetSkyBox(area) == SkyboxType.Icy)
                {
                    NWScript.SetWeather(area, WeatherType.Snow);
                }
            }
        }

        private static void InitModuleVariables()
        {
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X2_SWITCH_ENABLE_TAGBASED_SCRIPTS");
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X2_L_STOP_EXPERTISE_ABUSE");
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X2_L_NOTREASURE");
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X3_MOUNTS_EXTERNAL_ONLY");
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X3_MOUNTS_NO_UNDERGROUND");
            NWScript.SetLocalString(NWScript.GetModule(), NWScript.GetModule().ToString(), "X2_S_UD_SPELLSCRIPT");
        }

        private static void PrintBootTime() => Console.WriteLine($"SERVER LOADED:{DateTime.Now.ToString(@"yyyy/MM/dd hh:mm:ss tt", new CultureInfo("en-US"))}");
    }
}
        public static void SetPlayOption(AdministrationOption option, int value);
# NWN Environment Variables
NWN_SERVERNAME=DOTNET-Lite
NWN_MODULE=Lite-Demo
NWN_PUBLICSERVER=1
NWN_MAXCLIENTS=64
NWN_MINLEVEL=1
NWN_MAXLEVEL=40
NWN_PAUSEANDPLAY=0
NWN_PVP=2
NWN_SERVERVAULT=1
NWN_ELC=0
NWN_ILR=0
NWN_GAMETYPE=3
NWN_ONEPARTY=0
NWN_DIFFICULTY=2
NWN_AUTOSAVEINTERVAL=0
NWN_RELOADWHENEMPTY=0
NWN_PLAYERPASSWORD=
NWN_DMPASSWORD=
NWN_ADMINPASSWORD=
NWN_NWSYNCURL=
NWN_NWSYNCHASH=

# NWNX Environment Variables
NWNX_CORE_LOG_LEVEL=6
NWNX_DOTNET_LOG_LEVEL=6
NWNX_ADMINISTRATION_SKIP=n
NWNX_AREA_SKIP=n
NWNX_BEHAVIOURTREE_SKIP=y
NWNX_CHAT_SKIP=y
NWNX_CREATURE_SKIP=y
NWNX_COMBAT_SKIP=y
NWNX_EVENTS_SKIP=y
NWNX_EFFECT_SKIP=y
NWNX_DATA_SKIP=y
NWNX_DAMAGE_SKIP=y
NWNX_JVM_SKIP=y
NWNX_METRICS_INFLUXDB_SKIP=y
NWNX_DOTNET_SKIP=n
NWNX_OBJECT_SKIP=y
NWNX_PLAYER_SKIP=y
NWNX_FEEDBACK_SKIP=n
NWNX_LUA_SKIP=y
NWNX_PROFILER_SKIP=y
NWNX_PROFILER_ENABLE_SCRIPTS=false
NWNX_REDIS_SKIP=y
NWNX_REDIS_HOST=172.22.0.100
NWNX_REDIS_LOG_LEVEL=6
NWNX_RUBY_SKIP=y
NWNX_SERVERLOGREDIRECTOR_SKIP=y
NWNX_SQL_SKIP=y
NWNX_THREADWATCHDOG_SKIP=y
NWNX_TRACKING_SKIP=y
NWNX_TWEAKS_SKIP=n
NWNX_DIALOG_SKIP=y
NWNX_WEAPON_SKIP=n
NWNX_VISIBILITY_SKIP=y
NWNX_ITEMPROPERTY_SKIP=y
NWNX_ITEM_SKIP=y
NWNX_UTIL_SKIP=y

I gave it two parameters. It appears its throws on all the calls I made. I have no build errors.

Enum RadiusSize

NWN.Framework.Lite\Enum\RadiusSize.cs

namespace NWN.Framework.Lite.Enum
{
    public static class RadiusSize
    {
        public const float Colossal = 10.0f;
        public const float Gargantuan = 8.33f;
        public const float Huge = 6.67f;
        public const float Large = 5.0f;
        public const float Medium = 3.33f;
        public const float Small = 1.67f;
    }
}

Not sure why its this way so I'm just leaving this here and you can look at it and close this.

Missing Enums

These are the enums left to convert.

MouseCursorType
PackageType
PoisonType
RacialType
SpellType

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.