Here is a working fix for the second problem with "Secure the gate!" quest (Bruno not moving to the gates upon completion of the quest). It seems my initial guess of what caused a bug was correct - it turned out the Monastery gates remained closed when player opened them (player can move through because geometry of the door, blocking the passage for the player, has rotated, but the door was still flagged as "closed" by the game).
Spoiler:(zum lesen bitte Text markieren)Code:enum gEDoorStatus { gEDoorStatus_Open = 0x00000000, gEDoorStatus_Closed = 0x00000001 }; class gCDoor_PS; class GE_DLLIMPORT PSDoor { public: PROPERTY( PropertyStatus, gEDoorStatus ); public: template< typename T > T & Property(); template< typename T > T const & Property() const; public: GEBool IsValid() const; public: //PSDoor & operator=(PSDoor const &); gCDoor_PS const * operator->() const; protected: gCDoor_PS * operator->(void); operator gCDoor_PS *(void); operator gCDoor_PS const *(void)const; protected: eCEntity * m_pEntity; }; PROPERTY_ACCESSOR( PSDoor, PropertyStatus ) class gCStateGraph_PS; class GE_DLLIMPORT PSStateGraph { public: GEBool CanGoToState(bCString const &); GEBool ClearPath(); GEBool GoToState(bCString const &, GEBool); GEBool IsInState(bCString const &); GEBool IsValid() const; public: gCStateGraph_PS const * operator->() const; //PSStateGraph & operator=(PSStateGraph const &); protected: operator gCStateGraph_PS *(); operator gCStateGraph_PS const *() const; gCStateGraph_PS * operator->(); protected: eCEntity * m_pEntity; }; GE_ASSERT_SIZEOF( PSStateGraph, sizeof(Entity) ) GE_ASSERT_SIZEOF( PSDoor, sizeof(Entity) ) template<> PSStateGraph & Entity::PropertySet( void ) { return *reinterpret_cast< PSStateGraph * >( this ); } template<> PSStateGraph const & Entity::PropertySet( void ) const { return *reinterpret_cast< PSStateGraph const * >( this ); } template<> PSDoor & Entity::PropertySet( void ) { return *reinterpret_cast< PSDoor * >( this ); } template<> PSDoor const & Entity::PropertySet( void ) const { return *reinterpret_cast< PSDoor const * >( this ); } GEInt GE_STDCALL OnQuestSuccess_OpenMonasteryDoor( gCScriptProcessingUnit *, GELPVoid, GELPVoid, GEInt ) { Entity::GetEntity("MainDoor_Monastery").PropertySet< PSStateGraph >().GoToState("Off", GEFalse); Entity::GetEntity("Obj_Evt_MainDoor_Monastery").PropertySet< PSDoor >().Property< PSDoor::PropertyStatus >() = gEDoorStatus_Open; return 1; }
The next very critical bug I would like to fix (or at least try to understand what is causing it) is [BUG] Open the great gate quest bug. I wonder if anyone is familiar with triggerable entities (like doors, etc) and their state graphs? If not, maybe someone can figure them out by inspecting entities using console "edit" command?
Involved entities:
Big stone door that behaves incorrectly is Obj_EVT_Door_Lizard_01. The two winches used to open that door are: Obj_EVT_Winch_TitanDungeon_RightWing and Obj_EVT_Winch_TitanDungeon_LeftWing.
I havn't even figured out how exactly two winches are connected to the Obj_EVT_Door_Lizard_01 entity (none of the winches properties seem to reference Obj_EVT_Door_Lizard_01 entity). Both winches seem to trigger
EVT_Converter_Released2Trigger, which in turn triggers Obj_EVT_Drawbridge_01. But none of the last two entities is connected to the Obj_EVT_Door_Lizard_01 entity either.
Actually, the macros were meant as global (there are other classes where properties are defined similary) but I guess you don't like global macros even more.
EDIT: To make those macros work in the header file, templated accessors should be declared as inline. That would probably be a good thing to do regardless of using #define macros or not (to get rid of extra .cpp modules).
Ergebnis 61 bis 80 von 217
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
Geändert von PowerGamer (28.03.2011 um 21:50 Uhr) Grund: Added a note about using inline keyword
-
- Registriert seit
- May 2005
- Beiträge
- 1.238
Geändert von Shak-otay (28.03.2011 um 20:36 Uhr)
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
Not at all! You made me see what a useful program LrentViewer is (I always wanted to check if I missed any interesting areas or items in the game world during my playthrough).
No idea, really. But during my experimenting I had a peculiar situation: I was running through Monastery gates in god mode while a Lizardman was attacking me. One of the NPCs outside the gates instead of attacking a Lizardman was making comments about a fight (like I was having a duel with human). At some moment that NPC tryed to move away from me (to make a room for my fight) and he actually jumped (not walked!) through the doorway, flagged as closed by that time.
-
- Registriert seit
- May 2005
- Beiträge
- 1.238
Hehehe, would like to see this on a video; but it's not reproducable I guess?
By the way found that EVT_Converter_Door_VulcanTemple_Main_01 (in Dungeon_Titan_Events.lrent)
has the following
TriggerTargets
Obj_EVT_Door_Lizard_1
And this has the "parent" EVT_Converter_Released2Trigger and this
Obj_EVT_Winch_TitanDungeon_LeftWing
and now I'm tired... good night:-)Geändert von Shak-otay (28.03.2011 um 22:43 Uhr)
-
If the compiler decides to not inline it (for any reason) it might raise trouble. So I will stick to the *.cpp for all definitions (implementations) that are no generic (non-specialized) templates.
I’ll add the macros to the Script module and commit it tonight (edit: done).
We should move the discussion about the Script Fixes into a separate thread (starting with an overview what is known/planned/fixed).
Please do not introduce too many hacks (classes with wrong size and/or missing methods). You should take the time to complete the classes if possible."Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- ConnorGeändert von NicoDE (29.03.2011 um 00:27 Uhr)
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
I highly doubt anything can go wrong - just rechecked the standard regarding inline keyword to be sure:
Spoiler:(zum lesen bitte Text markieren)3 Every program shall contain exactly one definition of every non-inline function or object that is used in that
program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the
standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8).
An inline function shall be defined in every translation unit in which it is used.
5 There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function
with external linkage (7.1.2),
2 A function declaration (8.3.5, 9.3, 11.4) with an inline specifier declares an inline function. The inline
specifier indicates to the implementation that inline substitution of the function body at the point of call is
to be preferred to the usual function call mechanism. An implementation is not required to perform this
inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for
inline functions defined by 7.1.2 shall still be respected.
3 An inline member function (whether static or nonstatic) may also be defined outside of its class definition
provided either its declaration in the class definition or its definition outside of the class definition
declares the function as inline. [Note: member functions of a class in namespace scope have external
linkage. Member functions of a local class (9.8) have no linkage. See 3.5. ]
Except for member function definitions
that appear outside of a class definition, and except for explicit specializations of member functions of class
templates and member function templates (14.7) appearing outside of the class definition, a member function
shall not be redeclared.
14 An explicit specialization of a function template is inline only if it is explicitly declared to be, and independently
of whether its function template is. [Example:
template<class T> void f(T) { /* ... */ }
template<class T> inline T g(T) { /* ... */ }
template<> inline void f<>(int) { /* ... */ } // OK: inline
template<> int g<>(int) { /* ... */ } // OK: not inline
Also, I put inside that templated accessor a large chunk of code (along with recursive calls to itself, which prevents compiler from performing inline substitution according to MSDN) and the code compiled just fine.
Besides, templated property accessors should be inline regardless of dropping extra .cpp modules, shouldn't they?
Can't disagree on this. Sorry for derailing your thread a bit in the first place.
The problem is I do not feel knowledgable enough to dig all the details of the class structure from code disassembly. Basically, I recreate them by analogy - looking at the similar classes you recreated and copying stuff from *.export.txt files you provided. In particular, I am unsure about member variables and virtual functions (they are not mentioned in the *.export.txt files). So I am hoping you can verify my classes and get them into shape.
P.S. It seems you made a mistype in the Script/gs_infosystem.h - all static methods are protected, while they should be public?
-
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- ConnorGeändert von NicoDE (29.03.2011 um 13:45 Uhr)
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
You can specify inline keyword in GS_DEFINE_PROPERTYSET_ACCESSOR macro and drop GS_DECLARE_PROPERTYSET_ACCESSOR macro altogether. In turn this would allow to use GS_DECLARE_PROPERTYSET_ACCESSOR name for the macro currently named as GS_DECLARE_PROPERTYSET_TEMPLATE. (Analogous changes can be done with Propery macros).
Also, GS_DECLARE_PROPERTYSET macro breaks Ctrl+] command and outlining features of Visual Studio Editor. And it looks awkward to see class declaration starting with a macro. You probably did it to show that all PSxxx classes always have the same member - eCEntity * m_pEntity; this is a positive side of that macro, but probably not worth suffering the drawbacks I mentioned. I would probably drop that macro or at least move "class Someclass {" out of the macro.
-
I want to separate declarations from definitions. Just a style decision that I want to stick to.
OK, I removed it (and fixed the release build that was broken with the last commit).
Notice for IDA users: The Class Informer plug-in has been updated."Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- ConnorGeändert von NicoDE (30.03.2011 um 00:43 Uhr)
-
I removed the event, when tideworm eat the hero.
This is done by editing Rtn_FlatWater_Tideworm script.
But after run script is can not rotate the camera and script is called infinitely. Does anyone have any ideas how to restore a normal camera and complete the script call?
Trying to change other scripts from PS_DeepWater.cpp does not help.
In an attachment file with the script. Content, put in Risen\bin\scripts.Geändert von Digan (31.03.2011 um 18:11 Uhr)
-
I don’t know how to solve your problem, but I want to mention two things: There is no need for the "prolog" if Self and Other are not used and there is need to create new objects of global classes (use the existing achievement.*, focus.*, gui2.*, IS.*, and world.*).
Rtn_FlatWater_Tideworm starts the player state PS_FlatWater if it isn’t the current. It seems that AIStates return GEFalse to signal the end of the state."Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
-
Thanks.
How to get the current state of the player?
Spoiler:(zum lesen bitte Text markieren)Code:GS_DLLEXPORT GEInt GE_STDCALL Rtn_FlatWater_Tideworm( gCScriptProcessingUnit * a_pSPU, GELPVoid a_pSelfEntity, GELPVoid a_pOtherEntity, GEInt a_iArgs ) { a_iArgs = 0 ; a_pOtherEntity = 0; Entity Self; if(a_pSelfEntity) { Self = *static_cast< Entity const * >( a_pSelfEntity ); } else { Self.AttachTo( a_pSPU->GetSelfEntity() ); } Self = Entity::GetPlayer(); bCString currTask = "none"; PSRoutine routine; currTask = routine.GetCurrentTask(); gui2.PrintGameLog(bCUnicodeString(currTask), gELogMessageType_Gold, GEFalse, 0); return 1; }
This script is crashed..
Entity class has no method of getting the current state.
Added
Understood.
Script for getting current state of player:
Spoiler:(zum lesen bitte Text markieren)Code:GS_DLLEXPORT GEInt GE_STDCALL Rtn_FlatWater_Tideworm( gCScriptProcessingUnit * a_pSPU, GELPVoid a_pSelfEntity, GELPVoid a_pOtherEntity, GEInt a_iArgs ) { a_iArgs = 0 ; a_pSPU = 0; a_pSelfEntity = 0; a_pOtherEntity = 0; Entity Player = Entity::GetPlayer(); PSRoutine & PlayerRoutine = Player.PropertySet<PSRoutine>(); gui2.PrintGameLog(bCUnicodeString(PlayerRoutine.GetCurrentTask()), gELogMessageType_Gold, GEFalse, 0); return 1; }
PS - it is PropertySet or PlayerState?
Added
I tried to override the PS_FlatWater function.
Spoiler:(zum lesen bitte Text markieren)
Code:GS_DLLEXPORT GEBool GE_STDCALL PS_FlatWater( bTObjStack< gScriptRunTimeSingleState > & a_SRTSS, gCScriptProcessingUnit * a_pSPU) { gui2.PrintGameLog(bCUnicodeString("PS_FlatWater"), gELogMessageType_Gold, GEFalse, 0); return 1; }
Rewrote AddScriptPatch function for AIState - functions.
Spoiler:(zum lesen bitte Text markieren)
Code:void AddAIStateScriptPatch( gSScriptInit & a_ScriptInit, GELPCChar a_pcOriginalFileName, GELPCChar a_pcName, GELPCChar a_pcSource, gFScriptAIState a_funcScript ) { eCScriptFunctionMap & ScriptFunctionMap = eCScriptFunctionMap::GetInstance(); eSScriptBase * pScript = const_cast< eSScriptBase * >( ScriptFunctionMap.GetScript( a_pcName ) ); if( pScript && pScript->m_funcFunction ) { gSScriptDLL * pScriptDLL = static_cast< gSScriptDLL * >( pScript->m_pScriptDLL ); if( !pScriptDLL || !pScriptDLL->m_strFileName.CompareNoCase( a_pcOriginalFileName ) || g_MessageBox( 0, bCString::GetFormattedString( "The script \"%s\" is already overridden by the \"%s\"!\n" "Do you want to apply the patch anyway?", a_pcName, pScriptDLL->m_strFileName ), "Script Modification - Fixes", MB_ICONEXCLAMATION | MB_YESNO ) == IDYES ) { pScript->m_funcFunction = 0; if( pScriptDLL && pScriptDLL->m_arrScriptsAIStates.RemoveAt( pScriptDLL->m_arrScriptsAIStates.IndexOf( pScript ) ) ) ScriptFunctionMap.UnRegisterScriptAIState( pScript ); } } a_ScriptInit.m_arrScriptAIStates.Add( gSScriptInitScriptAIState( a_pcName, a_pcSource, a_funcScript ) ); }
In ScriptInit function wrote:
Spoiler:(zum lesen bitte Text markieren)
Code:AddAIStateScriptPatch(s_ScriptInit, "Script_Game.dll", "PS_FlatWater", "PS_DeepWater.cpp", PS_FlatWater );
But function is not overridden
In the original AIState-function return char type, but the SDK they return bool type. Why?Geändert von Digan (01.04.2011 um 09:17 Uhr)
-
There is no need to change local variables on the stack. To get rid of the compiler warning a) remove the identifier from the parameter or b) use the UNREFERENCED_PARAMETER macro (I prefer the first one).
Both, it depends on the context.
Short acronyms are not unique by design. The RetroQuestMessageSystem might be abbreviated with RQMS - but this is also used for Roll Quality Management System (considering the bugs of this feature in Risen, and associate the acronym with "Quality", makes a nice joke out of it).
Currently I don’t have to time to look at or test it, sorry.
IDA might guess the type as "char", because the "bool" (GEBool) of Visual C++ is 1 byte in size. You could change the size of "bool" in IDA’s compiler options, but this conflicts with the Hex-Rays plug-in (must be 4 bytes) - for this reason I declared GEBool as 1-byte enumeration in IDA."Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- ConnorGeändert von NicoDE (01.04.2011 um 09:35 Uhr)
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
It seems some types in the SDK are defined in the wrong modules? (For example, enum gEEffectLink is defined in the Engine module while it should be defined in the Game module, etc).
-
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
Can't figure out how to edit .tple file programmatically.
The following code recreates original file, loaded from Sergio.tple:
Code:eCTemplateEntity* tpl = eCTemplateEntity::Load("E:\\!risen\\compiled\\templates\\NPC\\Harbour\\Sergio.tple", GETrue); tpl->Save("e:\\Sergio.tple");
Code:eCEntityPropertySet* pps = tpl->GetPropertySet(eEPropertySetType_Inventory); gui2.PrintGameLogF( gELogMessageType_Grey, "pps: %d, PS cnt: %d", (DWORD)pps, tpl->GetPropertySetCount() ); // displays: "pps: 0, PS cnt: 0"
EDIT2: P.P.S. Some inconsistancies in naming, that prevented me to define a macro (notice extra 's' in second class members names):
Code:struct gSScriptInit { bTObjArray< gSScriptInitScriptAIState > m_arrScriptAIStates; bTObjArray< gSScriptInitScriptAIFunction > m_arrScriptAIFunctions; bTObjArray< gSScriptInitScriptAICallback > m_arrScriptAICallbacks; bTObjArray< gSScriptInitScript > m_arrScripts;
Code:struct gSScriptDLL { bTPtrArray< gSScriptAIState * > m_arrScriptsAIStates; bTPtrArray< gSScriptAIFunction * > m_arrScriptsAIFunctions; bTPtrArray< gSScriptAICallback * > m_arrScriptsAICallbacks; bTPtrArray< gSScript * > m_arrScripts;
Geändert von PowerGamer (02.04.2011 um 20:31 Uhr) Grund: Added EDIT1 and EDIT2
-
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor
-
- Registriert seit
- Aug 2008
- Beiträge
- 174
When I try to link to \lib\*.lib in new project I get the following errors (can be avoided if the functions are inline):
Spoiler:(zum lesen bitte Text markieren)Code:1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInitScriptAIFunction::gSScriptInitScriptAIFunction(char const *,char const *,bool (__stdcall*)(class bTObjStack<struct gScriptRunTimeSingleState> &,class gCScriptProcessingUnit *))" (??0gSScriptInitScriptAIFunction@@QAE@PBD0P6G_NAAV?$bTObjStack@UgScriptRunTimeSingleState@@@@PAVgCScriptProcessingUnit@@@Z@Z) referenced in function _ScriptInit@0 1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInitScript::gSScriptInitScript(char const *,char const *,int (__stdcall*)(class gCScriptProcessingUnit *,void *,void *,int))" (??0gSScriptInitScript@@QAE@PBD0P6GHPAVgCScriptProcessingUnit@@PAX2H@Z@Z) referenced in function _ScriptInit@0 1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInit::~gSScriptInit(void)" (??1gSScriptInit@@QAE@XZ) referenced in function "private: static ?? ::YAXXZ ?? `ScriptInit'::`2'::`dynamic atexit destructor for 's_ScriptInit''" (??__Fs_ScriptInit@?1??ScriptInit@@9@0@YAXXZ) 1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInitScriptBase::~gSScriptInitScriptBase(void)" (??1gSScriptInitScriptBase@@QAE@XZ) referenced in function "public: __thiscall gSScriptInitScript::~gSScriptInitScript(void)" (??1gSScriptInitScript@@QAE@XZ) 1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInitScriptAIFunction::gSScriptInitScriptAIFunction(void)" (??0gSScriptInitScriptAIFunction@@QAE@XZ) referenced in function "protected: static void __stdcall bTArrayBase<struct gSScriptInitScriptAIFunction>::New(struct gSScriptInitScriptAIFunction *,int)" (?New@?$bTArrayBase@UgSScriptInitScriptAIFunction@@@@KGXPAUgSScriptInitScriptAIFunction@@H@Z) 1>Script_Game_Patch.obj : error LNK2019: unresolved external symbol "public: __thiscall gSScriptInitScript::gSScriptInitScript(void)" (??0gSScriptInitScript@@QAE@XZ) referenced in function "protected: static void __stdcall bTArrayBase<struct gSScriptInitScript>::New(struct gSScriptInitScript *,int)" (?New@?$bTArrayBase@UgSScriptInitScript@@@@KGXPAUgSScriptInitScript@@H@Z)
When I try to link to build\debug\*.lib in new project I get the following warning (because my project uses Multi-threaded Debug DLL Runtime, while those libs where built with Multi-threaded Static Runtime, yes, I know I can/should make runtimes match but theoretically using different runtimes in different DLLs is not strictly forbidden and sometimes is unavoidable, so in my opinion it is better to make those functions inline):
Code:1>LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
-
You might have noticed the slowdown of nicode.net - someone is constantly loading content from the server in an endless loop (more than 50GB until this morning).
Therefore you currently need an user name and password to access http://svn.nicode.net/risensdk/
user: RisenSDK
pass: PC_Hero
The same account will be required for public read access to svn://nicode.net/risensdk/
Best Regards,
Nico Bendlin
ps: Please don’t poll the repository for changes. Use the RSS feed (it will be automatically updated with every commit)."Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- ConnorGeändert von NicoDE (30.04.2011 um 20:26 Uhr)
-
Back to normal, authentication is no longer required for public access.
"Unter diesen schwierigen Umständen bin ich mir sicher, daß diese guten Menschen meinen augenblicklichen Bedarf an deren Gold verstehen werden." -- Connor