Just hit a slight snag..
I have probably being procrastinating on 'populating' my town with ambient life npc's and lights that turn themselves off at night, for far too long now.
Anyway, after some time spent yesterday, I have managed to get my head around the SLS2 lightable system and get my lights turning on and off depending on the time of day. This is in the main area of my town and as such, it has taken quite awhile to set up all the lights, fx etc...
Next step. I thought I would finally tackle the whole ambient citizens side of things and have managed to get my head around it (thanks entirely to Kaldor's Silverwand campaign... (that whole campaign is a golden nugget for people like myself who cannot script)).
Anyway... I have just begun creating npc's to place around my town when I have only just now realized that both SLS2 lightable system and Kaldor's ALC(ambient life) systems both require a script to be placed in the area_on_heartbeart section....
So it was at about this point I realized I had no choice, but to come here and ask the powers that be to please merge the two scripts for me.
||||||||||||||||||||||||||||||||||||||||||||||
First up is the- SLS2 Lightable System on_area_heartbeat script:
||||||||||||||||||||||||||||||||||||||||||||||
// *************************************************
// Wrapper function for SLS2 areas onHeatbeat events
// Last Updated: 2008-02-23
// Brendan 'Slayster' Ellis - http://www.slayweb.com
// *************************************************
#include "ginc_sls2"
void main() {
SLS2AreaHeartbeat(OBJECT_SELF);
}
||||||||||||||||||||||||||||||||||||||||||||||
Ok that one was nice and short....brace yourself the next one is longer.
Next up is the- Kaldor (god of all that is) script that is required to also go into the area_heartbeat section.
||||||||||||||||||||||||||||||||||||||||||||||
// 1100_hb
// by Brendan Bellina, May 2007
// updated Dec 2007 by B. Bellina
// - add automatic night lighting
// - enhance citizens so they open and close nearby doors when appearing/vanishing
// updated Jan 2008 by B. Bellina
// - add nightwalker code so that night guards can walk around at night instead of walking around during the day
// heartbeat script for area 1100
// note that all objects within all areas of the module can be managed from here.
// There are some problems in the handling of walking citizens. See comments below for details.
#include "x0_i0_transport"
//#include "nw_i0_generic" // needed for testing citizen type 2
#include "bb_force_hide_inc" // needed for force hide approach
// Constants - set as needed to match the area
// These constants are used for daytime walkers
const string CITIZEN_DAYWALK_TAG = "hilltop_citizen"; // Tag of citizens who walk around during the day
const string CITIZEN_DAYWALK_WP_PFX = "wp_citizen_spawn"; // Prefix of tag for citizen daywalkers night waypoints
const int CITIZEN_DAYWALK_WP_NUM = 6; // Number of citizen daywalkers nighttime waypoints
const string CITIZEN_DAYWALK_BARK = "nightnight_barkstring"; // barkstrings to randomly say when going home at night
// These constants are used for nighttime walkers
const string CITIZEN_NIGHTWALK_TAG = "hilltop_citizen_night"; // Tag of citizens who walk around during the night
const string CITIZEN_NIGHTWALK_WP_PFX = "wp_citizen_night_spawn"; // Prefix of tag for citizen daytime waypoints
const int CITIZEN_NIGHTWALK_WP_NUM = 1; // Number of citizen nightwalkers daytime waypoints
const string CITIZEN_NIGHTWALK_BARK = "morning_barkstring"; // barkstrings to randomly say when going home in the morning
const string LIGHT_TAG = "bb_nightlight_1100"; // Tag of controllable lights
void DaylightToggle();
void DaylightChangeActions();
void main()
{
DaylightToggle(); // Handle change of daylight events
// handle normal heartbeat events
// GetNearestObjectByTag won't work here
object oKalgor = GetObjectByTag("c_kalgor");
object oFoodMerchant = GetObjectByTag("c_foodmerchant");
object oFoodMerchant1 = GetObjectByTag("c_foodmerchant1");
object oFoodMerchant2 = GetObjectByTag("c_foodmerchant2");
object oMagicMerchant = GetObjectByTag("c_magicmerchant");
object oBookMerchant = GetObjectByTag("c_bookmerchant");
int iAmbient = Random(6)+1; // the Random function should be the number of objects with ud
switch (iAmbient)
{
case 1:
SignalEvent(oKalgor, EventUserDefined(2000));
break;
case 2:
SignalEvent(oFoodMerchant, EventUserDefined(2000));
break;
case 3:
SignalEvent(oFoodMerchant1, EventUserDefined(2000));
break;
case 4:
SignalEvent(oFoodMerchant2, EventUserDefined(2000));
break;
case 5:
SignalEvent(oMagicMerchant, EventUserDefined(2000));
break;
case 6:
SignalEvent(oBookMerchant, EventUserDefined(2000));
break;
}
object oDogWalker = GetObjectByTag("c_dogwalker");
if (!Random(20)) // 1 out of 20 chance of saying something
SignalEvent(oDogWalker, EventUserDefined(2000));
}
void DaylightToggle()
{
// For some ideas on light toggling
// see <http://nwn2forums.bi...l?post=4751499>
if (GetLocalString(OBJECT_SELF, "loc_sTimeOfDay") == "")
{
// Set the opposite to force a change event on area entry
if (GetIsDay() || GetIsDawn()) SetLocalString(OBJECT_SELF, "loc_sTimeOfDay", "Night");
else SetLocalString(OBJECT_SELF, "loc_sTimeOfDay", "Day");
}
if ( ( (GetIsDawn() || GetIsDay()) && GetLocalString(OBJECT_SELF, "loc_sTimeOfDay") == "Night")
|| ( (GetIsDusk() || GetIsNight()) && GetLocalString(OBJECT_SELF, "loc_sTimeOfDay") == "Day"))
{
if (GetLocalString(OBJECT_SELF, "loc_sTimeOfDay") == "Day")
SetLocalString(OBJECT_SELF, "loc_sTimeOfDay", "Night");
else
SetLocalString(OBJECT_SELF, "loc_sTimeOfDay", "Day");
//ExecuteScript("g_togglelights", OBJECT_SELF);
DaylightChangeActions();
}
}
void DaylightChangeActions()
{
int nNth;
// if it is dusk or night then
// turn on lights that should be
// for each visible daywalk citizen have them walk to a nighttime waypoint
// if they have a local variable wp_night then walk to that waypoint
// else randomly choose waypoint CITIZEN_DAYWALK_WP_PFX + # (where # is 1 to CITIZEN_DAYWALK_WP_NUM)
// and vanish (hide)
// for each non-visible nightwalk citizen have them jump to a waypoint
// if they were heading to a specific wp already then jump there
// or if they have a local variable wp_day then jump there
// or randomly choose waypoint CITIZEN_NIGHTWALK_WP_PFX + # (where X is 1 to CITIZEN_NIGHTWALK_WP_NUM)
// and appear
// else it is dawn or day, so
// turn off lights that should be
// for each visible nightwalk citizen have them walk to a daytime waypoint
// if they have a local variable wp_day then walk to that waypoint
// else randomly choose waypoint CITIZEN_NIGHTWALK_WP_PFX + # (where # is 1 to CITIZEN_NIGHTWALK_WP_NUM)
// and vanish (hide)
// for each non-visible daywalk citizen have them jump to a waypoint
// if they were heading to a specific wp already then jump there
// or if they have a local variable wp_night then jump there
// or randomly choose waypoint CITIZEN_DAYWALK_WP_PFX + # (where X is 1 to CITIZEN_DAYWALK_WP_NUM)
// and appear
// leave the merchants out all night calling out their wares
if (GetIsDusk() || GetIsNight())
{
// light up any placeables with tag LIGHT_TAG
string myTag = LIGHT_TAG;
object oNightlight = GetObjectByTag(myTag, nNth);
while (GetIsObjectValid(oNightlight))
{
string sUseTemplate = GetLocalString(oNightlight, "UseTemplate");
string sEffectObject = GetLocalString(oNightlight, "EffectObject");
string sEffectToApply = GetLocalString(oNightlight, "EffectToApply");
string sEffectToRemove = GetLocalString(oNightlight, "EffectToRemove");
string sLightObject = GetLocalString(oNightlight, "LightObject");
int nLight = GetLocalInt(oNightlight, "LightState"); // 0=Inactive, 1=Active (Lit)
string sSoundObject = GetLocalString(oNightlight, "SoundObject");
int nSound = GetLocalInt(oNightlight, "SoundState"); // 0=Inactive, 1=Active (Playing)
if (nLight != 1) // if not already lit
{
if (sUseTemplate == "Toggle_Candle") // Turn candle on
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_candle";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 1;
SetLocalInt(oNightlight,"LightState",nLight);
}
else if (sUseTemplate == "Toggle_Tiki") // Turn tiki on
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_torchglow";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 1;
SetLocalInt(oNightlight,"LightState",nLight);
if (sSoundObject == "") sSoundObject = myTag + "_sound";
nSound = nLight;
}
else if (sUseTemplate == "Toggle_Blue") // Turn tiki with blue flame on
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_torch_blue";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 1;
SetLocalInt(oNightlight,"LightState",nLight);
if (sSoundObject == "") sSoundObject = myTag + "_sound";
nSound = nLight;
}
if (sLightObject != "")
{
object oLightObject;
oLightObject = GetNearestObjectByTag(sLightObject, oNightlight);
SetLightActive(oLightObject, nLight);
}
if (sSoundObject != "")
{
object oSoundObject;
oSoundObject = GetNearestObjectByTag(sSoundObject, oNightlight);
if (nSound == 0) SoundObjectStop(oSoundObject);
else SoundObjectPlay(oSoundObject);
}
if (sEffectObject != "" && sEffectToApply != "")
{
object oEffectObject;
oEffectObject = GetNearestObjectByTag(sEffectObject, oNightlight);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNWN2SpecialEffectFile(sEffectToApply), oEffectObject);
}
if (sEffectObject != "" && sEffectToRemove != "")
{
object oEffectObject;
oEffectObject = GetNearestObjectByTag(sEffectObject, oNightlight);
RemoveSEFFromObject(oEffectObject, sEffectToRemove);
}
} // if (nLight != 1)
nNth++;
oNightlight = GetObjectByTag(myTag, nNth);
} // while (GetIsObjectValid(oNightlight))
// Send Daywalking citizens to their nighttime waypoints and have them vanish
nNth = 0;
object oCitizen = GetObjectByTag(CITIZEN_DAYWALK_TAG, nNth);
while(GetIsObjectValid(oCitizen))
{
if (!GetScriptHidden(oCitizen))
{
string sWp = GetLocalString(oCitizen, "wp_night"); // optional nighttime wp specified on citizen object
if (sWp == "") { sWp = CITIZEN_DAYWALK_WP_PFX+ IntToString(Random(CITIZEN_DAYWALK_WP_NUM)+1); } // random nighttime wp
SetLocalInt(oCitizen, "ALC", FALSE); // needed to keep the heartbeat script from interrupting
SetLocalString(oCitizen, "sWp_spawn", sWp); // this is so they reappear at the waypoint they were heading to when they vanished
float fDelaySec = IntToFloat(Random(8)); // stagger citizens a bit
// Not sure why SpeakOneLinerConversation below is always grabbing the lines in order instead of randomly
if (Random(3)) DelayCommand(fDelaySec, AssignCommand(oCitizen, SpeakOneLinerConversation(CITIZEN_DAYWALK_BARK)));
// Tried this approach first, but had some problems with vanishing late and stopping early.
// Not sure why sometimes the NPC's just stop or refuse to walk.
// Not sure why the commands are not executed in order so that the walker vanishes when they get there. Have no choice
// but to use DelayCommand which looks strange if the walker gets to the waypoint early.
// TravelToObject(GetObjectByTag(sWp), oCitizen, 0, 45.0);
// Not sure why when the NPC is hidden their shadow remains visible.
// DelayCommand(50.0, SetScriptHidden(oCitizen, TRUE, TRUE));
// So gave up on TravelToObject and instead modified ActionForceExit which
// still doesn't work perfectly, but at least the people usually leave the market at night.
// They may not make it home before vanishing though.
AssignCommand(oCitizen, ActionForceHide(sWp, FALSE));
}
nNth++;
oCitizen = GetObjectByTag(CITIZEN_DAYWALK_TAG, nNth);
}
// Have nightwalking citizens appear and start walking about
nNth = 0;
oCitizen = GetObjectByTag(CITIZEN_NIGHTWALK_TAG, nNth);
while(GetIsObjectValid(oCitizen))
{
if (GetScriptHidden(oCitizen))
{
// jump to the location they were heading to in case they didn't make it
string sWp = GetLocalString(oCitizen, "sWp_spawn");
if (sWp == "")
{
sWp = GetLocalString(oCitizen, "wp_day"); // optional daytime wp specified on citizen object
if (sWp == "") { sWp = CITIZEN_NIGHTWALK_WP_PFX+ IntToString(Random(CITIZEN_NIGHTWALK_WP_NUM)+1); } // random day wp
}
AssignCommand(oCitizen, ActionJumpToLocation(GetLocation(GetObjectByTag(sWp))));
// If the citizen is near an unlocked door then open it, appear, and close the door
object oHide = GetObjectByTag(sWp);
object oCurArea = GetArea(oCitizen);
object oNearDoor = GetNearestObject(OBJECT_TYPE_DOOR, oHide, 0);
if (GetArea(oNearDoor) != oCurArea) oNearDoor = OBJECT_INVALID;
int nearDoor = (GetIsObjectValid(oNearDoor) && GetDistanceBetween(oNearDoor, oHide) < 3.0);
if (nearDoor)
{
if (!GetIsOpen(oNearDoor) && !GetLocked(oNearDoor))
AssignCommand(oNearDoor, ActionOpenDoor(oNearDoor));
else
nearDoor = 0;
}
if (nearDoor)
DelayCommand(1.5f, SetScriptHidden(oCitizen, FALSE, FALSE));
else
SetScriptHidden(oCitizen, FALSE, FALSE);
if (nearDoor)
AssignCommand(oCitizen, ActionCloseDoor(oNearDoor));
SetLocalInt(oCitizen, "ALC", TRUE); // Allow Ambient Life again
}
nNth++;
oCitizen = GetObjectByTag(CITIZEN_NIGHTWALK_TAG, nNth);
}
/*
// Special handling for citizen type 2 using waypoints
// Trying to get someone to walk from home in the morning and shop
// at the market all day (using ambient mobile animation), and then
// at night walk home and vanish until morning (using a scripted
// waypoint).
// This didn't work. The citizen would just walk back and forth all day.
oCitizen = GetObjectByTag("hilltop_citizen_1");
while(GetIsObjectValid(oCitizen))
{
SetLocalInt(oCitizen, "ALC", FALSE); // stop ambient mobile behavior
AssignCommand(oCitizen, SetWalkCondition(NW_WALK_FLAG_CONSTANT, TRUE)); // Start walking home
AssignCommand(oCitizen, SetWalkCondition(NW_WALK_FLAG_PAUSED, FALSE)); // Start walking home
// the vanish will be handled by the creature's wp script (wp_tag).
}
*/
// Put the guard dog to sleep
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectSleep(), GetObjectByTag("c_dogguard"));
// Hide the blacksmith in the blacksmith shop
//AssignCommand(GetObjectByTag("c_blacksmith"), ActionForceHide("WP_blacksmith_night", FALSE));
//AssignCommand(GetObjectByTag("c_blacksmith"), ActionForceMoveToObject(GetObjectByTag("WP_blacksmith_night"), FALSE, 0.0f, 15.0f));
//ActionDoCommand(AssignCommand(GetObjectByTag("c_blacksmith"), SetScriptHidden(GetObjectByTag("c_blacksmith"), TRUE, TRUE)));
SetScriptHidden(GetObjectByTag("c_blacksmith"), TRUE, TRUE);
}
else
{
// darken any placeables with tag LIGHT_TAG
string myTag = LIGHT_TAG;
object oNightlight = GetObjectByTag(myTag, nNth);
while (GetIsObjectValid(oNightlight))
{
string sUseTemplate = GetLocalString(oNightlight, "UseTemplate");
string sEffectObject = GetLocalString(oNightlight, "EffectObject");
string sEffectToApply = GetLocalString(oNightlight, "EffectToApply");
string sEffectToRemove = GetLocalString(oNightlight, "EffectToRemove");
string sLightObject = GetLocalString(oNightlight, "LightObject");
int nLight = GetLocalInt(oNightlight, "LightState"); // 0=Inactive, 1=Active (Lit)
string sSoundObject = GetLocalString(oNightlight, "SoundObject");
int nSound = GetLocalInt(oNightlight, "SoundState"); // 0=Inactive, 1=Active (Playing)
if (nLight == 1) // if lit
{
if (sUseTemplate == "Toggle_Candle") // Turn candle off
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_candle";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 0;
SetLocalInt(oNightlight,"LightState",nLight);
sEffectToRemove = sEffectToApply;
sEffectToApply = "";
}
else if (sUseTemplate == "Toggle_Tiki") // Turn tiki off
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_torchglow";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 0;
SetLocalInt(oNightlight,"LightState",nLight);
if (sSoundObject == "") sSoundObject = myTag + "_sound";
nSound = nLight;
sEffectToRemove = sEffectToApply;
sEffectToApply = "";
}
else if (sUseTemplate == "Toggle_Blue") // Turn tiki with blue flame off
{
if (sEffectObject == "") sEffectObject = myTag + "_effect";
if (sEffectToApply == "") sEffectToApply = "fx_torch_blue";
if (sLightObject == "") sLightObject = myTag + "_light";
nLight = 0;
SetLocalInt(oNightlight,"LightState",nLight);
if (sSoundObject == "") sSoundObject = myTag + "_sound";
nSound = nLight;
sEffectToRemove = sEffectToApply;
sEffectToApply = "";
}
if (sLightObject != "")
{
object oLightObject;
oLightObject = GetNearestObjectByTag(sLightObject, oNightlight);
SetLightActive(oLightObject, nLight);
}
if (sSoundObject != "")
{
object oSoundObject;
oSoundObject = GetNearestObjectByTag(sSoundObject, oNightlight);
if (nSound == 0) SoundObjectStop(oSoundObject);
else SoundObjectPlay(oSoundObject);
}
if (sEffectObject != "" && sEffectToApply != "")
{
object oEffectObject;
oEffectObject = GetNearestObjectByTag(sEffectObject, oNightlight);
ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNWN2SpecialEffectFile(sEffectToApply), oEffectObject);
}
if (sEffectObject != "" && sEffectToRemove != "")
{
object oEffectObject;
oEffectObject = GetNearestObjectByTag(sEffectObject, oNightlight);
RemoveSEFFromObject(oEffectObject, sEffectToRemove);
}
} // if (nLight == 1)
nNth++;
oNightlight = GetObjectByTag(myTag, nNth);
} // while (GetIsObjectValid(oNightlight))
// Send Nightwalking citizens to their daytime waypoints and have them vanish
nNth = 0;
object oCitizen = GetObjectByTag(CITIZEN_NIGHTWALK_TAG, nNth);
while(GetIsObjectValid(oCitizen))
{
if (!GetScriptHidden(oCitizen))
{
string sWp = GetLocalString(oCitizen, "wp_day"); // optional daytime wp specified on citizen object
if (sWp == "") { sWp = CITIZEN_NIGHTWALK_WP_PFX+ IntToString(Random(CITIZEN_NIGHTWALK_WP_NUM)+1); } // random day wp
SetLocalInt(oCitizen, "ALC", FALSE); // needed to keep the heartbeat script from interrupting
SetLocalString(oCitizen, "sWp_spawn", sWp); // this is so they reappear at the waypoint they were heading to when they vanished
float fDelaySec = IntToFloat(Random(8)); // stagger citizens a bit
// Not sure why SpeakOneLinerConversation below is always grabbing the lines in order instead of randomly
if (Random(3)) DelayCommand(fDelaySec, AssignCommand(oCitizen, SpeakOneLinerConversation(CITIZEN_NIGHTWALK_BARK)));
AssignCommand(oCitizen, ActionForceHide(sWp, FALSE));
}
nNth++;
oCitizen = GetObjectByTag(CITIZEN_NIGHTWALK_TAG, nNth);
}
// Have daywalking citizens appear and start walking about
nNth = 0;
oCitizen = GetObjectByTag(CITIZEN_DAYWALK_TAG, nNth);
while(GetIsObjectValid(oCitizen))
{
if (GetScriptHidden(oCitizen))
{
// jump to the location they were heading to in case they didn't make it
string sWp = GetLocalString(oCitizen, "sWp_spawn");
if (sWp == "")
{
sWp = GetLocalString(oCitizen, "wp_night"); // optional nighttime wp specified on citizen object
if (sWp == "") { sWp = CITIZEN_DAYWALK_WP_PFX+ IntToString(Random(CITIZEN_DAYWALK_WP_NUM)+1); } // random nighttime wp
}
AssignCommand(oCitizen, ActionJumpToLocation(GetLocation(GetObjectByTag(sWp))));
// If the citizen is near an unlocked door then open it, appear, and close the door
object oHide = GetObjectByTag(sWp);
object oCurArea = GetArea(oCitizen);
object oNearDoor = GetNearestObject(OBJECT_TYPE_DOOR, oHide, 0);
if (GetArea(oNearDoor) != oCurArea) oNearDoor = OBJECT_INVALID;
int nearDoor = (GetIsObjectValid(oNearDoor) && GetDistanceBetween(oNearDoor, oHide) < 3.0);
if (nearDoor)
{
if (!GetIsOpen(oNearDoor) && !GetLocked(oNearDoor))
AssignCommand(oNearDoor, ActionOpenDoor(oNearDoor));
else
nearDoor = 0;
}
if (nearDoor)
DelayCommand(1.5f, SetScriptHidden(oCitizen, FALSE, FALSE));
else
SetScriptHidden(oCitizen, FALSE, FALSE);
if (nearDoor)
AssignCommand(oCitizen, ActionCloseDoor(oNearDoor));
SetLocalInt(oCitizen, "ALC", TRUE); // Allow Ambient Life again
}
nNth++;
oCitizen = GetObjectByTag(CITIZEN_DAYWALK_TAG, nNth);
}
/*
// Special handling for citizen type 2 using waypoints
// This didn't work. The citizen would walk back and forth all day
// between the waypoint and town, stopping only to visit in town for
// a short time.
oCitizen = GetObjectByTag("hilltop_citizen_1");
while(GetIsObjectValid(oCitizen))
{
// Time to appear
SetScriptHidden(oCitizen, FALSE, FALSE); // make creature visible
SetLocalInt(oCitizen, "ALC", TRUE); // start ambient mobile behavior
}
*/
// Wake up the guard dog
object oTarget = GetObjectByTag("c_dogguard");
effect eEffect = GetFirstEffect(oTarget);
while (GetIsEffectValid(eEffect))
{
if (GetEffectType(eEffect)==EFFECT_TYPE_SLEEP) RemoveEffect(oTarget, eEffect);
&
Modifié par dickel, 19 avril 2011 - 08:47 .





Retour en haut







