::Ice::DispatchStatus Pera::News::___NewMsg(::IceInternal::Incoming& __inS, const ::Ice::Current& __current) { __checkMode(::Ice::Normal, __current.mode); ::IceInternal::BasicStream* __is = __inS.startReadParams(); ::std::string time; __is->read(time); __inS.endReadParams(); NewMsg(time, __current); __inS.__writeEmptyParams(); return ::Ice::DispatchOK; }
int UpdateNPCQuestWindow(HUDInfo *self,int pressID) { int c; char text[80]; int i; int fail; Progress *p; NPC *npc; npc = (NPC *)self->ib; c = GetQuestCount(npc); switch(pressID) { case 0: PopWindow(self->Handle); return 1; break; } if((pressID >= 1)&&(pressID <= c)) { /*if already complete, thank the player for it again*/ p = GetProgressByNameIndexMap(level.name,npc->quests[pressID - 1].name,self->state); if((p != NULL)&&(strcmp(p->value,"complete") == 0)) { NewMsg("Yes, you were very helpful with that one, thank you."); return 1; } /*check for fail condiitions*/ /*if player has met the win conditions, give player reward and mark complete*/ if(p != NULL) { fail = 0; for(i = 0; i < 4;i++) { if(!IsConditionMet(npc->quests[pressID - 1].wincond[i]))fail =1; } if(!fail) { sprintf(text,"Complete Quest %s?",npc->quests[pressID - 1].name); QuestID = pressID - 1; NPCID = self->state; QuestNPC = npc; YesNo(text,CompleteQuest,NULL); return 1; } } /*otherwise the the player about it*/ TextBlockWindow(npc->quests[pressID - 1].desc); SetPlayerProgress(level.name,npc->quests[pressID - 1].name, self->state,"offered"); return 1; } return 0; }
void CSpacePortal::OnRequestUseObject(int64 SourceID,ePipeline& RequestInfo){ int64 EventID = RequestInfo.PopInt(); ePipeline* ObjectInfo = (ePipeline*)RequestInfo.GetData(0); ePipeline* ExePipe = (ePipeline*)RequestInfo.GetData(1); CObjectData Object(*ObjectInfo); int64 ExecuterID = Object.m_ID; CLinker ExecuterLinker; GetLinker(ExecuterID,ExecuterLinker); if (!ExecuterLinker.IsValid()) { ExePipe->GetLabel() = Format1024(_T("Error: Executer not started.")); ExePipe->SetID(RETURN_ERROR); CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return; } PushExecuterEvent(ExecuterID,SourceID,EventID); WriteLogDB(_T("Use Object Event:%I64ld"),EventID); CMsg NewMsg(MSG_OBJECT_RUN,NULL,EventID); ePipeline& NewLetter = NewMsg.GetLetter(); NewLetter.PushPipe(*ExePipe); ExecuterLinker().PushMsgToSend(NewMsg); };
void CSpacePortal::OnRequestCloseObject(int64 SourceID,ePipeline& RequestInfo){ int64 EventID = RequestInfo.PopInt(); ePipeline* ObjectInfo = (ePipeline*)RequestInfo.GetData(0); ePipeline* ExePipe = (ePipeline*)RequestInfo.GetData(1); CObjectData Object(*ObjectInfo); //If it does not start the external organs, this is considered a normal close int64 ExecuterID = Object.m_ID; CLinker ExecuterLinker; GetLinker(ExecuterID,ExecuterLinker); if (!ExecuterLinker.IsValid()) { CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return; } PushExecuterEvent(ExecuterID,SourceID,EventID); WriteLogDB(_T("Close Object Event:%I64ld"),EventID); CMsg NewMsg(MSG_OBJECT_CLOSE,NULL,EventID); ePipeline& NewLetter = NewMsg.GetLetter(); NewLetter.PushPipe(*ExePipe); ExecuterLinker().PushMsgToSend(NewMsg); }
void DoStackWalk (LPCONTEXT lpContextRecord) { STACKFRAME64 stackFrame = {0}; CONTEXT context; HANDLE hProcess, hThread; ////CallstackEntry csEntry; ////IMAGEHLP_SYMBOL64 *pSym = NULL; ////IMAGEHLP_MODULE64_V2 Module; ////IMAGEHLP_LINE64 Line; LPBYTE caller; // Ptr to caller in stack trace APLU3264 nearAddress, // Offset from closest address nearIndex, // Index into StartAddresses nearAddress0, // Offset from closest address nearIndex0, // Index into StartAddresses nearAddress1, // Offset from closest address nearIndex1; // Index into StartAddresses WCHAR wszTemp[1024]; // Temp output save area ////char szAppDPFE[_MAX_PATH], //// szDir [_MAX_DIR], //// szDrive[_MAX_DRIVE], //// szSymPath[_MAX_PATH]; ////PSYMBOL_INFO lpSymInfo; // Ptr to ... // Initialize the handles hProcess = GetCurrentProcess (); hThread = GetCurrentThread (); ////// Allocate space for the symbol name struc ////pSym = (IMAGEHLP_SYMBOL64 *) malloc (sizeof (IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); ////if (!pSym) //// goto CLEANUP; // Not enough memory... ////memset (pSym, 0, sizeof (IMAGEHLP_SYMBOL64) + STACKWALK_MAX_NAMELEN); ////pSym->SizeOfStruct = sizeof (IMAGEHLP_SYMBOL64); ////pSym->MaxNameLength = STACKWALK_MAX_NAMELEN; ////// Allocate space for the symbol info struc ////lpSymInfo = (PSYMBOL_INFO) malloc (sizeof (SYMBOL_INFO) + STACKWALK_MAX_NAMELEN); ////if (lpSymInfo EQ NULL) //// goto CLEANUP; // Not enough memory... ////memset (lpSymInfo, 0, sizeof (SYMBOL_INFO) + STACKWALK_MAX_NAMELEN); ////lpSymInfo->SizeOfStruct = sizeof (SYMBOL_INFO); ////lpSymInfo->MaxNameLen = STACKWALK_MAX_NAMELEN; ////memset (&Line, 0, sizeof (Line)); ////Line.SizeOfStruct = sizeof (Line); ////memset (&Module, 0, sizeof (Module)); ////Module.SizeOfStruct = sizeof (Module); ////if (GetModuleFileNameA (_hInstance, szAppDPFE, sizeof (szSymPath))) ////{ //// // Split out the drive and path from the module filename //// _splitpath (szAppDPFE, szDrive, szDir, NULL, NULL); //// //// // Create the .HLP file name //// _makepath (szSymPath, szDrive, szDir, NULL, NULL); ////} else //// szSymPath[0] = '\0'; //// ////// Set the symbol options ////SymSetOptions (SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); //// ////// Initialize the symbols ////SymInitialize (hProcess, szSymPath, TRUE); // Copy the outer ContextRecord context = *lpContextRecord; // Initialize these fields before the first call to StackWalk64 #ifdef _WIN64 stackFrame.AddrPC.Offset = lpContextRecord->Rip; // Starting instruction address stackFrame.AddrFrame.Offset = lpContextRecord->Rbp; // Starting frame address stackFrame.AddrStack.Offset = lpContextRecord->Rsp; // Starting stack address #elif defined (_WIN32) stackFrame.AddrPC.Offset = lpContextRecord->Eip; // Starting instruction address stackFrame.AddrFrame.Offset = lpContextRecord->Ebp; // Starting frame address stackFrame.AddrStack.Offset = lpContextRecord->Esp; // Starting stack address #else #error Need code for this architecture. #endif stackFrame.AddrPC.Segment = 0; // Used for 16-bit addressing only stackFrame.AddrPC.Mode = AddrModeFlat; // Use flat mode addressing stackFrame.AddrFrame.Segment = 0; // Used for 16-bit addressing only stackFrame.AddrFrame.Mode = AddrModeFlat; // Use flat mode addressing stackFrame.AddrStack.Segment = 0; // Used for 16-bit addressing only stackFrame.AddrStack.Mode = AddrModeFlat; // Use flat mode addressing // Walk the stack while (StackWalk64 ( #ifdef _WIN64 IMAGE_FILE_MACHINE_AMD64, // Machine architecture type #elif defined (_WIN32) IMAGE_FILE_MACHINE_I386, // Machine architecture type #else #error Need code for this architecture. #endif hProcess, // Process handle hThread, // Thread handle &stackFrame, // Ptr to stack frame (input/output) &context, // Ptr to context struc (output) NULL, // Ptr to ReadMemoryRoutine (may be NULL) &SymFunctionTableAccess64, // Ptr to function table access routine &SymGetModuleBase64, // Ptr to get module base routine NULL)) // Ptr to translate address routine for 16-bit addresses { // Check for infinite loop if (stackFrame.AddrPC.Offset EQ stackFrame.AddrReturn.Offset) break; // Check for valid instruction offset if (stackFrame.AddrPC.Offset EQ 0) break; //// // Initialize the CallstackEntry struc //// csEntry.offset = stackFrame.AddrPC.Offset; //// csEntry.name[0] = 0; //// csEntry.undName[0] = 0; //// csEntry.undFullName[0] = 0; //// csEntry.offsetFromSmybol = 0; //// csEntry.offsetFromLine = 0; //// csEntry.lineFileName[0] = 0; //// csEntry.lineNumber = 0; //// csEntry.loadedImageName[0] = 0; //// csEntry.moduleName[0] = 0; //// DbgBrk (); //// // Get the symbol name //// if (SymFromAddr (hProcess, stackFrame.AddrPC.Offset, &csEntry.offsetFromSmybol, lpSymInfo)) //// { //// DbgBrk (); //// //// //// //// } // End IF //// // Get the symbol name //// if (SymGetSymFromAddr64 (hProcess, stackFrame.AddrPC.Offset, &csEntry.offsetFromSmybol, pSym)) //// { //// DbgBrk (); //// //// // Copy to temporary storage //// strcpy (csEntry.name, pSym->Name); //// //// // Undecorate the symbol name //// UnDecorateSymbolName (pSym->Name, csEntry.undName, STACKWALK_MAX_NAMELEN, UNDNAME_NAME_ONLY); //// UnDecorateSymbolName (pSym->Name, csEntry.undFullName, STACKWALK_MAX_NAMELEN, UNDNAME_COMPLETE); //// } // End IF //// GetLastError (); caller = (LPBYTE) stackFrame.AddrPC.Offset; // Format the address FindRoutineAddress (caller, &nearAddress0, &nearIndex0, FALSE); FindRoutineAddress (caller, &nearAddress1, &nearIndex1, TRUE); if (nearAddress0 < nearAddress1) { nearAddress = nearAddress0; nearIndex = nearIndex0; } else { nearAddress = nearAddress1; nearIndex = nearIndex1; } // End IF/ELSE // If the address is out of bounds, just display the address if (nearAddress > 0x00100000) // Format the addresses MySprintfW (wszTemp, sizeof (wszTemp), L"%p -- EBP = %p", caller, stackFrame.AddrFrame.Offset); else // Format the addresses MySprintfW (wszTemp, sizeof (wszTemp), L"%p (%S + %p) -- EBP = %p", caller, StartAddresses[nearIndex].StartAddressName, nearAddress, stackFrame.AddrFrame.Offset); #define NewMsg(a) SendMessageW (hWndCC_LB, LB_ADDSTRING, 0, (LPARAM) (a)); UpdateWindow (hWndCC_LB) NewMsg (wszTemp); #undef NewMsg } // End WHILE ////CLEANUP: ////if (lpSymInfo) //// free (lpSymInfo); ////if (pSym) //// free (pSym); } // End DoStackWalk
void DisplayException (void) { #ifdef DEBUG WCHAR wszTemp[1024]; // Temp output save area EXCEPTION_CODES exceptCode; // Exception code UINT uMem, // Loop counter uCnt, // ... SILevel; // The current SI level APLU3264 nearAddress, // Offset from closest address nearIndex, // Index into StartAddresses nearAddress0, // Offset from closest address nearIndex0, // Index into StartAddresses nearAddress1, // Offset from closest address nearIndex1; // Index into StartAddresses LPPERTABDATA lpMemPTD; // Ptr to PerTabData global memory LPWCHAR exceptText; // Ptr to exception text LPUCHAR exceptAddr; // Exception address APLU3264 regEBP, // Stack trace ptr regEIP; // Instruction ptr LPSIS_HEADER lpSISCur; // Ptr to current SIS header LPMEMVIRTSTR lpLstMVS; // Ptr to last MEMVIRTSTR (NULL = none) // Sort the StartAddresses in ascending order by address qsort (StartAddresses, START_ADDRESSES_LENGTH, sizeof (StartAddresses[0]), &CompareStartAddresses); // Get ptr to PerTabData global memory lpMemPTD = TlsGetValue (dwTlsPerTabData); // Assert (IsValidPtr (lpMemPTD, sizeof (lpMemPTD))); // If lpMemPTD isn't valid, just exit if (!IsValidPtr (lpMemPTD, sizeof (lpMemPTD))) return; // Get the saved exception code & address, & text exceptCode = gExceptionCode; exceptAddr = (LPUCHAR) gExceptionRecord.ExceptionAddress; exceptText = glpExceptionText; #ifdef _WIN64 regEBP = gContextRecord.Rbp; #elif defined (_WIN32) regEBP = gContextRecord.Ebp; #else #error Need code for this architecture. #endif lpSISCur = lpMemPTD->lpSISCur; lpLstMVS = lpMemPTD->lpLstMVS; // If the exception is EXCEPTION_BREAKPOINT (from DbgStop), // we need to display the return address as that's from // where we were called. Displaying DbgStop address is // of no help if (exceptCode EQ EXCEPTION_BREAKPOINT) exceptAddr = *(LPUCHAR *) &gExceptAddr; // Find the address closest to and at or below the given address // If the address is not found, it could be that we're // running under a debugger and the debugger has changed the // starting address of the routine to a near JMP instruction, // so try again with that assumption FindRoutineAddress (exceptAddr, &nearAddress0, &nearIndex0, FALSE); FindRoutineAddress (exceptAddr, &nearAddress1, &nearIndex1, TRUE); if (nearAddress0 < nearAddress1) { nearAddress = nearAddress0; nearIndex = nearIndex0; } else { nearAddress = nearAddress1; nearIndex = nearIndex1; } // End IF/ELSE ShowWindow (hWndCC, SW_SHOWNORMAL); UpdateWindow (hWndCC); #define NewMsg(a) SendMessageW (hWndCC_LB, LB_ADDSTRING, 0, (LPARAM) (a)); UpdateWindow (hWndCC_LB) NewMsg (L"COPY THIS TEXT TO AN EMAIL MESSAGE" ); NewMsg (L"----------------------------------------------------" ); NewMsg (L"Use Right-click: Select All, and" ); NewMsg (L" Right-click: Copy" ); NewMsg (L" to copy the entire text to the clipboard." ); NewMsg (L"----------------------------------------------------" ); NewMsg (L"Post the text on the Forum <http://forum.nars2000.org>"); NewMsg (L" in the Bug Reports section along with a detailed" ); NewMsg (L" statement of what you were doing just prior to the" ); NewMsg (L" crash." ); NewMsg (L"Also, if at all possible, it would be great if you" ); NewMsg (L" could send along a copy of the last saved workspace"); NewMsg (L" (the one with an extension of .save.bak.ws.nars)." ); NewMsg (L"----------------- Copy Below Here ------------------" ); // Display the version # of the executable MySprintfW (wszTemp, sizeof (wszTemp), WS_APPNAME L" -- Version %s (%s)" WS_APPEND_DEBUG, wszFileVer, #ifdef _WIN64 L"Win64" #elif defined (_WIN32) L"Win32" #else #error Need code for this architecture. #endif ); NewMsg (wszTemp); // Display the exception code and string MySprintfW (wszTemp, sizeof (wszTemp), L"Exception code = %08X (%s)", exceptCode, MyGetExceptionStr (exceptCode)); NewMsg (L""); NewMsg (wszTemp); MySprintfW (wszTemp, sizeof (wszTemp), L" at %p (%S + %p)", exceptAddr, StartAddresses[nearIndex].StartAddressName, nearAddress); NewMsg (wszTemp); MySprintfW (wszTemp, sizeof (wszTemp), L" from %s", exceptText); NewMsg (wszTemp); // Display the registers NewMsg (L""); NewMsg (L"== REGISTERS =="); MySprintfW (wszTemp, sizeof (wszTemp), #ifdef _WIN64 L"RAX = %p RBX = %p RCX = %p RDX = %p RIP = %p", gContextRecord.Rax, gContextRecord.Rbx, gContextRecord.Rcx, gContextRecord.Rdx, gContextRecord.Rip #elif defined (_WIN32) L"EAX = %p EBX = %p ECX = %p EDX = %p EIP = %p", gContextRecord.Eax, gContextRecord.Ebx, gContextRecord.Ecx, gContextRecord.Edx, gContextRecord.Eip #else #error Need code for this architecture. #endif ); NewMsg (wszTemp); MySprintfW (wszTemp, sizeof (wszTemp), #ifdef _WIN64 L"RSI = %p RDI = %p RBP = %p RSP = %p EFL = %08X", gContextRecord.Rsi, gContextRecord.Rdi, gContextRecord.Rbp, gContextRecord.Rsp, #elif defined (_WIN32) L"ESI = %p EDI = %p EBP = %p ESP = %p EFL = %08X", gContextRecord.Esi, gContextRecord.Edi, gContextRecord.Ebp, gContextRecord.Esp, #else #error Need code for this architecture. #endif gContextRecord.EFlags); NewMsg (wszTemp); MySprintfW (wszTemp, sizeof (wszTemp), #ifdef _WIN64 L"CS = %04X DS = %04X ES = %04X FS = %04X GS = %04X SS = %04X CR2 = %p", #elif defined (_WIN32) L"CS = %04X DS = %04X ES = %04X FS = %04X GS = %04X SS = %04X CR2 = %p", #else #error Need code for this architecture. #endif gContextRecord.SegCs, gContextRecord.SegDs, gContextRecord.SegEs, gContextRecord.SegFs, gContextRecord.SegGs, gContextRecord.SegSs, gExceptionRecord.ExceptionInformation[1]); NewMsg (wszTemp); // Display the instruction stream NewMsg (L""); NewMsg (L"== INSTRUCTIONS =="); // Get the instruction pointer #ifdef _WIN64 regEIP = gContextRecord.Rip; #elif defined (_WIN32) regEIP = gContextRecord.Eip; #else #error Need code for this architecture. #endif // Start instruction display three rows before the actual fault instruction regEIP -= 3 * 16; if (IsGoodReadPtr (*(LPUCHAR *) ®EIP, 48)) { for (uCnt = 0; uCnt < 7; uCnt++, regEIP += 16) { MySprintfW (wszTemp, sizeof (wszTemp), L"%p: ", regEIP); for (uMem = 0; uMem < 16; uMem++) MySprintfW (&wszTemp[lstrlenW (wszTemp)], sizeof (wszTemp) - (lstrlenW (wszTemp) * sizeof (wszTemp[0])), L" %02X", *(LPBYTE) (regEIP + uMem)); NewMsg (wszTemp); } // End FOR } // End IF // Display the backtrace NewMsg (L""); NewMsg (L"== BACKTRACE =="); // Do a stack walk DoStackWalk (&gContextRecord); // Display the virtual memory ranges NewMsg (L""); NewMsg (L"== MEMVIRTSTR =="); #ifdef _WIN64 NewMsg (L" IniAddr IncrSize MaxSize GuardPage"); #elif defined (_WIN32) NewMsg (L" IniAddr IncrSize MaxSize GuardPage"); #else #error Need code for this architecture. #endif // Check for global VirtualAlloc memory that needs to be expanded for (uMem = 0; uMem < uMemVirtCnt; uMem++) { MySprintfW (wszTemp, sizeof (wszTemp), L"%p %08X %08X %p %S", memVirtStr[uMem].IniAddr, memVirtStr[uMem].IncrSize, memVirtStr[uMem].MaxSize, memVirtStr[uMem].IniAddr + memVirtStr[uMem].MaxSize, memVirtStr[uMem].lpText ); NewMsg (wszTemp); } // End FOR // Display the local virtual memory ranges NewMsg (L""); NewMsg (L"== LCLMEMVIRTSTR =="); #ifdef _WIN64 NewMsg (L" IniAddr IncrSize MaxSize GuardPage"); #elif defined (_WIN32) NewMsg (L" IniAddr IncrSize MaxSize GuardPage"); #else #error Need code for this architecture. #endif while (lpLstMVS) { MySprintfW (wszTemp, sizeof (wszTemp), L"%p %08X %08X %p %S", lpLstMVS->IniAddr, lpLstMVS->IncrSize, lpLstMVS->MaxSize, lpLstMVS->IniAddr + lpLstMVS->MaxSize, lpLstMVS->lpText ); NewMsg (wszTemp); // Get the previous ptr in the chain lpLstMVS = lpLstMVS->lpPrvMVS; } // End WHILE // Display the SI stack NewMsg (L""); NewMsg (L"== SI STACK =="); // Loop backwards through the SI levels for (SILevel = 0; lpSISCur; lpSISCur = lpSISCur->lpSISPrv, SILevel++) { LPAPLCHAR lpMemName; // Ptr to function name global memory // Split cases based upon the caller's function type switch (lpSISCur->DfnType) { case DFNTYPE_IMM: #ifdef DEBUG NewMsg (WS_UTF16_IOTA); #endif break; case DFNTYPE_OP1: case DFNTYPE_OP2: case DFNTYPE_FCN: // Lock the memory to get a ptr to it lpMemName = MyGlobalLockWsz (lpSISCur->hGlbFcnName); // Format the Name, Line #, and Suspension marker MySprintfW (wszTemp, sizeof (wszTemp), L"%s[%d] %c", lpMemName, lpSISCur->CurLineNum, L" *"[lpSISCur->bSuspended]); // We no longer need this ptr MyGlobalUnlock (lpSISCur->hGlbFcnName); lpMemName = NULL; // Display the function name & line # NewMsg (wszTemp); break; case DFNTYPE_EXEC: NewMsg (WS_UTF16_UPTACKJOT); break; case DFNTYPE_QUAD: NewMsg (WS_UTF16_QUAD); break; case DFNTYPE_UNK: default: NewMsg (L"***UNKNOWN***"); break; } // End SWITCH } // End FOR // Tell the Crash Control window to display a MessageBox SendMessageW (hWndCC, MYWM_DISPMB, 0, 0); #undef NewMsg exit (exceptCode); #endif } // End DisplayException
void CSpacePortal::OnRequestStartObject(int64 SourceID,ePipeline& RequestInfo){ int64 EventID = RequestInfo.PopInt(); ePipeline* ObjectInfo = (ePipeline*)RequestInfo.GetData(0); ePipeline* ExePipe = (ePipeline*)RequestInfo.GetData(1); CObjectData Object(*ObjectInfo); ePipeline AddrData = Object.m_Address; assert(Object.m_ID != 0); //Checks whether the specified object addresses is valid SpaceAddress Address = FindChildSpace(AddrData,Object.m_Fingerprint); if (!Address.IsValid()) { CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); ExePipe->SetID(RETURN_ERROR); ExePipe->GetLabel() = Format1024(_T("Error: object address invalid")); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return; } //Need to open the corresponding DLL object in advance, in order to determine the type of executer //CSpace Space(Address.ParentID,Address.ChildID); AddrData = Object.m_Address; tstring FilePath = SpacePath2FileAddress(AddrData); tstring ObjectName = GetFileName(Object.m_Name); //不含扩展名 FilePath += _T("\\")+ObjectName; FilePath += _T("\\")+Object.m_Name; Dll_Object TempDll(Object.m_ID,FilePath); if (!TempDll.IsValid()) { int32 error = ::GetLastError(); ExePipe->SetID(RETURN_ERROR); ExePipe->GetLabel() = Format1024(_T("Load object fail: <%s>"),FilePath.c_str()); CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return ; } DLL_TYPE DllType = TempDll.GetDllType(); tstring ExecuterFile; switch (DllType) { case DLL_VC6: { ExecuterFile = _T("EXE_VC6.EXE"); } break; case DLL_VC6D: { ExecuterFile = _T("EXE_VC6D.EXE"); } break; case DLL_VC10: { ExecuterFile = _T("EXE_VC10.EXE"); } break; case DLL_VC10D: { ExecuterFile = _T("EXE_VC10D.EXE"); } break; default: { ExePipe->GetLabel() = Format1024(_T("Error: dll type not support:%d"),(int)DllType); ExePipe->SetID(RETURN_ERROR); CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return; } } //start a executer int64 ExeSourceID = Object.m_ID; //ExecuterID is equal to the external object instance ID bool ret = StartExecuter(ExeSourceID,ExecuterFile); if (!ret) { ExePipe->GetLabel() = Format1024(_T("Error: Executer start fail.")); ExePipe->SetID(RETURN_ERROR); CLinker Requester; GetLinker(SourceID,Requester); if (Requester.IsValid()) { CMsg FeedbackMsg(MSG_TASK_FEEDBACK,NULL,EventID); ePipeline& Letter = FeedbackMsg.GetLetter(); Letter.PushPipe(*ExePipe); Requester().PushMsgToSend(FeedbackMsg); } return; } RegisterExecuterUser(SourceID,ExeSourceID); CLinker ExecuterLinker; GetLinker(ExeSourceID,ExecuterLinker); //Register a start external object event PushExecuterEvent(ExeSourceID,SourceID,EventID); WriteLogDB(_T("Start Object Event:%I64ld"),EventID); //send execute msg CMsg NewMsg(MSG_OBJECT_START,NULL,EventID); ePipeline& NewLetter = NewMsg.GetLetter(); NewLetter.PushString(FilePath); NewLetter.PushPipe(*ExePipe); ExecuterLinker().PushMsgToSend(NewMsg); };
void CompleteQuest() { char buf[80]; char text[80]; char map[80]; int id; Progress *p; P_Item *pitem; char *b; int i; int g; if(QuestNPC == NULL)return; /*resolve win conditions*/ for(i = 0; i < 4;i++) { if(strlen(QuestNPC->quests[QuestID].wincond[i]) > 1) { sscanf(QuestNPC->quests[QuestID].wincond[i],"%s",buf); if(strcmp(buf,"return")==0) { /*first type of win condition, return an item*/ b = strchr(QuestNPC->quests[QuestID].wincond[i], ' '); b++; /*find item by b in player's inventory*/ pitem = GetPlayerItemByName(b); if(pitem != NULL) { /*by now, this should be true*/ TakePlayerItem(pitem); } } else if(strcmp(buf,"kill")==0) { sscanf(QuestNPC->quests[QuestID].wincond[i],"%s %s %i",buf,map,&id); p = GetProgressByIndexMap(map,id); if(p != NULL) { if(strcmp(p->value,"dead")== 0) { sprintf(text,"Well done killing that beast!"); NewMsg(text); } } } else if(strcmp(buf,"save")==0) { sscanf(QuestNPC->quests[QuestID].wincond[i],"%s %s %i",buf,map,&id); p = GetProgressByIndexMap(map,id); if(p != NULL) { if(strcmp(p->value,"saved")== 0) { sprintf(text,"You are a true hero, Thank you!"); NewMsg(text); } } } } } /*give rewards*/ for(i = 0; i < 4;i++) { if(strlen(QuestNPC->quests[QuestID].reward[i]) > 1) { sscanf(QuestNPC->quests[QuestID].reward[i],"%s",buf); if(strcmp(buf,"gold")==0) { b = strchr(QuestNPC->quests[QuestID].reward[i], ' '); b++; sscanf(b,"%i",&g); GivePlayerGold(g); NewMessage("Here is some Gold!",IndexColor(Gold)); } else if(strcmp(buf,"item")==0) { b = strchr(QuestNPC->quests[QuestID].reward[i], ' '); b++; GivePlayerItem(b); sprintf(text,"Have this %s.",b); NewMsg(text); } else if(strcmp(buf,"skill")==0) { b = strchr(QuestNPC->quests[QuestID].reward[i], ' '); b++; GivePlayerSkill(b); sprintf(text,"I will teach you the skill %s.",b); NewMsg(text); } else if(strcmp(buf,"spell")==0) { b = strchr(QuestNPC->quests[QuestID].reward[i], ' '); b++; GivePlayerSpell(b); sprintf(text,"I will teach you the spell %s.",b); NewMsg(text); } else if(strcmp(buf,"grace")==0) { b = strchr(QuestNPC->quests[QuestID].reward[i], ' '); b++; sscanf(b,"%i",&g); GivePlayerGrace(g); sprintf(text,"You have earned %i grace.",g); NewMsg(text); } } } SetPlayerProgress(level.name,QuestNPC->quests[QuestID].name, NPCID,"complete"); }
int UpdateNPCShopWindow(HUDInfo *self,int pressID) { char text[80]; int c; int Good; NPC *npc; P_Skill *skill; Item *item; npc = (NPC *)self->ib; c = GetShopCount(npc); switch(pressID) { case 0: PopWindow(self->Handle); return 1; break; } if((pressID >= 1)&&(pressID <= c)) { if(strcmp(npc->shop[pressID - 1].type,"item")==0) { item = GetItemByName(npc->shop[pressID - 1].name); if(item == NULL)return 0; if(PDat.gold >= (item->cost * npc->shop[pressID - 1].markup)) { BuyingPrice = (item->cost * npc->shop[pressID - 1].markup); strcpy(BuyingItem,item->name); sprintf(text,"Buy %s for %iG?",BuyingItem,BuyingPrice); YesNo(text,PurchaseItem,NULL); } else { NewMessage("You can't afford this!",IndexColor(White)); NewMessage("Come back when you have more money!",IndexColor(White)); } } else if(strcmp(npc->shop[pressID - 1].type,"service")==0) { if(strcmp(npc->shop[pressID - 1].name,"Rest")==0) { /*TODO:advance the clock some time...*/ /*TODO address status effects*/ NewMsg("After some rest, you feel better."); PlayerEnt->health = PlayerEnt->healthmax; PlayerEnt->mana = PlayerEnt->manamax; PlayerEnt->stamina = PlayerEnt->staminamax; } else if(strcmp(npc->shop[pressID - 1].name,"Inventory")==0) { /*TODO Open up Stockpile menu*/ NewMsg("To Be Added."); } else if(strcmp(npc->shop[pressID - 1].name,"Upgrade")==0) { /*TODO Open up Stockpile menu*/ NewMsg("To Be Added."); } } else if(strcmp(npc->shop[pressID - 1].type,"spell")==0) { skill = GetSpellByName(npc->shop[pressID - 1].name); if(skill == NULL)return 0; if(PDat.gold >= (skill->price * npc->shop[pressID - 1].markup)) { if(strcmp(skill->type,"favor")==0) { if(GetPlayerItemByName("Wood Relic")!= NULL)/*TODO add other favor castors as needed*/ { BuyingPrice = (skill->price * npc->shop[pressID - 1].markup); strcpy(BuyingItem,skill->name); sprintf(text,"Learn the divine favor %s for %iG?",BuyingItem,BuyingPrice); YesNo(text,PurchaseSpell,NULL); } else { NewMsg("In order to learn this, you will need a Holy Relic"); } } if(strcmp(skill->type,"alchemy")==0) { if(GetPlayerItemByName("White Stone")!= NULL)/*TODO add other favor castors as needed*/ { BuyingPrice = (skill->price * npc->shop[pressID - 1].markup); strcpy(BuyingItem,skill->name); sprintf(text,"Learn how to make %ss for %iG?",BuyingItem,BuyingPrice); YesNo(text,PurchaseSpell,NULL); } else { NewMsg("In order to learn this, you will need a Philosopher's Stone!"); } } } else { NewMsg("I'm afraid I can't afford to teach for free."); } } else if(strcmp(npc->shop[pressID - 1].type,"skill")==0) { skill = GetSkillByName(npc->shop[pressID - 1].name); if(skill == NULL)return 0; Good = 1; if(PDat.gold >= (skill->price * npc->shop[pressID - 1].markup)) { if(SkillHasSpecial(skill,"Strength")) { if(PDat.attr[A_Str].score < 10) { Good = 0; NewMsg("You will need to have more strength than that to learn this skill."); } } if(SkillHasSpecial(skill,"Endurance")) { if(PDat.attr[A_End].score < 10) { Good = 0; NewMsg("I'm sorry, you just are not tough enough to handle this skill."); } } if(SkillHasSpecial(skill,"Agility")) { if(PDat.attr[A_Agi].score < 10) { Good = 0; NewMsg("You will need to work on your footwork before I can teach you this."); } } if(SkillHasSpecial(skill,"Dexterity")) { if(PDat.attr[A_Dex].score < 10) { Good = 0; NewMsg("I'm sorry, but you have stupid hands. If you get new ones come back."); } } if(SkillHasSpecial(skill,"Focus")) { if(PDat.attr[A_Foc].score < 10) { Good = 0; NewMsg("If you can't concentrate, I can't teach you."); } } if(SkillHasSpecial(skill,"Spirit")) { if(PDat.attr[A_Str].score < 10) { Good = 0; NewMsg("You lack the strength of will to understand what I haave to teach you."); } } if(Good) { BuyingPrice = (skill->price * npc->shop[pressID - 1].markup); strcpy(BuyingItem,skill->name); sprintf(text,"Learn the %s skill for %iG?",BuyingItem,BuyingPrice); YesNo(text,PurchaseSkill,NULL); } } else { NewMsg("Training Takes time and MONEY. Come back when you have more of the later."); } } return 1; } return 0; }
void PurchaseSkill() { GivePlayerSkill(BuyingItem); PDat.gold -= BuyingPrice; NewMsg("I hope this comes in handy!"); }
void PurchaseSpell() { GivePlayerSpell(BuyingItem); PDat.gold -= BuyingPrice; NewMsg("Use this knowledge well!"); }
void PurchaseItem() { GivePlayerItem(BuyingItem); PDat.gold -= BuyingPrice; NewMsg("Thank you for your business!"); }