Files
dsrc/sku.0/sys.server/compiled/game/script/npc/bartender/base.script
T

759 lines
19 KiB
Plaintext

include library.ai_lib;
include library.chat;
include library.consumable;
include library.factions;
include library.money;
include library.prose;
include library.sui;
include library.township;
include library.utils;
const int TICK_TIME = 900;
const string VAR_BARTENDER_BASE = "bartender";
const string VAR_RUMOR_BASE = "bartender.rumor";
const string VAR_RUMOR_SPEAKER = "bartender.rumor.speaker";
const string VAR_RUMOR_TEXT = "bartender.rumor.text";
const string VAR_RUMOR_STAMP = "bartender.rumor.stamp";
const string VAR_LOC_BASE = VAR_BARTENDER_BASE + ".location";
const string TBL_BAR_LOC = "datatables/npc/bartender/bar_location.iff";
const string TBL_MENU_PATH = "datatables/npc/bartender/menu/";
const string SCRIPT_CONVERSE = "npc.converse.npc_converse_menu";
const string SCRIPT_LISTEN = "npc.bartender.listen";
const string[] ANIMS_TOWARD = {
"applause_excited",
"applause_polite",
//"belly_laugh",
//"beckon",
"check_wrist_device",
"clap_rousing",
//"cough_polite",
"entertained",
//"face_blink",
"face_bored",
"face_close_eyes",
//"face_eyebrow_arch",
//"face_pensive",
//"face_smile",
//"face_squint",
//"face_suspicious",
//"face_wink",
//"face_yawn",
"fidget",
"hold_object",
//"laugh",
//"listen",
"look_casual",
"look_right",
"look_left",
"manipulate_low",
"manipulate_medium",
//"nod_head_once",
"pick_up",
"put_down",
//"scratch",
//"scratch_head",
//"shake_head_no",
"stretch",
"tap_foot"
};
const string[] ANIMS_AWAY = {
"check_wrist_device",
"hold_object",
"look_casual",
"look_right",
"look_left",
"manipulate_high",
"manipulate_low",
"manipulate_medium",
"pick_up",
"put_down",
};
const string CONVONAME = "bartender";
const string STF = "bartender";
const string_id[] OPT_DEFAULT = {
new string_id(STF, "opt_buy"), //buy a drink...
new string_id(STF, "talk_to_me"),
};
const string_id[] OPT_RUMOR = {
new string_id(STF, "opt_buy"), //buy a drink...
new string_id(STF, "opt_rumor"), //hear a rumor
};
const string_id[] OPT_BUY = {
new string_id(STF, "opt_yes"), //buy a drink...
new string_id(STF, "opt_no"), //hear a rumor
};
const string_id PROSE_BUY_PASS = new string_id(STF, "prose_buy_pass");
const string_id PROSE_BUY_FAIL = new string_id(STF, "prose_buy_fail");
const string_id SID_INV_FULL = new string_id(STF, "inv_full");
//************* ATTACH/DETACH ******************
trigger OnAttach()
{
//LOG("bartender","OnAttach(): self = " + self);
if ( !hasScript(self, SCRIPT_CONVERSE) )
attachScript(self, SCRIPT_CONVERSE);
if ( !hasScript(self, SCRIPT_LISTEN) )
attachScript(self, SCRIPT_LISTEN);
factions.setFaction(self, "Unattackable");
setInvulnerable(self, true);
messageTo(self, "handleTick", null, 15, false);
return SCRIPT_CONTINUE;
}
trigger OnDetach()
{
//LOG("bartender","OnDetach(): self = " + self);
if ( hasScript(self, SCRIPT_CONVERSE) )
detachScript(self, SCRIPT_CONVERSE);
return SCRIPT_CONTINUE;
}
//************* CONVERSATION ******************
trigger OnStartNpcConversation (obj_id speaker)
{
int cnt = 0;
if ( utils.hasScriptVar(self, "bartender.speaking") )
cnt = utils.getIntScriptVar(self, "bartender.speaking");
cnt++;
utils.setScriptVar(self, "bartender.speaking", cnt);
string_id msg = new string_id(STF, "greet"); //nunya
if ( hasObjVar(self, VAR_RUMOR_BASE) )
{
npcStartConversation (speaker, self, CONVONAME, msg, OPT_RUMOR);
}
else
{
npcStartConversation (speaker, self, CONVONAME, msg, OPT_DEFAULT);
}
return SCRIPT_CONTINUE;
}
trigger OnEndNpcConversation(obj_id speaker )
{
int cnt = utils.getIntScriptVar(self, "bartender.speaking");
cnt--;
if ( cnt < 1 )
utils.removeScriptVar(self, "bartender.speaking");
if ( getBehavior(self) == BEHAVIOR_CALM )
messageTo( self, "resumeDefaultCalmBehavior", null, 5, false );
return SCRIPT_CONTINUE;
}
trigger OnNpcConversationResponse (string convo, obj_id speaker, string_id sid_response)
{
if (!convo.equals(CONVONAME) )
{
return SCRIPT_CONTINUE;
}
string tbl = sid_response.getTable();
string response = sid_response.getAsciiId();
if ( tbl.equals(STF) )
{
string_id msg = new string_id(STF, "greet"); //default
if (response.equals("opt_buy")) //buy a drink via sui
{
msg = new string_id (STF, "msg_buy");//
npcSpeak(speaker, msg);
npcEndConversation(speaker);
showBuySui(speaker);
}
else if (response.equals("opt_rumor")) //tell me a rumor!
{
if ( hasObjVar(self, VAR_RUMOR_BASE) )
{
//tell rumor
string rumorSource = getStringObjVar(self, VAR_RUMOR_SPEAKER);
string rumorText = getStringObjVar(self, VAR_RUMOR_TEXT);
string_id PROSE_RUMOR = new string_id(STF, "prose_rumor" + rand(1,4));
prose_package ppRumor = prose.getPackage(PROSE_RUMOR, rumorSource, rumorText);
chat.publicChat(self, speaker, chat.CHAT_WHISPER, chat.getChatMood(self), ppRumor);
msg = new string_id (STF, "query_buy");//
npcSpeak( speaker, msg );
npcSetConversationResponses(speaker, OPT_BUY);
}
else
{
msg = new string_id (STF, "no_rumor");//
npcSpeak( speaker, msg );
npcSetConversationResponses(speaker, OPT_DEFAULT);
}
}
else if (response.equals("opt_yes")) //teacher delta
{
msg = new string_id (STF, "msg_yes");//
npcSpeak(speaker, msg);
npcEndConversation(speaker);
showBuySui(speaker);
}
else if (response.equals("opt_no")) //all teacher skills
{
msg = new string_id (STF, "msg_no");//
npcSpeak(speaker, msg);
npcEndConversation(speaker);
}
else if (response.equals("talk_to_me")) // Galactic Civil War Rumors
{
location here = getLocation(self);
obj_id container = getTopMostContainer(self);
if ( isIdValid(container) )
{
here = getLocation(container);
}
string buildoutAreaName = getBuildoutAreaName(here.x, here.z);
if ( buildoutAreaName != null && buildoutAreaName.equals("nova_orion_station") )
{
msg = township.getNovaOrionRumor(speaker);
}
else
{
int fiction_rumor = rand (1, 9);
msg = new string_id (STF, "monthly_fiction_" + fiction_rumor);
}
npcSpeak(speaker, msg);
npcEndConversation(speaker);
}
return SCRIPT_CONTINUE;
}
return SCRIPT_CONTINUE;
}
//************* ARRIVE @ LOCATION ******************
trigger OnArrivedAtLocation(string locationName)
{
//LOG("bartender","OnArrivedAtLocation(): self = " + self + " loc = " + locationName);
dictionary d = new dictionary();
d.put("locationName", locationName);
messageTo(self, "handlePlayAnimation", d, 2f, false);
return SCRIPT_CONTINUE;
}
/*trigger OnMovePathComplete()
{
LOG("bartender","OnMovePathComplete(): self = " + self);
messageTo(self, "handlePlayAnimation", d, 2f, false);
return SCRIPT_CONTINUE;
}*/
trigger OnMovePathNotFound()
{
updateDestination(self);
return SCRIPT_CONTINUE;
}
//************* MESSAGEHANDLERS ******************
messageHandler handleTick()
{
//LOG("bartender","******** handleTick(): now = " + getGameTime() + " self = " + self + " ************");
if ( !utils.hasScriptVar(self, "bartender.speaking") && !hasObjVar(self, "bartender.doNotMove"))
{
if ( rand(0, 10) < 4 )
{
if ( bartenderMove(self) )
return SCRIPT_CONTINUE;
}
}
playBarAnimation(self, true);
messageTo(self, "handleTick", null, rand(15f,30f), false);
return SCRIPT_CONTINUE;
}
messageHandler handleListen()
{
if ( !hasScript(self, SCRIPT_LISTEN) )
attachScript(self, SCRIPT_LISTEN);
return SCRIPT_CONTINUE;
}
messageHandler handleNewRumor()
{
if ( params == null || params.isEmpty() )
return SCRIPT_CONTINUE;
removeObjVar(self, VAR_RUMOR_BASE);
string speaker = params.getString("speaker");
string text = params.getString("text");
setObjVar(self, VAR_RUMOR_SPEAKER, speaker);
setObjVar(self, VAR_RUMOR_TEXT, text);
setObjVar(self, VAR_RUMOR_STAMP, getGameTime());
return SCRIPT_CONTINUE;
}
messageHandler handlePlayAnimation()
{
string locationName = params.getString("locationName");
if ( locationName == null || locationName.equals("") )
{
}
else
{
if ( hasObjVar(self, VAR_LOC_BASE + "." + locationName + ".heading") )
{
float yaw = getFloatObjVar(self, VAR_LOC_BASE + "." + locationName + ".heading");
//LOG("bartender","OnArrivedAtLocation(): base yaw = " + yaw);
location here = getLocation(self);
boolean faceBar = true;
location faceLoc = null;
switch ( rand(1,2) )
{
case 1:
//LOG("bartender","OnArrivedAtLocation(): facing toward bar...");
float barYaw = yaw + rand(-10f,10f);
//LOG("bartender","OnArrivedAtLocation(): barYaw = " + barYaw);
setYaw(self, barYaw);
break;
case 2:
default:
//LOG("bartender","OnArrivedAtLocation(): facing away from bar...");
float yawAway = yaw - 180f + rand(-10f,10f);
//LOG("bartender","OnArrivedAtLocation(): yawAway = " + yawAway);
setYaw(self, yawAway);
faceBar = false;
break;
}
playBarAnimation(self, faceBar);
}
removeLocationTarget(locationName);
removeObjVar(self, VAR_LOC_BASE + "." + locationName);
}
messageTo(self, "handleTick", null, rand(30f,45f), false);
return SCRIPT_CONTINUE;
}
void playBarAnimation(obj_id self, boolean isFacingBar)
{
if ( !isIdValid(self) )
return;
string anim = "check_wrist_device";
if ( isFacingBar )
{
int tidx = rand(0, ANIMS_TOWARD.length - 1);
anim = ANIMS_TOWARD[tidx];
}
else
{
int aidx = rand(0, ANIMS_AWAY.length - 1);
anim = ANIMS_AWAY[aidx];
}
//LOG("bartender","playBarAnimation(): anim = " + anim);
ai_lib.doAction(self, anim);
}
boolean bartenderMove(obj_id self)
{
//LOG("bartender","bartenderMove(): self = " + self);
if ( !isIdValid(self) )
return false;
float[] col_x = dataTableGetFloatColumn(TBL_BAR_LOC, "X");
if ( (col_x != null) && (col_x.length > 0) )
{
int idx = rand(0, col_x.length - 2);
dictionary row1 = dataTableGetRow(TBL_BAR_LOC, idx);
dictionary row2 = dataTableGetRow(TBL_BAR_LOC, idx+1);
if ( (row1 != null) && (!row1.isEmpty()) && (row2 != null) && (!row2.isEmpty()) )
{
string planet = getCurrentSceneName();
obj_id structure = getTopMostContainer(self);
if ( !isIdValid(structure) )
return false;
float x1 = row1.getFloat("X");
float y1 = row1.getFloat("Y");
float z1 = row1.getFloat("Z");
string cell1 = row1.getString("CELL");
float heading1 = row1.getFloat("BAR_FACING");
obj_id cid1 = getCellId(structure, cell1);
if ( !isIdValid(cid1) )
return false;
location spot1 = new location(x1, y1, z1, planet, cid1);
float x2 = row2.getFloat("X");
float y2 = row2.getFloat("Y");
float z2 = row2.getFloat("Z");
string cell2 = row2.getString("CELL");
float heading2 = row2.getFloat("BAR_FACING");
obj_id cid2 = getCellId(structure, cell2);
if ( !isIdValid(cid2) )
return false;
location spot2 = new location(x2, y2, z2, planet, cid2);
if ( spot1 == null || spot2 == null )
{
LOG("bartender","bartenderMove(): datatable move locations created as null");
return false;
}
else
{
//LOG("bartender","bartenderMove(): spot1 = " + spot1.toString());
//LOG("bartender","bartenderMove(): spot2 = " + spot2.toString());
}
//location there = getLocationBetweenLocs(spot1, spot2);
location there = null;
if ( cell1.equals(cell2) )
{
float nx = x1;
if ( x1 < x2 )
{
nx = rand(x1, x2);
}
else if ( x2 < x1 )
{
nx = rand(x2, x1);
}
float nz = z1;
if ( z1 < z2 )
{
nx = rand(z1, z2);
}
else if ( z2 < z1 )
{
nz = rand(z2, z1);
}
there = new location(nx, y1, nz, planet, cid1);
}
else
{
there = new location(x1, y1, z1, planet, cid1);
}
if ( there != null )
{
int now = getGameTime();
float heading = (heading1 + heading2)/2f;
setObjVar(self, VAR_LOC_BASE + "." + now + ".location", there);
setObjVar(self, VAR_LOC_BASE + "." + now + ".heading", heading);
addLocationTarget("" + now, there, 0.25f);
//LOG("bartender","bartenderMove(): pathing to -> " + there.toString());
ai_lib.aiPathTo(self, there);
return true;
}
else
{
LOG("bartender","bartenderMove(): target location = null");
}
}
else
{
LOG("bartender","bartenderMove(): one of the selected rows was empty or null");
}
}
else
{
LOG("bartender","bartenderMove(): col X = null or length = 0");
}
return false;
}
void updateDestination(obj_id self)
{
//LOG("bartender","updateDestination(): self = " + self + " now = " + getGameTime());
if ( hasObjVar(self, VAR_LOC_BASE) )
{
obj_var_list ovl = getObjVarList(self, VAR_LOC_BASE);
if ( ovl != null )
{
int numItems = ovl.getNumItems();
for ( int i = 0; i < numItems; i++ )
{
obj_var ov = ovl.getObjVar(i);
if ( ov != null )
{
string name = ov.getName();
if ( name != null && !name.equals("") )
{
removeLocationTarget(name);
}
}
}
}
removeObjVar(self, VAR_LOC_BASE);
}
bartenderMove(self);
}
int showBuySui(obj_id target)
{
obj_id self = getSelf();
if ( !isIdValid(self) || !isIdValid(target) )
return -1;
string scriptvar_base = "menu."+target;
string scriptvar_pid = scriptvar_base+".pid";
string scriptvar_opt = scriptvar_base+".opt";
if ( utils.hasScriptVar(self, scriptvar_pid) )
{
int oldpid = utils.getIntScriptVar(self, scriptvar_pid);
sui.closeSUI(target, oldpid);
utils.removeScriptVarTree(self, scriptvar_base);
}
string title ="@" + STF + ":sui_title";
string prompt = "@" + STF + ":sui_prompt";
string tbl = TBL_MENU_PATH + getCurrentSceneName() + ".iff";
/*
string[] names = dataTableGetStringColumn(tbl, "encodedName");
int[] prices = dataTableGetIntColumn(tbl, "price");
resizeable string[] entries = new string[0];
if ( (names != null) && (names.length > 0) && (prices != null) && (prices.length > 0) )
{
for ( int i = 0; i < names.length; i++ )
{
string_id sid_name = utils.unpackString(names[i]);
if ( sid_name != null )
{
string entry = "[" + prices[i] + "] " + getString(sid_name);
entries = utils.addElement(entries, entry);
}
}
return sui.listbox(self, target, prompt, sui.OK_CANCEL, title, entries, "handleBuySui");
}
*/
int numRows = dataTableGetNumRows(tbl);
if ( numRows > 0 )
{
resizeable string[] opt = new string[0];
resizeable string[] entries = new string[0];
for ( int i = 0; i < numRows; i++ )
{
dictionary d = dataTableGetRow(tbl, i);
if ( d != null && !d.isEmpty() )
{
string template = d.getString("template");
string encodedName = d.getString("encodedName");
if ( template != null && !template.equals("") && encodedName != null && !encodedName.equals("") )
{
string_id sid_name = utils.unpackString(encodedName);
if ( sid_name != null )
{
string name = getString(sid_name);
if ( name != null && !name.equals("") )
{
int cost = d.getInt("price");
if ( cost > 0 )
{
entries = utils.addElement(entries, "[" + cost + "] " + name);
opt = utils.addElement(opt, encodedName);
}
}
}
}
}
}
if ( entries != null && entries.length > 0 && opt != null && opt.length == entries.length )
{
int pid = sui.listbox(self, target, prompt, sui.OK_CANCEL, title, entries, "handleBuySui");
if ( pid > -1 )
{
utils.setScriptVar(self, scriptvar_pid, pid);
utils.setScriptVar(self, scriptvar_opt, opt);
return pid;
}
}
}
return -1;
}
messageHandler handleBuySui()
{
obj_id player = sui.getPlayerId(params);
if ( !isIdValid(player) )
return SCRIPT_CONTINUE;
string[] opt = utils.getStringArrayScriptVar(self, "menu."+player+".opt");
utils.removeScriptVarTree(self, "menu."+player);
if ( opt == null || opt.length == 0 )
return SCRIPT_CONTINUE;
int bp = sui.getIntButtonPressed(params);
if ( bp == sui.BP_CANCEL )
return SCRIPT_CONTINUE;
int idx = sui.getListboxSelectedRow(params);
if ( idx < 0 )
return SCRIPT_CONTINUE;
string tbl = TBL_MENU_PATH + getCurrentSceneName() + ".iff";
int rIdx = dataTableSearchColumnForString(opt[idx], "encodedName", tbl);
if ( rIdx < 0 )
return SCRIPT_CONTINUE;
dictionary row = dataTableGetRow(tbl, rIdx);
if ( row == null || row.isEmpty() )
return SCRIPT_CONTINUE;
int price = row.getInt("price");
//debugSpeakMsg(self, "price for " + row.getString("encodedName") + " is " + price + " cr");
money.requestPayment(player, self, price, "handlePayReturn", row, false);
return SCRIPT_CONTINUE;
}
messageHandler handlePayReturn()
{
if ( params == null || params.isEmpty() )
return SCRIPT_CONTINUE;
obj_id player = params.getObjId(money.DICT_PLAYER_ID);
if ( !isIdValid(player) )
return SCRIPT_CONTINUE;
string template = params.getString("template");
if ( template == null || params.equals("") )
return SCRIPT_CONTINUE;
string encodedName = params.getString("encodedName");
string_id sid_name = null;
if ( encodedName != null && !encodedName.equals("") )
{
sid_name = utils.unpackString(encodedName);
}
int retCode = params.getInt(money.DICT_CODE);
if ( retCode == money.RET_FAIL )
{
prose_package ppBuyFail = prose.getPackage(PROSE_BUY_FAIL, getNameFromTemplate(template));;
if ( sid_name != null )
{
ppBuyFail = prose.getPackage(PROSE_BUY_FAIL, sid_name);
}
else if ( encodedName != null && !encodedName.equals("") )
{
ppBuyFail = prose.getPackage(PROSE_BUY_FAIL, encodedName);
}
sendSystemMessageProse(player, ppBuyFail);
}
else
{
obj_id myInv = utils.getInventoryContainer(self);
obj_id pInv = utils.getInventoryContainer(player);
if ( !isIdValid(myInv) || !isIdValid(pInv) )
return SCRIPT_CONTINUE;
int price = params.getInt(money.DICT_TOTAL);
obj_id drink = createObject(template, myInv, "");
if ( !isIdValid(drink) )
return SCRIPT_CONTINUE;
if ( sid_name != null )
setName(drink, sid_name);
if ( canPutIn(drink, pInv) == CEC_SUCCESS )
{
putIn(drink, pInv);
prose_package ppBuyPass = prose.getPackage(PROSE_BUY_PASS, drink, price);
sendSystemMessageProse(player, ppBuyPass);
money.bankTo(self, money.ACCT_CANTINA_DRINK, price);
}
else
{
money.pay(self, player, price, "whoCares", null);
dictionary d = new dictionary();
d.put("id", drink);
messageTo(self, "handleDestroyObject", d, 5, false);
prose_package ppInvFull = prose.getPackage(SID_INV_FULL, drink);
if ( sid_name != null )
{
ppInvFull = prose.getPackage(SID_INV_FULL, sid_name);
}
else if ( encodedName != null && !encodedName.equals("") )
{
ppInvFull = prose.getPackage(SID_INV_FULL, encodedName);
}
sendSystemMessageProse(player, ppInvFull);
}
}
return SCRIPT_CONTINUE;
}
messageHandler handleDestroyObject()
{
obj_id item = params.getObjId("id");
if ( isIdValid(item) )
destroyObject(item);
return SCRIPT_CONTINUE;
}