Sharing some of my scripts.

Information and Discussion Relating to NWN2 Scripting and Coding

Moderators: Moderator, Developer, DM

ComeAndSee
Posts: 18
Joined: Wed Oct 21, 2015 8:50 pm

Sharing some of my scripts.

Unread post by ComeAndSee »

Hello, I'm the admin and head dev of the Kingdom of Haven server. :) I feel like sharing some of my stuff for you guys. Feel free to prune and preen all you want!

--------------------------------------------------------------

Server hz frequency automatic adjustment. The TLDR is that the more players online the more the server will increase how often it communicates with clients to help reduce the amount of workload on the server. (i.e. lag)

This script is assuming you use KEMO Scry, but you can use any kind of other table or some kind of system to count how many players are online.

Code: Select all

-- ----------------------------
-- Table structure for pollfrequency
-- ----------------------------
DROP TABLE IF EXISTS `pollfrequency`;
CREATE TABLE `pollfrequency` (
  `current` varchar(64) DEFAULT NULL,
  `forced` varchar(64) DEFAULT NULL,
  `last_check` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of pollfrequency
-- ----------------------------
INSERT INTO `pollfrequency` VALUES ('200000', null, '2016-03-29 14:12:21');

Code: Select all

#include "nwnx_sql"

int CountScry()
{
	SQLExecDirect("SELECT COUNT(`name`) from kemoscry;");
	SQLFetch();
	return StringToInt(SQLGetData(1));
}

void SetPollFrequency(int frequency)
{
	SQLExecDirect("UPDATE pollfrequency SET current="+IntToString(frequency)+", last_check=NOW();");
	if(GetLocalInt(OBJECT_SELF,"PollFrequency") == 200000) return;
	SetLocalInt(OBJECT_SELF,"PollFrequency", frequency);
	SetGameObjUpdateTime(frequency);
}

void Cmnsee_PollHB()
{
		if(GetLocalInt(OBJECT_SELF,"NOHBPOLL") == 1) return;
	SetLocalInt(OBJECT_SELF,"NOHBPOLL",1); DelayCommand(600.0f, DeleteLocalInt(OBJECT_SELF,"NOHBPOLL"));

	int scrycount = CountScry();
	
	if(scrycount < 35) //Only adjusts poll frequency if there's more than 35 players online.
	{
	SetPollFrequency(200000);
	return;
	}
	
	SQLExecDirect("SELECT forced FROM pollfrequency;");
	SQLFetch();
	
	string forced = SQLGetData(1); int frequency;
		
	if (forced == "200000")
	{
	SetPollFrequency(200000);	
	return;
	}
			
	frequency = scrycount * 6000; //40 players = 240000. 50 players = 300000. 60 players = 360000.
	
	if(GetLocalInt(OBJECT_SELF,"PollFrequency") == frequency) return;
		
	if (forced != "") frequency = StringToInt(forced);
	
	if (frequency < 200000) frequency = 200000;
	if (frequency > 400000) frequency = 400000;
		
	SetPollFrequency(frequency);
}
--------------------------------------------------------------

Script that automatically kicks people using trainers. (i.e. stat boosters)

Code: Select all

#include "nwnx_sql"

void CheckStatCheating(object oPC)
{
	int nXP = GetXP(oPC); int boot = 0;
	
	if (!GetIsDM(oPC) && oPC != OBJECT_INVALID && !GetIsDMPossessed(oPC) && GetIsPC(oPC))
	{	
	//Check for stat cheaters.
	int cSTR = GetAbilityScore(oPC, ABILITY_STRENGTH);
	int cCON = GetAbilityScore(oPC, ABILITY_CONSTITUTION);
	int cINT = GetAbilityScore(oPC, ABILITY_INTELLIGENCE);
	int cWIS = GetAbilityScore(oPC, ABILITY_WISDOM);
	int cCHA = GetAbilityScore(oPC, ABILITY_CHARISMA);
	int cDEX = GetAbilityScore(oPC, ABILITY_DEXTERITY);

	if (cSTR >= 40) boot + 1;
	if (cCON >= 40) boot + 1;
	if (cINT >= 40) boot + 1;
	if (cWIS >= 40) boot + 1;
	if (cCHA >= 40) boot + 1;
	if (cDEX >= 40) boot + 1;
	
	//Boots people if they have more than 40 of every stat. I.E. cheaters.
	if ((cSTR >= 40)
	&& cCON >= 40
	&& cINT >= 40
	&& cWIS >= 40
	&& cCHA >= 40
	&& cDEX >= 40 ||
	boot >= 2)
	{
    SendMessageToPC(oPC,"You were booted because you were using cheated stats. If this is an error please make a post on the forums @ http://nwnhaven.com"); 
	WriteTimestampedLogEntry("k_mod_pc_loaded:StatCheck: Player booted due to using a trainer: " + GetPCPlayerName(oPC) +"/" + GetPCPublicCDKey(oPC) + ":" + GetPCIPAddress(oPC));
	BootPC(oPC);
	return;
	}

	if (nXP >= 1 && oPC != OBJECT_INVALID && GetIsPC(oPC))
	{

	if ((cSTR >= 45)
	|| cCON >= 45
	|| cINT >= 45
	|| cWIS >= 45
	|| cCHA >= 45
	|| cDEX >= 45)
	{
    SendMessageToAllDMs("<C=orange>"+GetPCPlayerName(oPC)+ "(" + GetPCPublicCDKey(oPC) +
	"," + GetPCIPAddress(oPC) + ")/" + GetName(oPC) +
	" and has STR: "+ IntToString(cSTR)+ ", "+
	" and has CON: "+ IntToString(cCON)+ ", "+
	" and has INT: "+ IntToString(cINT)+ ", "+
	" and has WIS: "+ IntToString(cWIS)+ ", "+
	" and has CHA: "+ IntToString(cCHA)+ ", "+
	" and has DEX: "+ IntToString(cDEX)+ ", "+
	"</C>");
	}
	}
	}
}
--------------------------------------------------------------

Automatic collision turn off on login. Has to do a check if the player is actually online else if somebody logs on and logs off immediately it crashes the server.

Code: Select all

void TurnCollissionOff(object oPC)
{
	if (GetIsPCJustLoaded(oPC) == 0 && GetIsPC(oPC))
	{
	object oTarget = GetFirstPC();
	while (GetIsObjectValid(oTarget))
	{
	if (oTarget == oPC)
	{
	SetCollision(oPC,0);
	return;
	}
	oTarget = GetNextPC();
	}
	}
}
--------------------------------------------------------------

KEMO Bio converted to SQL. Supports AES encryption. Not sure how you guys have it, but this will save you space (not storing it on players) and will be retained on rebuilds.

Code: Select all

-- ----------------------------
-- Table structure for kemo_bios
-- ----------------------------
DROP TABLE IF EXISTS `kemo_bios`;
CREATE TABLE `kemo_bios` (
  `bioid` int(3) NOT NULL,
  `name` varchar(128) DEFAULT NULL,
  `player` varchar(64) DEFAULT NULL,
  `biotext` varbinary(10000) DEFAULT NULL,
  `portrait` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`bioid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Code: Select all

#include "nwnx_sql"

string GetBioPCID(object oPC)
{
	string name = SQLEncodeSpecialChars(GetName(oPC));
	string player = SQLEncodeSpecialChars(GetPCPlayerName(oPC));
	string sQuery;
	string userid;
		
	sQuery = "SELECT bioid FROM kemo_bios where name='"+name+"' and player='"+player+"';";
	SQLExecDirect(sQuery); SQLFetch();

	userid = SQLGetData(1);
	
	if (userid == "")
	{
	sQuery = "INSERT INTO kemo_bios (bioid, name, player, portrait) SELECT 1 + coalesce((SELECT max(bioid)"+
	" FROM kemo_bios), 0), '"+name+"', '"+player+"', 'bg_60_alpha';";
	SQLExecDirect(sQuery);

	sQuery = "SELECT bioid FROM kemo_bios where name='"+name+"' and player='"+player+"';";
	SQLExecDirect(sQuery); SQLFetch();

	userid = SQLGetData(1);
	}

	return userid;
}

string GetPackPortrait(string sPortrait)
{
	int iFilenameLength = GetStringLength(sPortrait) - 1;
	int iPackSize = StringToInt(GetStringRight(sPortrait,1));
	int iPackVariant = Random(iPackSize+1);
	sPortrait = GetStringLeft(sPortrait,iFilenameLength);
	return sPortrait + IntToString(iPackVariant) + ".tga";
}

void CyclePortraits()
{
	object oPC = OBJECT_SELF; string sDB; string sPortrait; int iFilenameLength; string sQuery; string bioid;
	int iPackSize; int iPackVariant; string sPortraitTGA;
	
	bioid = GetBioPCID(oPC);

	sQuery = "SELECT portrait FROM kemo_bios where bioid='"+bioid+"';";
	SQLExecDirect(sQuery); SQLFetch();

	sPortrait = SQLGetData(1);

	if (sPortrait == "")
	{
	if (GetStringLength(sPortrait) < 2) sPortrait = "bg_60_alpha";
	}

	if (FindSubString(sPortrait,"pack") > -1)
	{
		iFilenameLength = GetStringLength(sPortrait) - 1;
		iPackSize = StringToInt(GetStringRight(sPortrait,1));
		sPortrait = GetStringLeft(sPortrait,iFilenameLength);
		iPackVariant = 0;
		while (iPackVariant <= iPackSize)
		{
		sPortraitTGA = sPortrait + IntToString(iPackVariant) + ".tga";
		DelayCommand(IntToFloat(iPackVariant)*0.5f,SetGUITexture(oPC,"KEMO_BIO_EDIT","KEMO_PORTRAIT",sPortraitTGA));
		iPackVariant++;
	}
	}
}

void main(string sAction, string sType, string sEntry)
{
	object oPC = OBJECT_SELF;
	object oTarget = GetPlayerCurrentTarget(oPC);
	string sDB; string sBio; string sPortrait; string sPortraitTGA; string bioid; string targetid; string sQuery;
	
	if (sAction == "display")
	{
		bioid = GetBioPCID(oTarget);

		sQuery = "SELECT AES_DECRYPT(biotext,'insertyourpasswordhere'), portrait FROM kemo_bios"+
		" where bioid='"+bioid+"';";
		SQLExecDirect(sQuery); SQLFetch();

		sBio=SQLGetData(1);
		sPortrait=SQLGetData(2);
		if (GetStringLength(sPortrait) < 2) sPortrait = "bg_60_alpha";
		
		//filenames with "pack" in them are set up as series, 0-9
		//viewers will see one of the pack selected at random
		//editors specify the size of the pack by using the highest number
		//in the series: if x_pack_ has 5 pictures, type in x_pack_4 to
		//set the range
		if (FindSubString(sPortrait,"pack") > -1)
		{	sPortrait = GetPackPortrait(sPortrait);
			DisplayGuiScreen(oPC,"KEMO_BIO_DISPLAY",FALSE,"kemo_bio_display.xml");
			SetGUIObjectText(oPC,"KEMO_BIO_DISPLAY","INPUT_BIOTEXT",-1,sBio);
			SetGUITexture(oPC,"KEMO_BIO_DISPLAY","KEMO_PORTRAIT",sPortrait);
			DisplayGuiScreen(oPC,"KEMO_ERP",FALSE,"kemo_erp.xml");
			SendMessageToPC(oTarget,"<C=gray>Someone is inspecting you. [Portrait: " + sPortrait + "]</C>");
		}
		else
		{	sPortrait = sPortrait + ".tga";
			DisplayGuiScreen(oPC,"KEMO_BIO_DISPLAY",FALSE,"kemo_bio_display.xml");
			SetGUIObjectText(oPC,"KEMO_BIO_DISPLAY","INPUT_BIOTEXT",-1,sBio);
			SetGUITexture(oPC,"KEMO_BIO_DISPLAY","KEMO_PORTRAIT",sPortrait);
			DisplayGuiScreen(oPC,"KEMO_ERP",FALSE,"kemo_erp.xml");
			SendMessageToPC(oTarget,"<C=gray>Someone is inspecting you.</C>");
		}
		WriteTimestampedLogEntry(GetName(oPC) + " is displaying a bio/portrait: " + sPortrait);
		
		return;
	}
	if (sAction == "preview")
	{
		CloseGUIScreen(oPC,"KEMO_BIO_EDIT");
		CloseGUIScreen(oPC,"KEMO_BIO_DISPLAY");
	
		bioid = GetBioPCID(oPC);

		sQuery = "SELECT AES_DECRYPT(biotext,'insertyourpasswordhere'), portrait FROM kemo_bios"+
		" where bioid='"+bioid+"';";
		SQLExecDirect(sQuery); SQLFetch();

		sBio=SQLGetData(1);
		sPortrait=SQLGetData(2);
		if (GetStringLength(sPortrait) < 2) sPortrait = "bg_60_alpha";
		
		//filenames with "pack" in them are set up as series, 0-9
		//viewers will see one of the pack selected at random
		//editors specify the size of the pack by using the highest number
		//in the series: if x_pack_ has 5 pictures, type in x_pack_4 to
		//set the range
		if (FindSubString(sPortrait,"pack") > -1)
		{	sPortrait = GetPackPortrait(sPortrait);
			DisplayGuiScreen(oPC,"KEMO_BIO_DISPLAY",FALSE,"kemo_bio_display.xml");
			SetGUIObjectText(oPC,"KEMO_BIO_DISPLAY","INPUT_BIOTEXT",-1,sBio);
			SetGUITexture(oPC,"KEMO_BIO_DISPLAY","KEMO_PORTRAIT",sPortrait);
			//DisplayGuiScreen(oPC,"KEMO_ERP",FALSE,"kemo_erp.xml");
			//SendMessageToPC(oTarget,"<C=gray>Someone is inspecting you. [Portrait: " + sPortrait + "]</C>");
		}
		else
		{	sPortrait = sPortrait + ".tga";
			DisplayGuiScreen(oPC,"KEMO_BIO_DISPLAY",FALSE,"kemo_bio_display.xml");
			SetGUIObjectText(oPC,"KEMO_BIO_DISPLAY","INPUT_BIOTEXT",-1,sBio);
			SetGUITexture(oPC,"KEMO_BIO_DISPLAY","KEMO_PORTRAIT",sPortrait);
			//DisplayGuiScreen(oPC,"KEMO_ERP",FALSE,"kemo_erp.xml");
			//SendMessageToPC(oTarget,"<C=gray>Someone is inspecting you.</C>");
		}
		WriteTimestampedLogEntry(GetName(oPC) + " is displaying a bio/portrait: " + sPortrait);
		
		return;
	}
	if (sAction == "edit")
	{
		WriteTimestampedLogEntry(GetName(oPC) + " is editing a bio/portrait.");
		SendMessageToPC(oPC,"Players portraits available: https://kingdomofhaven.com/gallery/");
		bioid = GetBioPCID(oPC);		

		sQuery = "SELECT AES_DECRYPT(biotext,'insertyourpasswordhere'), portrait FROM kemo_bios"+
		" where bioid='"+bioid+"';";
		SQLExecDirect(sQuery); SQLFetch();

		sPortrait=SQLGetData(2);
		sPortraitTGA = sPortrait+".tga";

		DisplayGuiScreen(oPC,"KEMO_BIO_EDIT",FALSE,"kemo_bio_edit.xml");
		SetGUIObjectText(oPC,"KEMO_BIO_EDIT","INPUT_BIOTEXT",-1,SQLGetData(1));
		SetGUIObjectText(oPC,"KEMO_BIO_EDIT","PORTRAIT_INPUT_BOX",-1,sPortrait);
		SetGUITexture(oPC,"KEMO_BIO_EDIT","KEMO_PORTRAIT",sPortraitTGA);
		DisplayGuiScreen(oPC,"KEMO_ERP",FALSE,"kemo_erp.xml");
		return;
	}
	if (sAction == "save")
	{
		WriteTimestampedLogEntry(GetName(oPC) + " is saving a bio/portrait.");
		bioid = GetBioPCID(oPC);

		if (sType == "bio")
		{
		sQuery = "UPDATE kemo_bios SET biotext=AES_ENCRYPT('"+SQLEncodeSpecialChars(sEntry)+
		"','insertyourpasswordhere') where bioid='"+bioid+"';";
		SQLExecDirect(sQuery);
		CloseGUIScreen(oPC,"KEMO_BIO_EDIT");
		}
		if (sType == "portrait")
		{
		sQuery = "SELECT portrait FROM kemo_bios where bioid='"+bioid+"';";
		SQLExecDirect(sQuery); SQLFetch();
		
		sPortrait=SQLGetData(1);

		if (sEntry == sPortrait) return;
		if (GetStringLength(sEntry) < 2) sEntry = "bg_60_alpha";
			
		sQuery = "UPDATE kemo_bios SET portrait='"+SQLEncodeSpecialChars(sEntry)+"' where bioid='"+bioid+"';";
		SQLExecDirect(sQuery);
		CyclePortraits();
		SetGUITexture(oPC,"KEMO_BIO_EDIT","KEMO_PORTRAIT",sEntry+".tga");
		}
		return;
	}
}

--------------------------------------------------------------

KEMO storage converted to SQL and supports guild tokens

Code: Select all

-- ----------------------------
-- Table structure for cmnsee_storage
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_storage`;
CREATE TABLE `cmnsee_storage` (
  `storageid` int(3) DEFAULT '0',
  `itemid` varchar(255) DEFAULT NULL,
  `itemname` varchar(255) DEFAULT NULL,
  `stacksize` int(3) DEFAULT NULL,
  `icon` varchar(255) DEFAULT NULL,
  `category` varchar(255) DEFAULT NULL,
  `campaignstring` blob
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for cmnsee_storage_guild
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_storage_guild`;
CREATE TABLE `cmnsee_storage_guild` (
  `id` int(3) NOT NULL,
  `guildname` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for cmnsee_storage_guildstorage
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_storage_guildstorage`;
CREATE TABLE `cmnsee_storage_guildstorage` (
  `storageid` int(3) DEFAULT '0',
  `itemid` varchar(255) DEFAULT NULL,
  `itemname` varchar(255) DEFAULT NULL,
  `stacksize` int(3) DEFAULT NULL,
  `icon` varchar(255) DEFAULT NULL,
  `category` varchar(255) DEFAULT NULL,
  `campaignstring` longtext,
  `depositedby` varchar(255) DEFAULT NULL,
  `act` varchar(255) DEFAULT NULL,
  `cdkey` varchar(255) DEFAULT NULL,
  `ipaddress` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for cmnsee_storage_history
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_storage_history`;
CREATE TABLE `cmnsee_storage_history` (
  `time` datetime DEFAULT NULL,
  `action` varchar(255) DEFAULT NULL,
  `storageid` varchar(255) DEFAULT NULL,
  `itemname` varchar(255) DEFAULT NULL,
  `stacksize` varchar(255) DEFAULT NULL,
  `actionby` varchar(255) DEFAULT NULL,
  `act` varchar(255) DEFAULT NULL,
  `cdkey` varchar(255) DEFAULT NULL,
  `ipaddress` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Table structure for cmnsee_storage_users
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_storage_users`;
CREATE TABLE `cmnsee_storage_users` (
  `id` int(3) NOT NULL,
  `name` varchar(64) DEFAULT NULL,
  `player` varchar(64) DEFAULT NULL,
  `converted` int(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Last edited by ComeAndSee on Sat Apr 02, 2016 3:46 pm, edited 1 time in total.
User avatar
LISA100595
Retired Staff
Posts: 5202
Joined: Mon Aug 22, 2011 12:23 pm

Re: Sharing some of my scripts.

Unread post by LISA100595 »

Wow thank you very much for sharing with us!
Lady Elvina Aira-S'efarro - The Order of the Silver Rose
Salaria - Bounty Hunter half-sister of Darius Brothers
Angelina Northstar - Holy Warrior of Tyr / Knight of the Silver Rose
Matilda Stonehold - Honorable Sheild Dwarf
Loriah Swift - Morninglord of Lathander
User avatar
Maecius
Retired Admin
Posts: 11639
Joined: Sat May 16, 2009 4:24 pm

Re: Sharing some of my scripts.

Unread post by Maecius »

Thanks, ComeAndSee, for the share! Haven's lucky to have you working on their behalf over there.

And we all appreciate your generosity of spirit and community-mindedness over here.
User avatar
Calodan
Posts: 2032
Joined: Fri Apr 19, 2013 12:21 pm
Location: Missoula Montana BIG SKY COUNTRY

Re: Sharing some of my scripts.

Unread post by Calodan »

Thanks a lot Haven person!!! It is so awesome to see a community come together and help each other!
Kory Sentinel
"We should take the army head on!"

"... it sounds like a terrible idea, but look at that smile."
"And he just sounds so confident ... he is a favored soul."
"Even if we don't survive, he will, and isn't that what matters?" -Red Lancer
User avatar
DM Wafflehouse
Posts: 175
Joined: Sat Jan 30, 2016 3:52 am

Re: Sharing some of my scripts.

Unread post by DM Wafflehouse »

When the game only has between 200-1000 players across all servers and its only the players supporting it, we all become one big family, especially those who have been targeted and attacked.

much love and gratitude to our neighboring servers including yours.
ComeAndSee
Posts: 18
Joined: Wed Oct 21, 2015 8:50 pm

Re: Sharing some of my scripts.

Unread post by ComeAndSee »

Weather system rewrite I did based off of Althea's. What my version does is you can create "weather patterns" on specific maps and every 45 minutes the system does a heartbeat and applies the effect based off parameters in MYSQL.

I call it "Dynamic Weather System" because the weather can adjust to different condition. (i.e. it can go from thunderstorm to light storm or fog to rain, etc.) Also, I added lightning ground-strikes. You will need to add adiditional placeables to the maps to get it to work. If you want them let me know.

Here's SQL dump.

Code: Select all

-- ----------------------------
-- Table structure for cmnsee_weather
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather`;
CREATE TABLE `cmnsee_weather` (
  `weather_pattern` varchar(64) DEFAULT NULL,
  `fogchance` varchar(64) DEFAULT NULL,
  `rainchance` varchar(64) DEFAULT NULL,
  `timewindow_start` time DEFAULT NULL,
  `timewindow_end` time DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of cmnsee_weather
-- ----------------------------
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'aboveaverage', 'aboveaverage', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('kortuga', 'high', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'veryhigh', 'occasional', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'occasional', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sunbright', 'aboveaverage', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'aboveaverage', 'aboveaverage', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'occasional', 'moderate', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('volcanoisland', 'high', 'high', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'veryhigh', 'aboveaverage', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'occasional', 'aboveaverage', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('goblin', 'aboveaverage', 'aboveaverage', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'moderate', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('harts', 'moderate', 'moderate', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'aboveaverage', 'high', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('valley', 'aboveaverage', 'aboveaverage', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'aboveaverage', 'rare', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'occasional', 'rare', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sharessia', 'moderate', 'rare', '18:00:00', '04:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'moderate', '05:00:00', '11:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'occasional', '12:00:00', '17:59:00');
INSERT INTO `cmnsee_weather` VALUES ('sylsrefuge', 'veryhigh', 'moderate', '18:00:00', '04:59:00');

-- ----------------------------
-- Table structure for cmnsee_weather_current
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather_current`;
CREATE TABLE `cmnsee_weather_current` (
  `weather_pattern` varchar(64) NOT NULL,
  `fog` int(1) DEFAULT NULL,
  `rain` int(1) DEFAULT NULL,
  `sunnyandclear` int(1) DEFAULT NULL,
  PRIMARY KEY (`weather_pattern`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of cmnsee_weather_current
-- ----------------------------
INSERT INTO `cmnsee_weather_current` VALUES ('goblin', '0', '0', '2');
INSERT INTO `cmnsee_weather_current` VALUES ('harts', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('kortuga', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('sharessia', '0', '0', '1');
INSERT INTO `cmnsee_weather_current` VALUES ('sunbright', '1', '0', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('sylsrefuge', '0', '0', '2');
INSERT INTO `cmnsee_weather_current` VALUES ('valley', '0', '1', '0');
INSERT INTO `cmnsee_weather_current` VALUES ('volcanoisland', '0', '0', '1');

-- ----------------------------
-- Table structure for cmnsee_weather_maps
-- ----------------------------
DROP TABLE IF EXISTS `cmnsee_weather_maps`;
CREATE TABLE `cmnsee_weather_maps` (
  `areatag` varchar(64) DEFAULT NULL,
  `interior` int(11) DEFAULT NULL,
  `weather_pattern` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of cmnsee_weather_maps
-- ----------------------------
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaCove', '0', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('SunbrightIsland', '0', 'sunbright');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugaclub', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('PurpleCrowBazaar', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugastylistshop', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaMercantile', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('KortugaBathHouse', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugatemple', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('haven_volcanoisland', '0', 'volcanoisland');
INSERT INTO `cmnsee_weather_maps` VALUES ('kortugasewer', '1', 'kortuga');
INSERT INTO `cmnsee_weather_maps` VALUES ('GoblinIsland', '0', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('goblincaves1', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('goblincaves2', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('vermincaves', '1', 'goblin');
INSERT INTO `cmnsee_weather_maps` VALUES ('Connisle', '0', 'harts');
INSERT INTO `cmnsee_weather_maps` VALUES ('ValleyofDeath', '0', 'valley');
INSERT INTO `cmnsee_weather_maps` VALUES ('Haven', '0', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('myrin', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenMercantile', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('SensualServices', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('inn', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('MagesGuild', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenTemple', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('FestHall', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('HavenKeep', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('EnchantedDragonFoundry', '1', 'sharessia');
INSERT INTO `cmnsee_weather_maps` VALUES ('syls_refuge', '0', 'sylsrefuge');

Code: Select all

cmnsee_weather_includes

#include "nwnx_sql"

float weatherdelay = 300.0;

void SendMessageToAllPlayers(string area, string message)
{
	object oTarget = GetFirstPC();
	while (GetIsObjectValid(oTarget))
	{
	if (GetTag(GetArea(oTarget)) == area)
	{
	SendMessageToPC(oTarget,message);
	}
	oTarget = GetNextPC();
	}
	}

void PlayThunder(object oArea)
{
	// WE HAVE STOPPED
	if(GetLocalInt(oArea, "LIGHTNINGON") == 0){return;}

	location lChecker = GetLocation(GetFirstObjectInArea(oArea));
	object oTarget = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,lChecker);

	if (oTarget == OBJECT_INVALID) return;

	string sThunder = "as_na_thunder_" + IntToString(Random(7) + 1);	
	object oTemp = CreateObject(OBJECT_TYPE_PLACEABLE, "alb_temp_weather", GetLocation(oTarget));
	DelayCommand(IntToFloat(d2()), AssignCommand(oTemp, PlaySound(sThunder, TRUE)));
	DestroyObject(oTemp, 10.0, FALSE);
}

void LightningDamage(object LightningStrike)
{
	int nCount = 1;

	object oPlayer = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,GetLocation(LightningStrike), nCount);
	while (GetIsObjectValid(oPlayer))
    {
	if (GetDistanceBetween(oPlayer, LightningStrike) < 4.0 && GetDistanceBetween(oPlayer, LightningStrike) > 0.00)
	{	
	effect eVis	= EffectVisualEffect(VFX_COM_HIT_ELECTRICAL);
	ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eVis, oPlayer, 1.0);
	
	effect eHurt = EffectDamage( FloatToInt((GetCurrentHitPoints(oPlayer) * 0.15)), DAMAGE_TYPE_ELECTRICAL, DAMAGE_POWER_NORMAL, TRUE);
	ApplyEffectToObject(DURATION_TYPE_INSTANT, eHurt, oPlayer);
	
	SendMessageToPC(oPlayer,"<i>*You were just struck by lightning!*</i>");
	}
	nCount++;
	oPlayer = GetNearestCreatureToLocation(CREATURE_TYPE_PLAYER_CHAR,PLAYER_CHAR_IS_PC,GetLocation(LightningStrike), nCount);
	}
}

void LightningStrike (object oArea)
{
	object LightningStrike = GetNearestObjectByTag("alb_lightning_spot", GetFirstObjectInArea(oArea), Random(20));

	effect eVFX = EffectNWN2SpecialEffectFile("sp_lightning_superray");
	effect eVFX2 = EffectNWN2SpecialEffectFile("sp_storm_veng_light");	
	effect eVFX3 = EffectNWN2SpecialEffectFile("fx_light_white_20");	
	
	ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, LightningStrike);
	ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX2, LightningStrike);
	ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX3, LightningStrike);
	
	DelayCommand(0.5,RemoveSEFFromObject(LightningStrike, "fx_light_white_20"));
	DelayCommand(5.0,RemoveSEFFromObject(LightningStrike, "sp_lightning_superray"));
	DelayCommand(5.0,RemoveSEFFromObject(LightningStrike, "sp_storm_veng_light"));
	
	LightningDamage(LightningStrike);
}

void MakeLightning(object oArea)
{
	// LIGHTNING
	object oLight = GetNearestObjectByTag("alb_lightning", GetFirstObjectInArea(oArea));
	SetLightActive(oLight, TRUE); int iCounter;

	if (d4() == 1) LightningStrike(oArea);
	
	DelayCommand(IntToFloat(d2()+ 1),SetLightActive(oLight, FALSE));
	DelayCommand(IntToFloat(d2()), PlayThunder(oArea));
}

void RandomLightning(object oArea)
{	
	if(GetLocalInt(oArea, "LIGHTNINGON") == 0) return;
	
	MakeLightning(oArea);
	if (d4() == 1) DelayCommand(3.0, MakeLightning(oArea));
				
	// KEEP GOING IF REQUIRED	
	DelayCommand(IntToFloat(Random(30)+5), RandomLightning(oArea));
}

void CancelSounds(object oTarget, string tag)
{
	int nSound = 0;
	
	object oSound = GetNearestObjectByTag(tag,oTarget,nSound);

	while (GetIsObjectValid(oSound))
	{
	SoundObjectStop(oSound);
	nSound++;
	oSound = GetNearestObjectByTag(tag,oTarget,nSound);
	}
}

void StopSounds(object oTarget)
{
	object oSound = GetFirstObjectInArea(oTarget);

	CancelSounds(oSound, "alb_rain_light");
	CancelSounds(oSound, "alb_rain_stormheavy");
	CancelSounds(oSound, "alb_rain_heavy");
	CancelSounds(oSound, "alb_thunder_ambient");
	
	CancelSounds(oSound, "alb_rain_light_interior");
	CancelSounds(oSound, "alb_rain_stormheavy_interior");
	CancelSounds(oSound, "alb_rain_heavy_interior");
	CancelSounds(oSound, "alb_thunder_ambient_interior");
}

void ResetAllNWN2Fog(object oTarget)
{
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNRISE);	
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_DAYTIME);	
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNSET);	
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONRISE);	
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_NIGHTTIME);	
	ResetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONSET);
}

void SetAllNWN2Fog(object oTarget, int nColor, float fFogStart, float fFogEnd)
{
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNRISE, nColor, fFogStart, fFogEnd );	
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_DAYTIME, nColor, fFogStart, fFogEnd );	
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_SUNSET, nColor, fFogStart, fFogEnd );	
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONRISE, nColor, fFogStart, fFogEnd );	
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_NIGHTTIME, nColor, fFogStart, fFogEnd );	
	SetNWN2Fog(oTarget, FOG_TYPE_NWN2_MOONSET, nColor, fFogStart, fFogEnd );
}

void SetFogColours(object oArea, int iCurrentPower)
{
	if(iCurrentPower == 1){SetAllNWN2Fog(oArea, FOG_COLOR_WHITE, 45.0, 65.0);} //Fog
	if(iCurrentPower == 2){SetAllNWN2Fog(oArea, FOG_COLOR_GREY, 45.0, 70.0);} //Light rain
	if(iCurrentPower == 3){SetAllNWN2Fog(oArea, FOG_COLOR_BLACK, 45.0, 65.0);} //Heavy rain
	if(iCurrentPower == 4){SetAllNWN2Fog(oArea, FOG_COLOR_BLACK, 45.0, 50.0);} //Thunderstorm
}

void RemoveWeatherEffect(object oTarget, string effectname)
{
	if (GetIsAreaInterior(oTarget) == TRUE) return;
	
	int iCounter = 1; 
		
	object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oTarget), iCounter);
		
	while(oWeatherUnit != OBJECT_INVALID)
	{
	RemoveSEFFromObject(oWeatherUnit, effectname);				
			
	iCounter = iCounter + 1; 
	oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oTarget), iCounter);
	}
}

void RemoveAllEffects(object oArea)
{
	if (GetIsAreaInterior(oArea) == TRUE) return;
	
	// USE A STATIC OBJECT TO LOOP FROM (PC MAY MOVE AND CHANGE TARGET)
	int iCounter = 1; 
		
	object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
		
	while(oWeatherUnit != OBJECT_INVALID)
	{
	// REMOVE ALL POSSIBLE WEATHER EFFECTS
	RemoveSEFFromObject(oWeatherUnit, "fx_area_fog_white");		// AREA FOG					
	RemoveSEFFromObject(oWeatherUnit, "fx_rain_splash");		// HEAVY RAIN
	RemoveSEFFromObject(oWeatherUnit, "fx_rain_nosplash");		// HEAVY RAIN
	RemoveSEFFromObject(oWeatherUnit, "fx_rain_light");		// LIGHT RAIN
							
	iCounter = iCounter + 1; 
	oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
	}	
}

void UpdateSkyEffect(object oArea, string SEFEffectFile)
{
	if (GetIsAreaInterior(oArea) == TRUE) return;

	effect eVFX = EffectNWN2SpecialEffectFile(SEFEffectFile);
			
	int iCounter = 1; 
		
	object oWeatherUnit = GetNearestObjectByTag("alb_skybox_unit", GetFirstObjectInArea(oArea), iCounter);
		
	while(oWeatherUnit != OBJECT_INVALID)
	{
	ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, oWeatherUnit);
	iCounter = iCounter + 1;
	oWeatherUnit = GetNearestObjectByTag("alb_skybox_unit", GetFirstObjectInArea(oArea), iCounter);
	}
}	

void UpdateUnitEffect(object oArea, string SEFEffectFile)
{
	if (GetIsAreaInterior(oArea) == TRUE) return;

	effect eVFX = EffectNWN2SpecialEffectFile(SEFEffectFile);
			
	int iCounter = 1; 
		
	object oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
		
	while(oWeatherUnit != OBJECT_INVALID)
	{
	ApplyEffectToObject(DURATION_TYPE_PERMANENT, eVFX, oWeatherUnit);
	iCounter = iCounter + 1;
	oWeatherUnit = GetNearestObjectByTag("alb_weather_unit", GetFirstObjectInArea(oArea), iCounter);
	}
}	

void StopWeather(object oArea)
{
	RemoveAllEffects(oArea);
	StopSounds(oArea);
	ResetAllNWN2Fog(oArea);
	
	DeleteLocalInt(oArea,"LIGHTNINGON");
	DeleteLocalInt(oArea,"WEATHERON");
	DeleteLocalInt(oArea,"FOGCOLOR");
	DeleteLocalInt(oArea,"FOGENABLED");
	
	SetWeather(oArea, 0, 0);
}

void StopAllWeather(string area)
{
	SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
	string sArea;
	
	while (SQLFetch() == SQL_SUCCESS)
	{
	sArea = SQLGetData(1);
	StopWeather(GetObjectByTag(sArea));
	}
}

void PlaySounds(object oTarget, int choice)
{
	string soundtag; string tag; string tag2; int iCounter = 1;
	
	if (choice == 1)
	{
	tag = "alb_rain_light";
	tag2 = "alb_rain_light_interior";
	}
	
	if (choice == 2)
	{
	tag = "alb_rain_heavy";
	tag2 = "alb_rain_heavy_interior";
	}
	
	if (choice == 3)
	{
	tag = "alb_rain_stormheavy";
	tag2 = "alb_rain_stormheavy_interior";
	}
	
	if (choice == 4)
	{
	tag = "alb_thunder_ambient";
	tag2 = "alb_thunder_ambient_interior";
	}
	
	SoundObjectPlay(GetNearestObjectByTag(tag, GetFirstObjectInArea(oTarget)));
	
	object oSound = GetNearestObjectByTag(tag2, GetFirstObjectInArea(oTarget), iCounter);

	while(oSound != OBJECT_INVALID)
	{
	SoundObjectPlay(oSound);
	
	iCounter = iCounter + 1;
	oSound = GetNearestObjectByTag(tag2, GetFirstObjectInArea(oTarget), iCounter);
	}
}

void FogOn(object oArea, int rain)
{
	if (GetLocalInt(oArea,"FOGENABLED") == 1 || GetIsAreaInterior(oArea)) return;
	if (GetIsAreaInterior(oArea) == TRUE) return;

	RemoveWeatherEffect(oArea, "fx_area_fog_white");
	UpdateUnitEffect(oArea, "fx_area_fog_white");
	SetLocalInt(oArea,"FOGENABLED",1);	
	
	if (rain == 1) return;
	SetFogColours(oArea, 1);
	SetLocalInt(oArea,"FOGCOLOR",1);
	SendMessageToAllPlayers(GetTag(oArea),"<i>*A heavy fog descends over the area*</I>");
}

void FogOff(object oArea, int rain)
{
	if (GetIsAreaInterior(oArea) == TRUE) return;
	float delay = weatherdelay; //5 minutes
	SendMessageToAllPlayers(GetTag(oArea), "<i>*The heavy fog begins to fade away*</I>");

	DelayCommand(delay,	StopWeather(oArea));
}

void AreaFogOnOff(string area, int fogswitch)
{
	SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"' AND interior=0;");
	string sArea;
	
	while (SQLFetch() == SQL_SUCCESS)
	{
	sArea = SQLGetData(1);
	if (fogswitch == 1) FogOn(GetObjectByTag(sArea), 0);
	if (fogswitch == 0) FogOff(GetObjectByTag(sArea), 0);
	}
}

void Drizzle(object oArea)
{
	// START THIS SOUND
	if (GetIsAreaInterior(oArea) == TRUE) return;
	
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));

	// REDUCE LIGHTING
	SetFogColours(oArea, 1);
	SetWeather(oArea, 0, 2);
					
	// SETTINGS
	SetLocalInt(oArea,"LIGHTNINGON",0);
	SetLocalInt(oArea,"WEATHERON",1);
	SetLocalInt(oArea,"FOGCOLOR",1);
	DeleteLocalInt(oArea,"FOGENABLED");
}

void LightRainStorm(object oArea)
{
	// START THIS SOUND
	DelayCommand(0.5, StopSounds(oArea));
	DelayCommand(1.0, PlaySounds(oArea, 1)); //Light rainstorm
	if (GetIsAreaInterior(oArea) == TRUE) return;

	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
	DelayCommand(0.5, UpdateUnitEffect(oArea,"fx_rain_light"));
	
				
	// REDUCE LIGHTING
	ResetAllNWN2Fog(oArea);
	SetFogColours(oArea, 2);
	SetWeather(oArea, 0, 2);
					
	// ADD DOWNPOUR RAIN & SPLASH
	FogOn(oArea, 1);
		 
	// SETTINGS
	SetLocalInt(oArea,"LIGHTNINGON",0);
	SetLocalInt(oArea,"WEATHERON",2);
	SetLocalInt(oArea,"FOGCOLOR",2);
}

void HeavyRainStorm(object oArea)
{
	// START THIS SOUND
	DelayCommand(0.5, StopSounds(oArea));
	DelayCommand(1.0, PlaySounds(oArea, 2)); //Heavy Rainstorm
	if (GetIsAreaInterior(oArea) == TRUE) return;
			
	// REDUCE LIGHTING
	ResetAllNWN2Fog(oArea);
	SetFogColours(oArea, 3);
	SetWeather(oArea, 0, 4);
				
	// ADD DOWNPOUR RAIN & SPLASH
	FogOn(oArea, 1);
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
	DelayCommand(1.0, UpdateUnitEffect(oArea,"fx_rain_splash"));
		 
	// SETTINGS
	SetLocalInt(oArea,"LIGHTNINGON",0);
	SetLocalInt(oArea,"WEATHERON",3);
	SetLocalInt(oArea,"FOGCOLOR",3);
}

void ThunderStorm(object oArea)
{
	// START THIS SOUND
	DelayCommand(0.5, StopSounds(oArea));
	DelayCommand(1.0, PlaySounds(oArea, 3)); //Heavy rainstorm
	DelayCommand(1.0, PlaySounds(oArea, 4)); //Thunder, ambient
	if (GetIsAreaInterior(oArea) == TRUE) return;
			
	// REDUCE LIGHTING
	ResetAllNWN2Fog(oArea);
	SetFogColours(oArea, 4);
	SetWeather(oArea, 0, 5);
				
	// ADD DOWNPOUR RAIN & SPLASH
	FogOn(oArea, 1);
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_light"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_splash"));
	DelayCommand(0.5, RemoveWeatherEffect(oArea,"fx_rain_nosplash"));
	DelayCommand(1.0, UpdateUnitEffect(oArea,"fx_rain_splash"));
		 
	// START LIGHTNING
	DelayCommand(IntToFloat(Random(10) + 5), RandomLightning(oArea));
	
	// SETTINGS
	SetLocalInt(oArea,"LIGHTNINGON",1);
	SetLocalInt(oArea,"WEATHERON",4);
	SetLocalInt(oArea,"FOGCOLOR",4);
}

void DynamicRainStorm(string area, int stormtype, string weatherpattern, int onoff)
{
	int weatheron = GetLocalInt(GetObjectByTag(area),"WEATHERON");
	if (weatheron == stormtype) return;
	string sMessage; int interior;
	if (GetIsAreaInterior(GetObjectByTag(area)) == TRUE) interior = 1;
	
	float delay = weatherdelay; //5 minutes
		
	//OFF SWITCHES
	if (weatheron == 1 && onoff == 0) //Drizzle stops
	{
	sMessage = "<i>*The rain storm passes by*</I>";
	if (interior == 1) sMessage = "<i>*The sound of light rain outside stops.*</I>";
	DelayCommand(delay / 2,StopAllWeather(weatherpattern));
	}

	//OFF SWITCHES
	if (weatheron == 2 && onoff == 0) //Light rain stops.
	{
	sMessage = "<i>*The rain storm passes by*</I>";
	if (interior == 1) sMessage = "<i>*The sound of light rain outside stops.*</I>";
	DelayCommand(delay / 2, Drizzle(GetObjectByTag(area)));
	DelayCommand(delay * 1.5,StopAllWeather(weatherpattern));
	}
	
	if (weatheron == 3 && onoff == 0) //Heavy rain stops.
	{
	sMessage = "<i>*The heavy rain begins to let up.*</I>";
	if (interior == 1) sMessage = "<i>*The sound of heavy rain outside begins to let up. Perhaps the storm is passing by.*</I>";
	DelayCommand(delay, LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 2, Drizzle(GetObjectByTag(area)));
	DelayCommand(delay * 3, StopAllWeather(weatherpattern));
	}
	
	if (weatheron == 4 && onoff == 0)
	{
	sMessage = "<i>*The thunder storm begins to pass through the area.*</I>";
	if (interior == 1) sMessage = "<i>*The thundering outside begins to let up.*</I>";
	DelayCommand(delay * 0.75,HeavyRainStorm(GetObjectByTag(area))); //Thunderstorm stops.
	DelayCommand(delay * 2,LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 3,Drizzle(GetObjectByTag(area)));
	DelayCommand(delay * 4,StopAllWeather(weatherpattern));
	}		
	
	//ON SWITCHES (NO WEATHER ON)
	if (weatheron == 0 && stormtype == 1 && onoff == 1)
	{
	DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
	sMessage = "<i>*A light drizzle begins to fall on the area.*</I>";
	if (interior == 1) sMessage = "<i>*A light drizzle can be heard outside.*</I>";
	}

	if (weatheron == 0 && stormtype == 2 && onoff == 1)
	{
	DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	sMessage = "<i>*A light rain begins to fall on the area.*</I>";
	if (interior == 1) sMessage = "<i>*A light rain can be heard outside.*</I>";
	}
	
	if (weatheron == 0 && stormtype == 3 && onoff == 1)
	{
	DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	sMessage = "<i>*A light rain begins to fall on the area with dark clouds in the distance.*</I>";
	if (interior == 1)	sMessage = "<i>*A light rain can be heard outside and over-time seems to be picking up.*</I>";
	DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
	}
	
	if (weatheron == 0 && stormtype == 4 && onoff == 1)
	{
	DelayCommand(15.0, Drizzle(GetObjectByTag(area)));
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	sMessage = "<i>*A light rain begins to fall on the area with dark clouds spotted in the distance. The sound of distant thunder can be heard.*</I>";
	if (interior == 1) sMessage = "<i>*A light rain can be heard outside and the sound of distant thunder can be heard.*</I>";
	DelayCommand(delay * 1.5,HeavyRainStorm(GetObjectByTag(area)));	
	DelayCommand(delay * 3.0,ThunderStorm(GetObjectByTag(area)));
	}	
	
	//ON SWITCHES (WEATHER ALREADY ON)
	
	//DRIZZLE
	if (weatheron == 1 && stormtype == 2 && onoff == 1) //Drizzle becomes light rain.
	{
	sMessage = "<i>*The rain storm suddenly begins to pick up.*</I>";
	if (interior == 1) sMessage = "<i>*The rain outside begins to pick up.*</I>";
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	}

	if (weatheron == 1 && stormtype == 3 && onoff == 1) //Drizzle becomes
	{
	sMessage = "<i>*The rain storm suddenly begins to pick up heavily.*</I>";
	if (interior == 1) sMessage = "<i>*The rain outside begins to pick up heavily.*</I>";
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
	}
	
	if (weatheron == 1 && stormtype == 4 && onoff == 1) //Light rain becomes thunderstorm.
	{
	sMessage = "<i>*The rain storm begins to pick up heavily. The sound of thunder can be heard in the distance.*</I>";
	if (interior == 1) sMessage = "<i>*The rainstorm outside suddenly picks up heavily and the sound of thunder can be heard in the distance.*</I>";
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 2.75, ThunderStorm(GetObjectByTag(area)));
	}
	
	//LIGHT RAIN
	if (weatheron == 2 && stormtype == 3 && onoff == 1) //Light rain becomes heavy storm.
	{
	sMessage = "<i>*The rain storm suddenly begins to pick up.*</I>";
	if (interior == 1) sMessage = "<i>*The rain outside begins to pick up.*</I>";
	DelayCommand(delay / 2, LightRainStorm(GetObjectByTag(area)));
	}

	if (weatheron == 2 && stormtype == 4 && onoff == 1) //Light rain becomes thunderstorm.
	{
	sMessage = "<i>*The rain storm begins to pick up heavily. The sound of thunder can be heard in the distance.*</I>";
	if (interior == 1) sMessage = "<i>*The rainstorm outside suddenly picks up heavily and the sound of thunder can be heard in the distance.*</I>";
	HeavyRainStorm(GetObjectByTag(area));
	DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 3.0, ThunderStorm(GetObjectByTag(area)));
	}

	//HEAVY RAIN
	if (weatheron == 3 && stormtype == 4 && onoff == 1)
	{
	if (interior == 1) sMessage = "<i>*The heavy rain picks up with the sound of thunder in the area.*</I>";
	if (interior == 1) sMessage = "<i>*The rain suddenly picks up heavily with loud rumbles of thunder making the ground shake. You can see frequent lightning strikes outside if you look.*</I>";
	DelayCommand(delay, ThunderStorm(GetObjectByTag(area)));
	}

	//ON SWITCHES (DOWNGRADES) 

	//LIGHT RAIN BECOMES DRIZZLE
	if (weatheron == 2 && stormtype == 1 && onoff == 1)
	{
	sMessage = "<i>*The rain begins to let up into a drizzle.*</I>";
	if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
	DelayCommand(delay, Drizzle(GetObjectByTag(area)));
	}
	
	//HEAVY RAIN BECOMES DRIZZLE
	if (weatheron == 3 && stormtype == 1 && onoff == 1)
	{
	sMessage = "<i>*The heavy rain begins to let up into a drizzle.*</I>";
	if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
	DelayCommand(delay * 1.5, LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 2.0, Drizzle(GetObjectByTag(area)));
	}
			
	//HEAVY STORM BECOMES LIGHT RAIN
	if (weatheron == 3 && stormtype == 2 && onoff == 1)
	{
	sMessage = "<i>*The heavy rain begins to let up into a gentle shower.*</I>";
	if (interior == 1) sMessage = "<i>*The rain begins to let up outside.*</I>";
	DelayCommand(delay * 1.5, LightRainStorm(GetObjectByTag(area)));
	}

	//THUNDER STORM BECOMES DRIZZLE
	if (weatheron == 4 && stormtype == 1 && onoff == 1)
	{
	sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues and slowly lets up into a drizzle.*</I>";
	if (interior == 1) sMessage = "<i>*The thundering outside begins to let up, but the heavy rain continues and slowly lets up into a drizzle.*</I>";
	DelayCommand(delay, HeavyRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 2.0, LightRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 3.0, Drizzle(GetObjectByTag(area)));
	}
	
	//THUNDER STORM BECOMES LIGHT RAIN
	if (weatheron == 4 && stormtype == 2 && onoff == 1)
	{
	sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues and slowly lets up.*</I>";
	if (interior == 1) sMessage = "<i>*The thundering outside begins to let out, but the heavy rain continues and slowly lets up.*</I>";
	DelayCommand(delay, HeavyRainStorm(GetObjectByTag(area)));
	DelayCommand(delay * 2.0, LightRainStorm(GetObjectByTag(area)));
	}

	//THUNDER STORM BECOMES HEAVY
	if (weatheron == 4 && stormtype == 3 && onoff == 1)
	{
	sMessage = "<i>*The thunder and lightning begins to stop, but the heavy rain continues.*</I>";
	if (interior == 1) sMessage = "<i>*The thundering outside begins to let out, but the heavy rain continues.*</I>";
	DelayCommand(delay * 1.5, HeavyRainStorm(GetObjectByTag(area)));
	}
	
	SendMessageToAllPlayers(area,sMessage);
}

void RainAreaOff(string area)
{
	SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
	string sArea;
	
	while (SQLFetch() == SQL_SUCCESS)
	{
	sArea = SQLGetData(1);
	DynamicRainStorm(sArea, 0, area, 0);
	}
}


void RainAreaOn(string area)
{
	int iRoll = d100(); int stormtype;
	
	if (iRoll > 0) stormtype = 1;
	if (iRoll >= 45) stormtype = 2;
	if (iRoll >= 75) stormtype = 3;
	if (iRoll >= 90) stormtype = 4;
	
	int weatheron = GetLocalInt(GetObjectByTag(area),"WEATHERON");
	if (weatheron == stormtype) return;

	SQLExecDirect("SELECT areatag FROM cmnsee_weather_maps WHERE weather_pattern='"+SQLEncodeSpecialChars(area)+"';");
	string sArea;
	
	while (SQLFetch() == SQL_SUCCESS)
	{
	sArea = SQLGetData(1);
	DynamicRainStorm(sArea, stormtype, area, 1);
	}
}

void ChangeWeather(object oPC)
{
	object oArea = GetArea(oPC);
	int weather = GetLocalInt(oArea,"WEATHERON"); SetLocalInt(oArea,"NOHEARTBEAT",1); 
	//0 - light rain, 1 - medium rain, 2 - heavy rain, 3 - thunderstorm
	
	if (weather == 0)
	{
	SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to drizzle!");
	Drizzle(oArea);
	return;
	}
	
	if (weather == 1)
	{
	SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to light-rain!");
	LightRainStorm(oArea);
	return;
	}
	
	if (weather == 2)
	{
	StopWeather(oArea);
	SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to heavy-rain!");
	HeavyRainStorm(oArea);
	return;
	}
	
	if (weather == 3)
	{
	StopWeather(oArea);
	SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather set to thunderstorm!");
	ThunderStorm(oArea);
	return;
	}
	
	if (weather == 4)
	{
	StopWeather(oArea);
	SendMessageToPC(oPC,"CMNSEE Weather Wand: Weather reset!");
	StopWeather(oArea);
	DeleteLocalInt(oArea,"NOHEARTBEAT"); 
	}
	}
	
	int WeatherChance(string name)
	{
	if (name == "alwayson") return 100;
	if (name == "veryhigh") return 60;
	if (name == "high") return 50;
	if (name == "aboveaverage") return 45;
	if (name == "moderate") return 35;
	if (name == "occasional") return 25;
	if (name == "uncommon") return 16;
	if (name == "low") return 8;
	if (name == "rare") return 4;
	if (name == "veryrare") return 1;
	return 0;
	}
	
	void WeatherUpdate(string weatherpattern, int category, int status)
	{
	string sQuery;
	
	weatherpattern = SQLEncodeSpecialChars(weatherpattern);
	
	//1 - fog
	if (category == 1) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"',"+IntToString(status)+",'0',0)"+
	" ON DUPLICATE KEY UPDATE fog='"+IntToString(status)+"', rain='0', sunnyandclear='0';";
	
	//2 - rain
	if (category == 2) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"','0',"+IntToString(status)+",'0')"+
	" ON DUPLICATE KEY UPDATE fog='0', rain='"+IntToString(status)+"', sunnyandclear='0';";	

	//3 - clear
	if (category == 3) sQuery = "INSERT INTO cmnsee_weather_current VALUES ('"+weatherpattern+"','0','0',"+IntToString(status)+")"+
	" ON DUPLICATE KEY UPDATE fog='0', rain='0', sunnyandclear='"+IntToString(status)+"';";	
		
	SQLExecDirect(sQuery);
	}
	
	
	void HeartbeatWeather()
	{	
	if (GetLocalInt(OBJECT_SELF,"NOHEARTBEAT") == 1) return;	 
	
	SetLocalInt(OBJECT_SELF,"NOHEARTBEAT",1); 
	DelayCommand(2700.0,DeleteLocalInt(OBJECT_SELF,"NOHEARTBEAT"));

	string sQuery; string areatag = SQLEncodeSpecialChars(GetTag(OBJECT_SELF));	

	SQLExecDirect("SELECT weather_pattern from cmnsee_weather_maps WHERE areatag='"+areatag+"' AND interior=0;");
	SQLFetch();

	string weatherpattern = SQLGetData(1);
	
	if (weatherpattern == "") return;
	string sWeatherpattern = SQLEncodeSpecialChars(weatherpattern);

	sQuery = "SELECT fogchance, rainchance FROM cmnsee_weather WHERE (timewindow_start <= timewindow_end and NOW() >= timewindow_start and NOW() <= timewindow_end AND weather_pattern='"+sWeatherpattern+"') or (timewindow_end < timewindow_start and (NOW() <= timewindow_end or NOW() >= timewindow_start) AND weather_pattern='"+sWeatherpattern+"') LIMIT 1;";
	
	SQLExecDirect(sQuery); SQLFetch();

	int fogchance = WeatherChance(SQLGetData(1));
	int rainchance = WeatherChance(SQLGetData(2));
	
	int weatheron = GetLocalInt(OBJECT_SELF,"WEATHERON");
	int fogon = GetLocalInt(OBJECT_SELF,"FOGENABLED");

	int iRollFog = d100(); int iRollRain = d100();
	
	//Rain turning on.
	if (iRollRain <= rainchance)
	{
	RainAreaOn(weatherpattern);
	WeatherUpdate(weatherpattern, 2, 1);
	return;
	}

	//Rain turning off. No fog.
	if (iRollRain > rainchance && weatheron >= 1 && iRollFog > fogchance)
	{
	RainAreaOff(weatherpattern);
	WeatherUpdate(weatherpattern, 3, 2);
	return;
	}
	
	//Fog turning on.
	if (iRollFog <= fogchance)
	{

	if (weatheron == 1)
	{
	RainAreaOff(weatherpattern);
	DelayCommand((weatherdelay / 2) + 25.0, AreaFogOnOff(weatherpattern, 1));
	}
	
	if (weatheron == 2)
	{
	RainAreaOff(weatherpattern);
	DelayCommand((weatherdelay * 1.5) + 25.0, AreaFogOnOff(weatherpattern, 1));
	}
	
	if (weatheron == 3)
	{
	RainAreaOff(weatherpattern);
 	DelayCommand((weatherdelay * 3) + 25.0, AreaFogOnOff(weatherpattern, 1));
	}
	
	if (weatheron == 4)
	{
	RainAreaOff(weatherpattern);
 	DelayCommand((weatherdelay * 4) + 25.0, AreaFogOnOff(weatherpattern, 1));
	}
	
	if (weatheron > 0)
	{
	WeatherUpdate(weatherpattern, 1, 2);
	return;
	}
	
	WeatherUpdate(weatherpattern, 1, 1);
	AreaFogOnOff(weatherpattern, 1);
	return;
	}
	
	//It's sunny!
	if (iRollRain > rainchance && iRollFog > fogchance || iRollFog > fogchance)
	{
	if (weatheron >= 1) RainAreaOff(weatherpattern);
	if (weatheron == 0 && fogon == 1) AreaFogOnOff(weatherpattern, 0);	
	if (weatheron == 0 && fogon != 0) StopAllWeather(weatherpattern);
	WeatherUpdate(weatherpattern, 3, 1);
	}
	
	}

Code: Select all

cmnsee_weather_heartbeat ... add on area

#include "cmnsee_weather_includes"

	void main()
	{
	HeartbeatWeather();
	}
	

Code: Select all


Add this to on area enter script...

[code]	int fogcolor = GetLocalInt(GetArea(oPC),"FOGCOLOR");
	if (fogcolor > 0) SetFogColours(GetArea(oPC), fogcolor);
Sylael
Posts: 35
Joined: Fri Mar 25, 2016 5:46 am

Re: Sharing some of my scripts.

Unread post by Sylael »

Wow, very generous! Thank you!
User avatar
LISA100595
Retired Staff
Posts: 5202
Joined: Mon Aug 22, 2011 12:23 pm

Re: Sharing some of my scripts.

Unread post by LISA100595 »

Thanks again ComeAndSee.. very generous ! :)
Lady Elvina Aira-S'efarro - The Order of the Silver Rose
Salaria - Bounty Hunter half-sister of Darius Brothers
Angelina Northstar - Holy Warrior of Tyr / Knight of the Silver Rose
Matilda Stonehold - Honorable Sheild Dwarf
Loriah Swift - Morninglord of Lathander

Return to “NWN2 Scripting”