/////////////////////////////////////////////////////////////////// // Roving Merchant - Version 2.0 // By Deva Bryson Winblood. 04/12/2004 /////////////////////////////////////////////////////////////////// #include "antistuck_h" ////////////////////////// // PROTOTYPES ////////////////////////// void fnRelaunch(int nCompare); string fnRandomStartingGood(); string fnBarbarianGoods(); string fnMurinsGoods(); string fnWoodmans(); string fnPotions(); string fnDesert(); void fnWatchForMaster(object oRMG); int fnStoreHasHowMany(object oStore,string sTag,int nMax=1000); void fnDoTrade(object oOx,object oStore,int nParm,object oRM); void fnMessageStuck(); void fnDespawn(object oOb); ///////////////////////////////////////////////////////////////////////// MAIN void main() {// main int CONST_FOLLOW = 4; int CONST_RECON = 14; object oMod=GetModule(); object oRMG=GetLocalObject(oMod,"oRMGMerchant"); object oRMGG1=GetLocalObject(oMod,"oRMGG1"); object oRMGG2=GetLocalObject(oMod,"oRMGG2"); object oRMGG3=GetLocalObject(oMod,"oRMGG3"); object oRMGG4=GetLocalObject(oMod,"oRMGG4"); object oRMGG5=GetLocalObject(oMod,"oRMGG5"); object oRMGOx=GetLocalObject(oMod,"oRMGOx"); object oDest=GetLocalObject(oMod,"oRMGDest"); int nState=GetLocalInt(oMod,"nRMGState"); int nSpeed=GetLocalInt(oMod,"nRMGSpeed"); int nKilled=GetLocalInt(oMod,"nRMGKilled"); int nDestNum=GetLocalInt(oMod,"nRMGDestN"); int nC; int nR; int nParm; string sResRMG="rovingmerchant"; string sResMonk="rmgmonk"; string sResRanger="rmgranger"; string sResSorc="rmgsorc"; string sResElite="rmgelite"; string sResOx="rmgoxen"; object oWP; float fDist; float fLDist=GetLocalFloat(oRMG,"fLDist"); object oStore; object oItem; string sName; int nRMGLaunch=GetLocalInt(oMod,"nRMGLaunch"); effect eSleep=EffectVisualEffect(VFX_IMP_SLEEP); int nDisableNonEssential=GetLocalInt(oMod,"nDisableNonEssential"); if (nDisableNonEssential!=TRUE) { // !Disabled if (oRMG==OBJECT_INVALID&&oDest==OBJECT_INVALID) { // spawn a new merchant-----------------[ SPAWN ]---------------------- //SendMessageToPC(GetFirstPC()," Spawn new merchant."); if (oRMGG1!=OBJECT_INVALID) fnDespawn(oRMGG1); if (oRMGG2!=OBJECT_INVALID) fnDespawn(oRMGG2); if (oRMGG3!=OBJECT_INVALID) fnDespawn(oRMGG3); if (oRMGG4!=OBJECT_INVALID) fnDespawn(oRMGG4); if (oRMGG5!=OBJECT_INVALID) fnDespawn(oRMGG5); if (oRMGOx!=OBJECT_INVALID) fnDespawn(oRMGOx); SetLocalInt(oMod,"nRMGDestN",0); SetLocalInt(oMod,"nRMGSpeed",12); SetLocalInt(oMod,"nRMGState",0); oWP=GetWaypointByTag("RMG_SPAWN"); //SendMessageToPC(GetFirstPC()," Should spawn '"+sResRMG+"' @:"+GetTag(oWP)+" in Area:"+GetName(GetArea(oWP))); oRMG=CreateObject(OBJECT_TYPE_CREATURE,sResRMG,GetLocation(oWP)); SetLocalObject(oMod,"oRMGMerchant",oRMG); SetAILevel(oRMG,AI_LEVEL_NORMAL); SetLocalString(oRMG,"sTeamID","RMG"); //SendMessageToPC(GetFirstPC(),"RMG="+GetName(oRMG)+" LOCATION="+GetName(GetArea(oRMG))); if (nKilled<4) { // not elite oRMGG1=CreateObject(OBJECT_TYPE_CREATURE,sResMonk,GetLocation(oWP)); SetLocalString(oRMGG1,"sTeamID","RMG"); SetLocalObject(oRMGG1,"oDestWP",oRMG); SetLocalInt(oRMGG1,"nMState",CONST_RECON); SetAILevel(oRMGG1,AI_LEVEL_NORMAL); SetLocalInt(oRMGG1,"nParm",1); // 3 meters SetLocalInt(oRMGG1,"nRun",TRUE); SetLocalObject(oMod,"oRMGG1",oRMGG1); oRMGG2=CreateObject(OBJECT_TYPE_CREATURE,sResMonk,GetLocation(oWP)); SetLocalString(oRMGG2,"sTeamID","RMG"); SetLocalObject(oRMGG2,"oDestWP",oRMG); SetLocalInt(oRMGG2,"nMState",CONST_RECON); SetLocalObject(oMod,"oRMGG2",oRMGG2); SetAILevel(oRMGG2,AI_LEVEL_NORMAL); SetLocalInt(oRMGG2,"nParm",1); // 3 meters SetLocalInt(oRMGG2,"nRun",TRUE); } // not elite else { // elite oRMGG1=CreateObject(OBJECT_TYPE_CREATURE,sResElite,GetLocation(oWP)); SetLocalString(oRMGG1,"sTeamID","RMG"); SetLocalObject(oRMGG1,"oDestWP",oRMG); SetLocalInt(oRMGG1,"nMState",CONST_RECON); SetLocalObject(oMod,"oRMGG1",oRMGG1); SetAILevel(oRMGG1,AI_LEVEL_NORMAL); SetLocalInt(oRMGG1,"nRun",TRUE); SetLocalInt(oRMGG1,"nParm",1); // 3 meters oRMGG2=CreateObject(OBJECT_TYPE_CREATURE,sResElite,GetLocation(oWP)); SetLocalString(oRMGG2,"sTeamID","RMG"); SetLocalObject(oRMGG2,"oDestWP",oRMG); SetLocalInt(oRMGG2,"nMState",CONST_RECON); SetLocalObject(oMod,"oRMGG2",oRMGG2); SetAILevel(oRMGG2,AI_LEVEL_NORMAL); SetLocalInt(oRMGG2,"nRun",TRUE); SetLocalInt(oRMGG2,"nParm",1); // 3 meters } // elite if (nKilled>0) { // rangers oRMGG3=CreateObject(OBJECT_TYPE_CREATURE,sResRanger,GetLocation(oWP)); SetLocalString(oRMGG3,"sTeamID","RMG"); SetLocalObject(oRMGG3,"oDestWP",oRMG); SetLocalInt(oRMGG3,"nMState",CONST_FOLLOW); SetLocalObject(oMod,"oRMGG3",oRMGG3); SetAILevel(oRMGG3,AI_LEVEL_NORMAL); SetLocalInt(oRMGG3,"nFollowDist",1); // 7 meters oRMGG4=CreateObject(OBJECT_TYPE_CREATURE,sResRanger,GetLocation(oWP)); SetLocalString(oRMGG4,"sTeamID","RMG"); SetLocalObject(oRMGG4,"oDestWP",oRMG); SetLocalObject(oMod,"oRMGG4",oRMGG4); SetLocalInt(oRMGG4,"nMState",CONST_FOLLOW); SetAILevel(oRMGG3,AI_LEVEL_NORMAL); SetLocalInt(oRMGG3,"nFollowDist",1); // 7 meters } // rangers if (nKilled>1) { // sorceress oRMGG5=CreateObject(OBJECT_TYPE_CREATURE,sResSorc,GetLocation(oWP)); SetLocalString(oRMGG5,"sTeamID","RMG"); SetLocalObject(oRMGG5,"oDestWP",oRMG); SetLocalInt(oRMGG5,"nMState",CONST_FOLLOW); SetLocalObject(oMod,"oRMGG5",oRMGG5); SetAILevel(oRMGG5,AI_LEVEL_NORMAL); SetLocalInt(oRMGG5,"nFollowDist",0); // 3 meters } // sorceress oRMGOx=CreateObject(OBJECT_TYPE_CREATURE,sResOx,GetLocation(oWP)); SetLocalString(oRMGOx,"sTeamID","RMG"); SetLocalObject(oRMGOx,"oDestWP",oRMG); SetLocalInt(oRMGOx,"nMState",CONST_FOLLOW); SetLocalInt(oRMGOx,"nSState",0); SetLocalObject(oMod,"oRMGOx",oRMGOx); SetAILevel(oRMGOx,AI_LEVEL_NORMAL); SetLocalInt(oRMGOx,"nFollowDist",2); // 5 meters SetLocalInt(oRMGOx,"nParm",1); nC=0; nR=d6(); while(nC0) { // valid sName=GetStringLeft(sName,GetStringLength(sName)-1); oStore=GetObjectByTag(sName); if (GetObjectType(oStore)!=OBJECT_TYPE_STORE) oStore=GetObjectByTag(sName,1); if (oStore!=OBJECT_INVALID&&GetObjectType(oStore)==OBJECT_TYPE_STORE) { // valid store found fnDoTrade(oRMGOx,oStore,nParm,oRMG); } // valid store found SetLocalInt(oMod,"nRMGState",1); } // valid else { SetLocalInt(oMod,"nRMGState",1); } } // parse break; } // interpret destination case 4: { // camp setup oItem=CreateObject(OBJECT_TYPE_PLACEABLE,"plc_campfrwspit",GetLocation(oRMG)); AssignCommand(oRMG,SpeakString("We camp here. Stay alert!")); AssignCommand(oItem,fnWatchForMaster(oRMG)); SetLocalInt(oMod,"nRMGState",5); DelayCommand(HoursToSeconds(1),SetLocalInt(oMod,"nRMGState",6)); break; } // camp setup case 5: { // camp animations if (GetIsInCombat(oRMG)==FALSE) { // not fighting AssignCommand(oRMG,ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,15.0)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oRMG,13.0); } // not fighting if (GetIsInCombat(oRMGOx)==FALSE) { // not fighting AssignCommand(oRMGOx,ActionPlayAnimation(ANIMATION_LOOPING_DEAD_FRONT,1.0,15.0)); ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eSleep,oRMGOx,13.0); } // not fighting break; } // camp animations case 6: { // camp take down oItem=GetNearestObjectByTag("CampfirewithSpit",oRMG,1); DestroyObject(oItem); SetLocalInt(oMod,"nRMGState",1); break; } // camp take down case 7: { // End of merchant fnDespawn(oRMG); if (oRMGG1!=OBJECT_INVALID) fnDespawn(oRMGG1); if (oRMGG2!=OBJECT_INVALID) fnDespawn(oRMGG2); if (oRMGG3!=OBJECT_INVALID) fnDespawn(oRMGG3); if (oRMGG4!=OBJECT_INVALID) fnDespawn(oRMGG4); if (oRMGG5!=OBJECT_INVALID) fnDespawn(oRMGG5); if (oRMGOx!=OBJECT_INVALID) fnDespawn(oRMGOx); DeleteLocalObject(oMod,"oRMGDest"); DeleteLocalInt(oMod,"nRMGSpeed"); DeleteLocalInt(oMod,"nRMGDestN"); nSpeed=0; DeleteLocalInt(oMod,"nRMGState"); break; } // End of merchant } // main switch } // merchant active--------------------------------------------------- if (nSpeed!=0) DelayCommand(IntToFloat(nSpeed),fnRelaunch(nRMGLaunch)); else { DelayCommand(120.0,fnRelaunch(nRMGLaunch)); } } // !Disabled else { // disabled if (oRMG!=OBJECT_INVALID) fnDespawn(oRMG); if (oRMGG1!=OBJECT_INVALID) fnDespawn(oRMGG1); if (oRMGG2!=OBJECT_INVALID) fnDespawn(oRMGG2); if (oRMGG3!=OBJECT_INVALID) fnDespawn(oRMGG3); if (oRMGG4!=OBJECT_INVALID) fnDespawn(oRMGG4); if (oRMGG5!=OBJECT_INVALID) fnDespawn(oRMGG5); if (oRMGOx!=OBJECT_INVALID) fnDespawn(oRMGOx); DeleteLocalObject(oMod,"oRMGDest"); DeleteLocalInt(oMod,"nRMGSpeed"); DeleteLocalInt(oMod,"nRMGState"); DeleteLocalInt(oMod,"nRMGDestN"); } // disabled } // main ///////////////////////////////////////////////////////////////////////// MAIN /////////////////// // FUNCTIONS /////////////////// void fnRelaunch(int nCompare) { if (GetLocalInt(GetModule(),"nRMGLaunch")==nCompare) ExecuteScript("rmg_main",OBJECT_SELF); } // recall program string fnRandomStartingGood() { // provide a string to a random starting good at monestary int nR=d20(); string sRet=""; if (nR!=20) { // common items nR=d6(); if (nR==1) sRet="nw_it_mring021"; else if (nR==2) sRet="nw_it_mring022"; else if (nR==3) sRet="nw_it_mneck020"; else if (nR==4) sRet="nw_it_medkit001"; else if (nR==5) sRet="nw_it_torch001"; else if (nR==6) sRet="fb1_cloak"; } // common items else { // rare items nR=d4(); if (nR==1) sRet="x1_wmgrenade005"; else if (nR==2) sRet="fb1_campkit"; else if (nR==3) sRet="fb1_warmcloak"; else if (nR==4) sRet="nw_wblmml002"; } // rare items return sRet; } // fnRandomStartingGood(); string fnBarbarianGoods() { // goods provided by northern barbarians int nR=d20(); string sRet=""; if (nR!=20) { // common goods nR=d20(); if (nR==1) sRet="bullhelm"; else if (nR==2) sRet="hornedhelm"; else if (nR==3) sRet="nw_aarcl001"; else if (nR==4) sRet="nw_aarcl002"; else if (nR==5) sRet="warmclothes"; else if (nR==6) sRet="fb1_warmclothes"; else if (nR==7) sRet="nw_aarcl008"; else if (nR==8) sRet="nw_ashsw001"; else if (nR==9) sRet="nw_ashlw001"; else if (nR==10) sRet="nw_it_msmlmisc20"; else if (nR==11) sRet="nw_it_mmidmisc05"; else if (nR==12) sRet="tradeskin"; else if (nR==13) sRet="nw_it_mpotion021"; else if (nR==14) sRet="nw_it_mpotion022"; else if (nR==15) sRet="nw_wamar001"; else if (nR==16) sRet="nw_waxhn001"; else if (nR==17) sRet="nw_waxbt001"; else if (nR==18) sRet="nw_wswbs001"; else if (nR==19) sRet="nw_wplss001"; else if (nR==20) sRet="fb1_wintercloak"; } // common goods else { // rare goods nR=d8(); if (nR==1) sRet="nw_waxmhn002"; else if (nR==2) sRet="nw_waxgr001"; else if (nR==3) sRet="nw_wswgs001"; else if (nR==4) sRet="nw_wblhw001"; else if (nR==5) sRet="nw_wbwsh001"; else if (nR==6) sRet="x1_wmgrenade007"; else if (nR==7) sRet="fb1_ringwarm"; else if (nR==8) sRet="nw_wblms001"; } // rare goods return sRet; } // fnBarbarianGoods(); string fnMurinsGoods() { // stuff from murin the smith int nR=d20(); string sRet=""; if (nR!=20) { // common goods nR=d20(); if (nR==1) sRet="nw_aarcl005"; else if (nR==2) sRet="nw_aarcl012"; else if (nR==3) sRet="nw_aarcl004"; else if (nR==4) sRet="nw_aarcl003"; else if (nR==5) sRet="nw_ashto001"; else if (nR==6) sRet="nw_wambu001"; else if (nR==7) sRet="nw_wswdg001"; else if (nR==8) sRet="nw_wswls001"; else if (nR==9) sRet="nw_wswrp001"; else if (nR==10) sRet="nw_wswsc001"; else if (nR==11) sRet="nw_wswss001"; else if (nR==12) sRet="nw_wblml001"; else if (nR==13) sRet="nw_wblhw001"; else if (nR==14) sRet="nw_wblml001"; else if (nR==15) sRet="nw_wblms001"; else if (nR==16) sRet="nw_wspka001"; else if (nR==17) sRet="nw_wplhb001"; else if (nR==18) sRet="nw_wthax001"; else if (nR==19) sRet="nw_wthdt001"; else if (nR==20) sRet="nw_wbwsl001"; } // common goods else { // rare goods nR=d20(); if (nR==1) sRet="nw_aarcl007"; else if (nR==2) sRet="nw_aarcl006"; else if (nR==3) sRet="eaglewinghelm"; else if (nR==4) sRet="helmofdeceit"; else if (nR==5) sRet="helmofteeth"; else if (nR==6) sRet="helmetdeathshead"; else if (nR==7) sRet="helmetpincer"; else if (nR==8) sRet="nw_wammbu008"; else if (nR==9) sRet="nw_waxmhn002"; else if (nR==10) sRet="nw_wswka001"; else if (nR==11) sRet="nw_wblmcl002"; else if (nR==12) sRet="nw_wblmml002"; else if (nR==13) sRet="nw_wspmka002"; else if (nR==14) sRet="nw_wspsc001"; else if (nR==15) sRet="nw_wspmsc002"; else if (nR==16) sRet="nw_wplsc001"; else if (nR==17) sRet="nw_wbwxl001"; else if (nR==18) sRet="nw_wbwxh001"; else if (nR==19) sRet="nw_wbwmsl001"; else if (nR==20) sRet="nw_wthsh001"; } // rare goods return sRet; } // fnMurinsGoods() string fnWoodmans() { // get goods from woodmans int nR=d20(); string sRet=""; if (nR!=20) { // common goods nR=d12(); if (nR==1) sRet="nw_aarcl009"; else if (nR==2) sRet="warmclothes"; else if (nR==3) sRet="nw_ashsw001"; else if (nR==4) sRet="nw_it_medkit001"; else if (nR==5) sRet="nw_it_mpotion023"; else if (nR==6) sRet="nw_wamar001"; else if (nR==7) sRet="nw_wambo001"; else if (nR==8) sRet="nw_wbwln001"; else if (nR==9) sRet="nw_wbwsh001"; else if (nR==10) sRet="fb1_cloak"; else if (nR==11) sRet="fb1_campkit"; else if (nR==12) sRet="dh2_waterbot"; } // common goods else { // rare goods nR=d6(); if (nR==1) sRet="rangerguardarmor"; else if (nR==2) sRet="nw_it_mring023"; else if (nR==3) sRet="nw_wammar009"; else if (nR==4) sRet="nw_wammbo008"; else if (nR==5) sRet="x1_wmgrenade005"; else if (nR==6) sRet="fb1_wintercloak"; } // rare goods return sRet; } // fnWoodmans() string fnPotions() { // potions trader int nR=d20(); string sRet=""; if (nR!=20) { // common nR=d8(); if (nR==1) sRet="dh2_waterbot"; else if (nR==2) sRet="nw_it_mpotion019"; else if (nR==3) sRet="nw_it_mpotion006"; else if (nR==4) sRet="nw_it_mpotion001"; else if (nR==5) sRet="nw_it_mpotion011"; else if (nR==6) sRet="nw_it_mpotion015"; } // common else { // rare nR=d4(); if (nR==1) sRet="nw_it_mpotion005"; else if (nR==2) sRet="nw_it_mpotion020"; else if (nR==3) sRet="nw_it_mpotion002"; else if (nR==4) sRet="x1_wmgrenade005"; } // rare return sRet; } // fnPotions() string fnDesert() { // desert goods int nR=d8(); string sRet=""; if (nR==1) sRet="x1_wmgrenade006"; else if (nR==2) sRet="x1_wmgrenade002"; else if (nR==3) sRet="x1_wmgrenade004"; else if (nR==4) sRet="x1_wmgrenade003"; else if (nR==5) sRet="nw_wbwsl001"; else if (nR==6) sRet="nw_wambu001"; else if (nR==7) sRet="nw_it_picks001"; else if (nR==8) sRet="nw_it_medkit001"; return sRet; } // fnDesertGoods() void fnWatchForMaster(object oRMG) { // placeable look for master float fDist=GetDistanceBetween(oRMG,OBJECT_SELF); if (fDist<20.0&&GetArea(oRMG)==GetArea(OBJECT_SELF)) DelayCommand(30.0,fnWatchForMaster(oRMG)); else { DestroyObject(OBJECT_SELF); } } // fnWatchForMaster() int fnStoreHasHowMany(object oStore,string sTag,int nMax=1000) { // count items object oItem=GetFirstItemInInventory(oStore); int nCount=0; while(oItem!=OBJECT_INVALID&&nCountd100()) { // percentage passed if (nAllowed!=0) { // check count nP=fnStoreHasHowMany(oStore,GetTag(oInv),nAllowed); if (nP