#include "nwnx_chat" #include "inc_system_const" #include "nwnx_events" #include "colors_inc" #include "inc_helper_funcs" //////////////////////////////// // RADIO SYSTEM CONFIGURATION // //////////////////////////////// // The number of channels available to players using radios. // Default: 10 const int RADIO_NUMBER_OF_CHANNELS = 10; ////////////////////// // SYSTEM CONSTANTS // ////////////////////// // Resref and tag of the radio NPC which handles distributing messages. const string RADIO_NPC = "radio_npc"; //////////////// // PROTOTYPES // //////////////// void RADIO_OnNWNXChat(); // Call this on the module's OnEnter event. // It will enable NWNX_Chat if the entering object is a PC (not a DM) void RADIO_OnModuleEnter(); // Call this on the module's OnExit event. // It will update NWNX_Chat if the exiting object is a PC (not a DM) void RADIO_OnModuleLeave(); // This is called in the REO_MOD_USEITEM script. // It will change the channel a PC is tuned into. A PC may only tune into one // channel at a time even if they have more than one radio in their inventory. void RADIO_ChangeChannel(); // This is called in the REO_MOD_USEITEM script. // It will toggle a radio's power. If the PC already has a radio turned on, they cannot // turn on a second and will receive an error message stating so. void RADIO_TogglePower(); // Call this on your module's OnUnacquireItem event. // If a radio is lost and it's turned on then the variables on both the item and the PC's database // are removed. This prevents other players from acquiring the radio and causing the system to bug out // because they're tuned into more than one channel. void RADIO_OnModuleUnacquire(); // Call this on your module's OnAcquireItem event. // If a radio is acquired and it's turned on then the variables on both the item and the PC's database // are removed. This prevents other players from acquiring the radio and causing the system to bug out // because they're tuned into more than one channel. void RADIO_OnModuleAcquire(); /////////////// // FUNCTIONS // /////////////// void RADIO_OnNWNXChat() { object oPC = OBJECT_SELF; object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); int iChannel = GetLocalInt(oDatabase, RADIO_CHANNEL); struct chat_message stMessage = NWNXChat_GetMessage(); // This only matters when a PC uses the party chat channel if(stMessage.Mode != CHAT_CHANNEL_PARTY) return; NWNXChat_SuppressMessage(); object oNPC = GetObjectByTag(RADIO_NPC); // Can't send messages without a radio turned on. if(iChannel <= 0) { SendMessageToPC(oPC, ColorTokenRed() + "You must have a radio to communicate over party chat." + ColorTokenEnd()); return; } string sSenderName = ColorToken(115, 101, 206) + "(Ch. " + IntToString(iChannel) + ") " + GetName(oPC) + ": " + ColorTokenEnd(); // Why is there no CHAT_CHANNEL_DM?? //NWNXChat_SendMessage(oNPC, CHAT_CHANNEL_DM, sSenderName = stMessage.Text + ColorTokenEnd()); object oMember = GetFirstPC(); while(GetIsObjectValid(oMember)) { object oMemberDatabase = GetItemPossessedBy(oMember, PC_DATABASE); int iMemberChannel = GetLocalInt(oMemberDatabase, RADIO_CHANNEL); // Message is sent to anyone if they've got a radio tuned in to the correct channel. They do not need to be // in the same party. if(iMemberChannel == iChannel || GetIsDM(oMember)) { NWNXChat_SendMessage(oNPC, CHAT_CHANNEL_PRIVATE, sSenderName + ColorTokenWhite() + stMessage.Text + ColorTokenEnd(), oMember); } oMember = GetNextPC(); } } void RADIO_OnModuleEnter() { object oPC = GetEnteringObject(); if(!GetIsPC(oPC) || GetIsDM(oPC)) return; NWNXChat_PCEnter(oPC); } void RADIO_OnModuleLeave() { object oPC = GetExitingObject(); if(!GetIsPC(oPC) || GetIsDM(oPC)) return; NWNXChat_PCExit(oPC); } void RADIO_ChangeChannel() { object oPC = OBJECT_SELF; object oRadio = GetEventItem(); object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); int iRadioChannel = GetLocalInt(oDatabase, RADIO_CHANNEL); int bPoweredOn = GetLocalInt(oRadio, RADIO_POWER); // Can't change channel unless the radio is turned on if(!bPoweredOn) { SendMessageToPC(oPC, ColorTokenRed() + "You must turn the radio on first." + ColorTokenEnd()); return; } iRadioChannel++; // Can't cycle beyond the maximum number of channels if(iRadioChannel > RADIO_NUMBER_OF_CHANNELS) { iRadioChannel = 1; } // Mark the new channel, inform player of new channel, and update the radio's name to reflect the new channel SetLocalInt(oDatabase, RADIO_CHANNEL, iRadioChannel); SendMessageToPC(oPC, ColorTokenPurple() + "Radio Channel: " + IntToString(iRadioChannel) + ColorTokenEnd()); UpdateItemName(oRadio); } void RADIO_TogglePower() { object oPC = OBJECT_SELF; object oRadio = GetEventItem(); object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); int iRadioChannel = GetLocalInt(oDatabase, RADIO_CHANNEL); int bPoweredOn = GetLocalInt(oRadio, RADIO_POWER); int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER); // Another radio is already turned on. Can't turn on another. if(iRadioChannel > 0 && !bPoweredOn) { SendMessageToPC(oPC, ColorTokenRed() + "Another radio is already turned on. You may only have one radio turned on at a time." + ColorTokenEnd()); return; } // It's powered on right now, but we're turning it off. Remove variables from the owner and the radio itself if(bPoweredOn) { DeleteLocalInt(oDatabase, RADIO_CHANNEL); DeleteLocalInt(oRadio, RADIO_POWER); DeleteLocalInt(oRadio, RADIO_PC_ID_ENABLED_BY); SendMessageToPC(oPC, ColorTokenPurple() + "Radio powered off." + ColorTokenEnd()); } // It's powered off right now, and we're turning it on. Add variables to the owner and the radio itself else { SetLocalInt(oDatabase, RADIO_CHANNEL, 1); SetLocalInt(oRadio, RADIO_POWER, TRUE); SetLocalInt(oRadio, RADIO_PC_ID_ENABLED_BY, iPCID); SendMessageToPC(oPC, ColorTokenPurple() + "Radio powered on." + ColorTokenEnd()); SendMessageToPC(oPC, ColorTokenPurple() + "Radio Channel: 1" + ColorTokenEnd()); } UpdateItemName(oRadio); } void RADIO_OnModuleUnacquire() { object oPC = GetModuleItemLostBy(); object oRadio = GetModuleItemLost(); string sResref = GetResRef(oRadio); if(sResref == RADIO_RESREF) { object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); int bPoweredOn = GetLocalInt(oRadio, RADIO_POWER); if(bPoweredOn) { DeleteLocalInt(oDatabase, RADIO_CHANNEL); DeleteLocalInt(oRadio, RADIO_POWER); UpdateItemName(oRadio); } } } void RADIO_OnModuleAcquire() { object oPC = GetModuleItemAcquiredBy(); object oDatabase = GetItemPossessedBy(oPC, PC_DATABASE); object oRadio = GetModuleItemAcquired(); string sResref = GetResRef(oRadio); int iPCID = GetLocalInt(oDatabase, PC_ID_NUMBER); int iRadioPCID = GetLocalInt(oRadio, RADIO_PC_ID_ENABLED_BY); if(sResref == RADIO_RESREF) { int bPoweredOn = GetLocalInt(oRadio, RADIO_POWER); // The radio must be turned on and the person who turned it on must not be // the current owner. I.E: When the server resets, the OnAcquire event is fired // for all items. This check prevents the radio's status from being reset when // that happens. if(bPoweredOn && iPCID != iRadioPCID) { DeleteLocalInt(oDatabase, RADIO_CHANNEL); DeleteLocalInt(oRadio, RADIO_POWER); UpdateItemName(oRadio); } } } // Error checking //void main(){}