Merge branch 'master' of github.com:SWG-Source/dsrc

This commit is contained in:
Cekis
2020-11-15 14:49:56 -05:00
8 changed files with 179 additions and 89 deletions

View File

@@ -1325,4 +1325,4 @@ i i h i f f f f f f f s p
1187928 1187917 object/cell/cell.iff 11 0 0 0 1 0 0 0 $|
1187929 1187917 object/cell/cell.iff 12 0 0 0 1 0 0 0 $|
-19844656 0 object/tangible/planet_map_location/city.iff 0 1570.98 5 1342.91 0.938444 0 0.345432 0 $|
-990069 0 object/tangible/ground_spawning/patrol_waypoint.iff 0 1469.301 4 1334.822 1 0 0 0 fishing.master_object $|
-90069420 0 object/tangible/theme_park/invisible_object.iff 0 1475.19 5 1371.49 1 0 0 0 fishing.controller $|

View File

@@ -159,6 +159,13 @@ public class holiday_controller extends script.base_script
}
return SCRIPT_CONTINUE;
}
// Make sure CSRs can't take the master object on a stroll down Amidala's Beach when they should be home doing their homework
public int OnAboutToBeTransferred(obj_id self, obj_id destContainer, obj_id transferer) throws InterruptedException {
sendSystemMessageTestingOnly(transferer, "You cannot move this item!");
return SCRIPT_OVERRIDE;
}
private void startHolidayEvent(obj_id speaker, String holidayName, String holidayRunning, int holidayStatus) throws InterruptedException
{
if (holidayRunning == null)

View File

@@ -0,0 +1,64 @@
package script.fishing;
import script.dictionary;
import script.library.fishing;
import script.location;
import script.obj_id;
public class controller extends script.base_script {
public controller()
{
}
/*
* The purpose of the controller is really only to spawn and setup the master object
* Everything fishing related that is stored or updated should be going in the master object via messageTo fishing.getMasterFishingObject()
*/
public static final String CONTROLLER = "object/tangible/ground_spawning/patrol_waypoint.iff";
public int OnInitialize(obj_id self) throws InterruptedException {
setName(self, "Fishing Controller");
location selfLoc = getLocation(self);
obj_id objects[] = getObjectsInRange(selfLoc, 0.1f);
boolean exists = false;
if (objects != null || objects.length > 0)
{
for (obj_id object : objects) {
if ((getTemplateName(object)).equals(CONTROLLER)) {
exists = true;
}
}
}
if (!exists)
{
createMasterObject(self);
}
return SCRIPT_CONTINUE;
}
// Make sure CSRs can't take the master object on a stroll down Amidala's Beach when they should be home doing their homework
public int OnAboutToBeTransferred(obj_id self, obj_id destContainer, obj_id transferer) throws InterruptedException {
sendSystemMessageTestingOnly(transferer, "You cannot move this item!");
return SCRIPT_OVERRIDE;
}
public int createMasterObject(obj_id self, dictionary params) throws InterruptedException {
createMasterObject(self);
return SCRIPT_CONTINUE;
}
/**
* createMasterObject
* Spawns the fishing master object and persists it to the database
* We need to persist this object because it contains records of fishing (e.g. leaderboard)
* and should not be deleted at restart (that would be very bad)
*/
public void createMasterObject(obj_id self) throws InterruptedException {
obj_id object = createObject(CONTROLLER, getLocation(self));
attachScript(object, "fishing.master_object");
persistObject(object);
}
}

View File

@@ -13,41 +13,92 @@ public class master_object extends script.base_script {
public static final String OBJVAR_LEADERBOARD_UPDATE_TIME = "leaderboards_last_updated";
public static final String OBJVAR_CONTROLLER_SETUP_TIME = "master_fishing_object_created";
public int OnInitialize(obj_id self) throws InterruptedException {
if(!hasObjVar(self, OBJVAR_CONTROLLER_SETUP_TIME)) {
messageTo(self, "handleSetupMasterFishingObject", null, 3, true);
}
setName(self, "Master Fishing Object [do not move]");
public int OnAttach(obj_id self) throws InterruptedException {
messageTo(self, "handleControllerInitialization", null, 120f, true);
return SCRIPT_CONTINUE;
}
public int OnInitialize(obj_id self) throws InterruptedException {
messageTo(self, "handleControllerInitialization", null, 120f, true);
return SCRIPT_CONTINUE;
}
// Make sure CSRs can't take the master object on a stroll down Amidala's Beach when they should be home doing their homework
public int OnAboutToBeTransferred(obj_id self, obj_id destContainer, obj_id transferer) throws InterruptedException {
sendSystemMessageTestingOnly(transferer, "You cannot move this item!");
return SCRIPT_OVERRIDE;
}
/**
* handleControllerInitialization
* Handles the setup of the controller and triggers updates to critical functions
*/
public int handleControllerInitialization(obj_id self, dictionary params) throws InterruptedException {
setName(self, "Master Fishing Object");
if(!hasObjVar(self, OBJVAR_CONTROLLER_SETUP_TIME)) {
messageTo(self, "handleSetupMasterFishingObject", null, 20f, true);
}
// Update the leader board weekly, and force update if 7-days have passed since last update (in case of offline fails to trigger update)
createWeeklyAlarmClock(self, "handleUpdateLeaderboards", null, DAY_OF_WEEK_THU, 19, 0,0);
if (!hasObjVar(self, OBJVAR_LEADERBOARD_UPDATE_TIME)) {
messageTo(self, "handleUpdateLeaderboards", null, 120, false);
messageTo(self, "handleWeeklyUpdateLeaderboards", null, 20f, true);
}
if(getCalendarTime() > getIntObjVar(self, OBJVAR_LEADERBOARD_UPDATE_TIME) + 604800) {
messageTo(self, "handleUpdateLeaderboards", null, 120, false);
messageTo(self, "handleWeeklyUpdateLeaderboards", null, 20f, true);
}
return SCRIPT_CONTINUE;
}
/**
* handleSetupMasterFishingObject
* Handles all required setup for the Fishing Object, intended to only be called on a fresh server once
*/
public int handleSetupMasterFishingObject(obj_id self, dictionary params) throws InterruptedException {
if(!hasObjVar(self, OBJVAR_CONTROLLER_SETUP_TIME)) {
if (isIdValid(self)) {
setObjVar(getPlanetByName("tatooine"), "master_fishing_object", self);
setObjVar(self, OBJVAR_CONTROLLER_SETUP_TIME, getCalendarTime());
fishing.handleConstructElusiveFishTable(self);
LOG("fishing", "Created Master Fishing Object ("+ self +") and attached to Tatooine Planet Object.");
} else {
LOG("fishing", "[ERROR FEATURE-FATAL]: Attempted to create Master Fishing Object but it failed.");
}
setObjVar(getPlanetByName("tatooine"), fishing.OBJVAR_PLANET_OBJECT_REFERENCE, self);
setObjVar(self, OBJVAR_CONTROLLER_SETUP_TIME, getCalendarTime());
String[] elusiveFishTable = dataTableGetStringColumn(fishing.ELUSIVE_FISH_TABLE, "fish");
for (String fish : elusiveFishTable) {
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fish, 0);
}
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TOTAL, 0);
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TABLE_MADE, 1);
LOG("fishing", "Created Master Fishing Object ("+ self +") and completed setupMasterFishingObject.");
return SCRIPT_CONTINUE;
}
/**
* handleUpdateElusiveFishLeaderboard
* Adds an array of information to the elusive fish leaderboard as passed in fishing.giveElusiveFishRewards
*/
public int handleUpdateElusiveFishLeaderboard(obj_id self, dictionary params) throws InterruptedException {
String[] fishInfo = params.getStringArray("elusiveFishLeaderboardItems");
String fishType = params.getString("fishType");
// update total elusive fish caught count
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TOTAL, getIntObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TOTAL)+1);
// update specific elusive fish caught count
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType, getIntObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType)+1);
// add leaderboard entry
if(!hasObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL)) {
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL, 1);
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+"0", fishInfo);
} else {
int leaderboardEntries = getIntObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL);
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+leaderboardEntries, fishInfo);
setObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL, ++leaderboardEntries);
}
return SCRIPT_CONTINUE;
}
public int handleUpdateLeaderboards(obj_id self, dictionary params) throws InterruptedException {
/**
* handleWeeklyUpdateLeaderboards
* Called when it is time to update all of the fishing leaderboards (does not include elusive fish as that is lifetime per galaxy)
*/
public int handleWeeklyUpdateLeaderboards(obj_id self, dictionary params) throws InterruptedException {
// placeholder for weekly updated leaderboards
setObjVar(self, OBJVAR_LEADERBOARD_UPDATE_TIME, getCalendarTime());
return SCRIPT_CONTINUE;
}
}

View File

@@ -81,7 +81,7 @@ public class pole extends script.base_script
}
if(item == menu_info_types.SERVER_MENU30) {
if(fishing.getElusiveFishRewardedCount() > 0) {
fishing.showElusiveFishLeaderboard(player, null);
fishing.showElusiveFishLeaderboard(player);
} else {
sendSystemMessageTestingOnly(player, "No ELUSIVE Fish have been captured yet so the Leaderboard is empty.");
}

View File

@@ -27,22 +27,23 @@ public class fishing extends script.base_script {
public static final int ELUSIVE_FISH_MAX_GALAXY = 70;
public static final double ELUSIVE_FISH_CHANCE = 0.005d; // 1% chance default
public static final String ELUSIVE_FISH_TABLE = "datatables/fishing/fish/elusive_fish.iff";
public static final obj_id FISHING_OBJECT = getObjIdObjVar(getPlanetByName("tatooine"), "master_fishing_object");
public static final String OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT = "fishing.elusive_fish_caught"; // count also used for guild/city travel point perk
public static final String OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL = "elusive_fish.leaderboard_total";
public static final String OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE = "elusive_fish.leaderboard.e_";
public static final String OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE = "elusive_fish.count_table.fish_";
public static final String OBJVAR_ELUSIVE_FISH_COUNT_TABLE_MADE = "elusive_fish.count_table_made";
public static final String OBJVAR_ELUSIVE_FISH_COUNT_TOTAL= "elusive_fish.count_rewarded_total";
public static final String OBJVAR_PLANET_OBJECT_REFERENCE = "master_fishing_object";
/**
* getMasterFishingObject
* The Master Fishing Object is an invisible ghost object which exists in the world to store information about fishing records and data (as ObjVars).
* It is in the tatooine_5_5 buildout and initialized via fishing.master_object script
* A controller in tatooine_5_5 buildout uses fishing.controller script to handle MFO creation.
* The controller spawns the master object if it doesn't exist OnInitialize, attaches fishing.master_object, and persists to the world
* @return The obj_id of the master fishing object
*/
public static obj_id getMasterFishingObject() throws InterruptedException {
return getObjIdObjVar(getPlanetByName("tatooine"), "master_fishing_object");
return getObjIdObjVar(getPlanetByName("tatooine"), OBJVAR_PLANET_OBJECT_REFERENCE);
}
/**
@@ -171,18 +172,18 @@ public class fishing extends script.base_script {
*/
public static boolean hasElusiveFishBeenCollected(obj_id fish) throws InterruptedException {
String fishType = getStringObjVar(fish, "fish.name");
return getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType) >= 1;
return getIntObjVar(getMasterFishingObject(), OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType) >= 1;
}
/**
* isWinningElusiveFish - To be initiated by fishing process when player catches a fish
* handleElusiveFishRollAndWin - To be initiated by fishing process when player catches a fish
* This is triggered at the point of the fish actually being caught and transferred to the player, then the system rolls to
* decide if it should make this an elusive fish.
* @param player the player fishing
* @param fish the fish the player caught
*/
public static void handleElusiveFishRollAndWin(obj_id player, obj_id fish) throws InterruptedException {
if(!isIdValid(FISHING_OBJECT)) {
if(!isIdValid(player) || !isIdValid(fish)) {
return;
}
if(!utils.checkConfigFlag("Fishing", "elusiveFishEnabled")) {
@@ -213,21 +214,19 @@ public class fishing extends script.base_script {
*/
public static void giveElusiveFishRewards(obj_id player, obj_id fish) throws InterruptedException {
obj_id masterFishingObject = getMasterFishingObject();
dictionary d = new dictionary();
String fishType = getStringObjVar(fish, "fish.name");
if(!badge.hasBadge(player, "bdg_fishing_elusive_fish_"+fishType)) {
badge.grantBadge(player, "bdg_fishing_elusive_fish_"+fishType);
}
// make the fish elusive
attachScript(fish, "fishing.elusive_fish");
// count this specific fish as caught
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType, getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fishType)+1);
// count the overall number of elusive fish caught
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TOTAL, getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TOTAL)+1);
// update the player's personal count of caught elusive fish (this is also used for granting travel point perks)
if(!hasObjVar(player, OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT)) {
setObjVar(player, OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT, 1);
} else {
setObjVar(player, OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT, getIntObjVar(player, "elusive_fish_caught")+1);
setObjVar(player, OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT, getIntObjVar(player, OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT)+1);
}
// pack fish information and send to leaderboard, then log the catch
String species = getFishSpecies(fish);
@@ -240,12 +239,14 @@ public class fishing extends script.base_script {
(int)getFishCaughtLocation(fish).x+", "+(int)getFishCaughtLocation(fish).z,
getFishCaughtTimeReadable(fish),
};
d.put("fishType", fishType);
d.put("elusiveFishLeaderboardItems", elusiveFishLeaderboardItems);
if(hasElusiveFishBeenCollected(fish)) {
if (utils.checkConfigFlag("Fishing", "elusiveFishShowDuplicatesOnLeaderboard")) {
handleUpdateElusiveFishLeaderboard(elusiveFishLeaderboardItems);
messageTo(masterFishingObject, "handleUpdateElusiveFishLeaderboard", d, 6f, true);
}
} else {
handleUpdateElusiveFishLeaderboard(elusiveFishLeaderboardItems);
messageTo(masterFishingObject, "handleUpdateElusiveFishLeaderboard", d, 6f, true);
}
CustomerServiceLog("elusive_fish", getPlayerName(player)+" ("+player+") caught elusive fish "+fishType+" ("+fish+")");
}
@@ -276,7 +277,7 @@ public class fishing extends script.base_script {
* @return the number of elusive fish that have been caught on the cluster
*/
public static int getElusiveFishRewardedCount() throws InterruptedException {
return getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TOTAL);
return getIntObjVar(getMasterFishingObject(), OBJVAR_ELUSIVE_FISH_COUNT_TOTAL);
}
/**
@@ -285,23 +286,22 @@ public class fishing extends script.base_script {
* @param fish the name of the elusive fish (reference elusive fish datatable) e.g. bluefish_dantooine
*/
public static int getCountOfSpecificElusiveFishRewarded(String fish) throws InterruptedException {
return getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fish);
return getIntObjVar(getMasterFishingObject(), OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fish);
}
/**
* showElusiveFishLeaderboard
* Constructs and then shows the player a SUI Table containing the Elusive Fish Leaderboard
* @param player the player who should get the SUI window
* @param params currently unused dictionary of params for future implementation
*/
public static void showElusiveFishLeaderboard(obj_id player, dictionary params) throws InterruptedException {
public static void showElusiveFishLeaderboard(obj_id player) throws InterruptedException {
int fishCount = getElusiveFishRewardedCount();
String prompt = "Showing all caught ELUSIVE Fish on the " + getClusterName() + " Galaxy as of " + getCalendarTimeStringGMT(getCalendarTime()) + "\n\n";
String[] columns = { "Type", "Planet", "Length", "Angler", "Location", "Time Caught" };
String[] columnTypes = { "text", "text", "text", "text", "text", "text" };
String[][] leaderboardData = new String[fishCount][columns.length];
for (int i = 0; i < fishCount; i++) {
String[] leaderboardEntry = getStringArrayObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+i);
String[] leaderboardEntry = getStringArrayObjVar(getMasterFishingObject(), OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+i);
for (int a = 0; a < leaderboardEntry.length; a++) {
leaderboardData[i][a] = leaderboardEntry[a];
}
@@ -309,38 +309,6 @@ public class fishing extends script.base_script {
sui.table(player, player, sui.OK_ONLY, "ELUSIVE Fish Leaderboard", "noHandler", prompt, columns, columnTypes, leaderboardData, true, true);
}
/**
* handleUpdateElusiveFishLeaderboard
* Adds an array of information to the elusive fish leaderboard as passed in giveElusiveFishRewards
* @param fishInfo the packaged array of fish info to add to the leaderboard
*/
public static void handleUpdateElusiveFishLeaderboard(String[] fishInfo) throws InterruptedException {
if(!hasObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL)) {
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL, 1);
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+"0", fishInfo);
} else {
int leaderboardEntries = getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL);
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+leaderboardEntries, fishInfo);
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL, ++leaderboardEntries);
}
}
/**
* handleConstructElusiveFishTable
* This is used to setup the ObjVars for all elusive fish (as a part of master fish object creation)
*/
public static void handleConstructElusiveFishTable(obj_id masterObject) throws InterruptedException {
if(hasObjVar(masterObject, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_MADE)) {
return;
}
String[] elusiveFishTable = dataTableGetStringColumn(ELUSIVE_FISH_TABLE, "fish");
for (String fish : elusiveFishTable) {
setObjVar(masterObject, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fish, 0);
}
setObjVar(masterObject, OBJVAR_ELUSIVE_FISH_COUNT_TOTAL, 0);
setObjVar(masterObject, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_MADE, 1);
}
/**
* getElusiveFishCountTableTree
* Returns a dictionary containing the counts of each elusive fish capture
@@ -354,23 +322,4 @@ public class fishing extends script.base_script {
return d;
}
/**
* clearElusiveFishLeaderboardAndTableDebugTestingOnly (for debug use only)
* Resets the Elusive Fish table and leaderboard as though you're on a brand new server
*/
public static void clearElusiveFishLeaderboardAndTableDebugTestingOnly() throws InterruptedException {
String[] elusiveFishTable = dataTableGetStringColumn(ELUSIVE_FISH_TABLE, "fish");
for (String fish : elusiveFishTable) {
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_TREE+fish, 0);
}
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TOTAL, 0);
setObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_COUNT_TABLE_MADE, 1);
int leaderboardEntries = getIntObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL);
for (int i = 0; i <= leaderboardEntries; i++) {
removeObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_TREE+i);
}
removeObjVar(FISHING_OBJECT, OBJVAR_ELUSIVE_FISH_LEADERBOARD_COUNT_TOTAL);
}
}

View File

@@ -983,6 +983,7 @@ public class veteran_rewards extends script.base_script
int bp = sui.getIntButtonPressed(params);
if ((bp == sui.BP_OK) && (isValidLocationForCts(self, true)))
{
removeObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT); // you can't keep your old galaxy's elusive fish record when you CTS
performFreeCts(self, destinationGalaxy, destinationCharacterName);
utils.setScriptVar(self, SCRIPTVAR_FREE_CTS_REQUEST_TIMEOUT, getGameTime() + 300);
}
@@ -1345,6 +1346,7 @@ public class veteran_rewards extends script.base_script
if ((bp == sui.BP_OK) && isValidLocationForCts(self, false) && verifyItemForCts(self, item))
{
CustomerServiceLog("CharacterTransfer", "requesting ingame CTS for character " + self + " using item " + item);
removeObjVar(self, fishing.OBJVAR_ELUSIVE_FISH_PLAYER_CAUGHT_COUNT); // you can't keep your old galaxy's elusive fish record when you CTS
performCts(self, destinationGalaxy, destinationCharacterName);
utils.setScriptVar(self, cts.SCRIPTVAR_CTS_ITEM_ID, item);
utils.setScriptVar(self, SCRIPTVAR_CTS_REQUEST_TIMEOUT, getGameTime() + 300);

View File

@@ -70,7 +70,24 @@ public class string_id implements Comparable, Serializable
m_indexId = src.m_indexId;
m_asciiId = src.m_asciiId;
} // string_id(string_id)
/**
* Overloaded version of string_id constructor that uses a dummy string not a localized one
* Allows forcing of inline-defined Strings in lieu of creating strings in .STF where a string_id is expected by the code
* Can be used directly as a string_id or pushed into a prose_package
* This is predominately intended for use in admin/debug scenarios where adding a real string does not make sense
* However, this seemingly works perfectly fine for production use provided that you never intend to localize your client in another language
* Good for radial menu items, comm messages, and all those other annoying functions that want a string_id
* You should NOT use this for conversations, though, as conversation logic relies on STF indexing
*
* Example Usage: string_id message = new string_id("a message you don't want to put into a .STF here");
*
* @param dummyText String text to display in the client
*/
public string_id(String dummyText)
{
m_table = "dummy_string_table"; // client relies on this name to not parse as a string_id
m_asciiId = dummyText;
} // string_id(dummyText)
/**
* Accessor function.
*