Command and Conquer: Renegade Official Forums - RDF feed
C&C: Renegade --> Dying since 2003™, resurrected in 2024!
Syncing or changing BuildingGameObj 'IsDetroyed' state for clients
Could support or a function be added to sync or change the IsDestroyed flag of a BuildingGameObj via the server? It's the only issue with properly working building revival. Of course this would only be supported by 4.0 clients. [20:33:10] <iran> I was fixing up my building revival plugin and I got everything working now for maps without duplicate structures, one issue though: [20:33:40] <iran> after reviving a building on the server the IsDestroyed flag is still set to true on clients unless they restart [20:34:59] <iran> i ran the client under a debugger and I set BuildingGameObj offset 0x778 (which contains a IsDestroyed bool flag) to false on the hand after reviving it [20:35:44] <iran> this allowed me to buy infantry again, but there is no way to set the IsDestroyed flag for clients via the server [20:36:47] <iran> *hand of nod after reviving it [20:37:14] <iran> the IsDestroyed flag not syncing with the server affects the follow things I've seen: [20:37:32] <iran> 1. Can't buy from revived production facilities 2. no death announcement is made for revived building (damage announcements still work)
Re: Syncing or changing BuildingGameObj 'IsDetroyed' state for clients
It has been a really long time since I did something with W3D coding but I was able to dig up some very old code: void Set_Object_Dirty_Bit_All(BaseControllerClass *Base, DIRTY_BIT Bit, bool Set) { for (int i = 1; i < 0x80; i++) { if (Set) { Base->DirtyBits[i] |= Bit; } else { Base->DirtyBits[i] &= ~Bit; } } } void Restore_Building(GameObject *obj) { if (!Commands->Get_ID(obj) || !obj) { return; } GameObject *o = As_BuildingGameObj(obj); if (!o) { return; } char *c = (char *)obj; c += 0x778; bool *x = (bool *)c; //Is building destroyed bool *x = false; //Make it false BaseControllerClass *b = BaseControllerClass::Find_Base(Get_Object_Type(o)); if (b && !Is_Building_Dead(obj)) { if (Is_SoldierFactory(o)) { b->CanGenerateSoldiers = true; } else if (Is_WarFactory(o) || Is_Airstrip(o)) { b->CanGenerateVehicles = true; } else if(Is_PowerPlant(o)) { b->IsPowered = true; } Set_Object_Dirty_Bit_All(b, DB_RARE, true); float max = Commands->Get_Max_Health(o); Commands->Set_Health(obj, max); } } I have no idea if this is still valid code for 4.0. The part that should sync the clients is the Set_Object_Dirty_Bit_All if I recall all of this correctly (and I didn't just dig up old broken code xD)
Did that work properly, e.g. could clients buy advanced infantry if they were in-game before say the Barracks was revived? With what I currently have after the barracks is revived players can't buy advanced infantry because the clients still think the Barracks is destroyed (unless they restart). Can't say I've tried modifying the BaseControllerClass object.
This is what makes you able to purchase infantry and vehicles again. It used to anyway; as I said I don't know if this code still works with 4.0. It worked with 3.4.4. You could just try it with 4.0 PS. If you do, let me know if the code still works
I tried it, doesn't seem to work. I'm using: void Revive_Building(GameObject *Building) { if (Building == nullptr ) return; if ( Is_Building_Dead(Building) == false ) return; int Team = ((DamageableGameObj*)Building)->Get_Player_Type(); Restore_Building(Building); Building->Set_Object_Dirty_Bit(NetworkObjectClass::BIT_CREATION, true); Update_Network_Object(Building); float max = Commands->Get_Max_Health(Building); Commands->Set_Health(Building, max); // This is needed to update the state of a building from 'dead' to 'alive on the client Update_Network_Object(Building); Commands->Apply_Damage(Building, 1.0f, "Explosive", 0); Update_Network_Object(Building); Commands->Apply_Damage(Building, 1.0f, "Explosive", 0); Update_Network_Object(Building); if (Is_Base_Powered(Team)) { Commands->Set_Building_Power(Building, true); } else { Commands->Set_Building_Power(Building, false); } GameObject *Ref = Find_Refinery(Team); bool RefDead = Commands->Get_Health(Ref) == 0.0f; bool HarvDead = Commands->Get_Health(Find_Harvester(Team)) == 0.0f; // Console_Output("HarvDead = %d, HarvHealth = %f, RefDead = %d, Ref = %x, Harv = %x", HarvDead, Commands->Get_Health(Find_Harvester(Team)), // RefDead, Ref, Find_Harvester(Team)); // DEBUG CRAP // Build a new Harvester if needed if ( HarvDead && !RefDead ) { Request_New_Harvester(Team); } // Needed for re-initialisation and also updating the state of the buidling ((BuildingGameObj*)Building)->Collect_Building_Components(); Update_Network_Object(Building); Update_Building_State(Building, false); Update_Network_Object(Building); Initialize_Building(Building); Update_Network_Object(Building); auto c = BaseControllerClass::Find_Base(Team); c->Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); Update_Network_Object(c); } I call Restore_Building() which is a scripts 4.0 API function which does the following: void SCRIPTS_API Restore_Building(GameObject* obj) { if (!obj) return; BuildingGameObj* building = obj->As_BuildingGameObj(); if (!building || !building->Is_Destroyed()) return; building->Set_Is_Destroyed(false); BaseControllerClass* base = BaseControllerClass::Find_Base(Get_Object_Type(building)); if (base) { if (building->As_SoldierFactoryGameObj()) base->Set_Can_Generate_Soldiers(true); if (building->As_VehicleFactoryGameObj()) base->Set_Can_Generate_Vehicles(true); base->Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } }
Hmm it actually seems the restore building 4.0 function kinda does what I had in mine. Sadly I'm seeing a lot of new functions in your code from which I have no idea what it does aside from an educated guess. PS. I believe you should delete the BIT_CREATION. The Restore_Building already sets the BIT_RARE. PSPS. I've never had to damage a building for it to sync with a client... As I said it has been a very long time but based on my old code I would think it would be something like this in 4.0... :/ void Revive_Building(GameObject *Building) { if (Building == nullptr || !Is_Building_Dead(Building)) return; Restore_Building(Building); //Scripts API call already sets BIT_RARE and I assume Set_Is_Destroyed does the 0x778 offset bool or something similar. float max = Commands->Get_Max_Health(Building); Commands->Set_Health(Building, max); //The remaining stuff; restore power, harvester, w/e } But I really have no idea why that wouldn't work tbh, sorry I'm almost 100% sure that old code I dug up used to work under 3.4.4. (I may have my files organized/archived but that doesn't mean I remember if it all worked for a 100% xD )
Yeah I should probably remove that BIT_CREATION, still working on the code. I checked the Import_XXXX functions for BaseControllerClass and they only affect BaseControllerClass data members like "CanGenerateVehicles". This might have worked on 3.4.4 but I'm not sure. The PT code is a mess.
In 4.0, I can state 2 things: 1.The PT code (for the standard stock PT at least) will NOT let you purchase an object unless the barracks/vehicle factory is still alive. and 2.The building netcode will NOT let you toggle the "IsDestroyed" flag from "false" to "true" over the network at all no matter what you do. So basically there is NO WAY to bring back vehicle/infantry purchasing in the stock logic. As for making changes to scripts so it is possible, the answer is no, its NOT going to happen.
Why not make it possible? Should be easy right?
I mean it's just a manual function to send a netcode command to clients telling them the network ID of the building and whether the IsDetroyed flag should be set to 'true' or 'false'. I don't really see the issue with that. Why add support for building revival with the scripts.dll API command Restore_Building() when it doesn't work properly because of a tiny bug on the client? You could probably fix the bug on the client side too by setting IsDetroyed to false if the building health isn't 0.0f, somewhere in a Import_XXX function for the building, because the client still updates the health of the building even when the IsDestroyed flag is set.
Restore_Building is probably intended for use with the APB/AR/TSR stuff that disables the functionality of buildings without destroying them.
I checked the game's code and saw it exports and imports the IsDstroyed flag in BuildingGameObj::Import_Rare() and BuildingGameobj::Export_Rare(). However when importing it only calls BuildingGameObj::On_Destroyed() when the servers sends that the BuildingGameObj IsDetroyed is true and when on the client it's still alive (IsDetroyed set to false). I fixed the issue with building revival by setting the IsDestroyed on the client to what the server sends after that code (at the end of the function). Here's my memory patched client code for TT's BuildingGameObj::Import_Rare(), using the space for alignment to add my patch: 561A8A63 84DB TEST BL,BL // contains IsDestroyed sent by server 561A8A65 74 17 JE SHORT tt.561A8A7E // if false jump past this code to Out 561A8A67 80BE 70070000 00 CMP BYTE PTR DS:[ESI+770],0 // Check client IsDetroyed 561A8A6E 75 0E JNZ SHORT tt.561A8A7E // if IsDestroyed is true jump to Out, only execute the below call if false 561A8A70 8B56 F8 MOV EDX,DWORD PTR DS:[ESI-8] 561A8A73 8B82 94000000 MOV EAX,DWORD PTR DS:[EDX+94] 561A8A79 8D4E F8 LEA ECX,DWORD PTR DS:[ESI-8] 561A8A7C FFD0 CALL EAX // call BuildingGameObj::On_Destroyed() // Out: 561A8A7E 889E 70070000 MOV BYTE PTR DS:[ESI+770],BL // I memory patched this in, this sets client IsDetroyed with what server sends 561A8A84 90 NOP 561A8A85 90 NOP 561A8A86 90 NOP 561A8A87 5F POP EDI // Normal epilogue 561A8A88 5E POP ESI 561A8A89 5B POP EBX 561A8A8A 8BE5 MOV ESP,EBP 561A8A8C 5D POP EBP 561A8A8D C2 0400 RETN 4 So the issue can be fixed by 4.0 by patching BuildingGameObj::Import_Rare() to set the client IsDestroyed flag with what the server sends at the end of the function. Note that the IsDestroyed offset is BuildingGameObj + 0x770, NOT 0x778 like I previously thought. The offset seems to be diffeerent between server versions and they handle Import_Rare() and Export_Rare() a bit differently.
Okay so apparently jonwil doesn't want to add this fix cause it fixes the bug and would cause the state of the client to be different from players without this fix. Even though this fix is the equivalent of rejoining a server after a building has been revived. And even though stuff like vlimit and Commands->Enable_Stealth() are also fixed for scripts clients and so have a different state from stock clients.
D: I think it's time to get 4.0 to become an official/required patch for everyone. How are the possibilities of making it an official patch like 1.037? If we're limiting fixes because the client states would become different it is time to make it so tbh.
Omar007 wrote on Fri, 02 August 2013 14:02 D: I think it's time to get 4.0 to become an official/required patch for everyone. How are the possibilities of making it an official patch like 1.037? If we're limiting fixes because the client states would become different it is time to make it so tbh. Trust me, we're trying.
EvilWhiteDragon wrote on Sat, 03 August 2013 02:00 Omar007 wrote on Fri, 02 August 2013 14:02 D: I think it's time to get 4.0 to become an official/required patch for everyone. How are the possibilities of making it an official patch like 1.037? If we're limiting fixes because the client states would become different it is time to make it so tbh. Trust me, we're trying. Try harder D:
Yea get DJ on behalf of the renegade community to put forward the idea!
I know this has been a while since this topic was active but I strongly feel that the next maintenance patch needs to address this. While the reasons for not patching it was that it would make the clients destroyed state different for those running scripts and those that don't, at the moment it is actually far more fragmented. Clients that join after the restore have the destroyed flag set to false while those who were ingame prior will have the destroyed flag set to true, even those on the latest scripts, which on many servers is the vast majority, especially ones that make use of the advanced features like building restores where 4.0 and above is actually mandatory. Overall this would fix a ton of issues regarding building restores such as proper factory restores, but also fix the broken death announcements that happen on all buildings. Fixing this client side would ensure that all clients running the latest scripts would have the same building state, where as today even players on the same scripts versions can have differing building states. Being able to properly restore factories would also encourage those who are on old versions of scripts to upgrade as well reducing the number of cheaters who use old versions of scripts that are still susceptible to hacks. I see this as a win for all players. I'd much rather see 98% or so percent of the clients have the same building destroyed state than the current mishmash of destroyed states that the current situation has.
We have never supported nor had plans to support building controllers transitioning from dead back to alive, the engine is not designed to support it and anyone attempting to jury rig it on their own servers are on their own as far as support is concerned...
Except it has been proven again and again that it does work with very minimal modifications. There are a lot of things that the engine didn't support originally that were added by scripts both client and server side. I don't understand the resistance to this idea. Its not like we don't know how to fix it. We do. That parts all done. The only thing needed is to merge it and send it out as part of an upcoming patch.
dblaney1 wrote on Sat, 03 May 2014 19:46 Except it has been proven again and again that it does work with very minimal modifications. Where? I don't know about you, but I've never seen any proof of this.
The Original poster of this thread released tweaked client side dll's that synced the destroyed flag as described in this thread. The method of how to patch it is also described in this thread. I just don't see a reason to not add support for this. It would add a lot of possibilities for modders and server operators alike. I don't see any downside to having more consistent clients states either. Hopefully Iranian sees this and can provide you with a 4.1 patched version. The one I found was for 4.0. If someone can tell me where the function mentioned about half way down this page has moved to in 4.1 i'll gladly patch it myself and show you that way. If we had this response to every change made by scripts so far we wouldn't have higher vehicle limits, commands->enable_stealth, and many other things. I am thankful for everything this community has done.
To find the function epilogue to patch open Renegade and attach OllyDbg, make sure Renegade is already in the main menu. in OllyDbg go to 0x006843E0 then follow the jump at the location. The new scripts 4.1 uses SSE heavily so the instructions for functions look kinda weird. Scroll up to find this kind of pattern at a function prologue: ORIGINAL RENEGADE CODE AS EXAMPLE, THE TT CODE LOOKS DIFFERENT BUT ACTS THE SAME: mov al, [esp+20h+var_11] test al, al jz short loc_68431E mov al, [ebx+770h] test al, al jnz short loc_68431E mov edx, [ebx-8] lea ecx, [ebx-8] call dword ptr [edx+94h] pop edi pop esi pop ebx add esp, 14h retn 4 All you really need is to find the check with 0x770 and a virtual function call to edx+0x94. Patch the epilogue so offset 0x770 is given the content of the byte stack variable that is tested for zero before the test for 0x770 being tested for zero in the code above. In this case: mov al, [esp+20h+var_11] test al, al Happens before: jz short loc_68431E mov al, [ebx+770h] So the epilogue needs to be patched so that offset 0x770 is updated with the content of [esp+20h+var_11]. Use OllyDbg to patch the epilogue in memory. then select and copy the patched instructions and save them somewhere. Undo these memory patches (select the patches and right click -> Undo Selection) then open bandtest.dll with a hex editor, then find the epilogue in of the function in your hex editor by searching for the instruction bytes for the original epilogue (obviously make sure you find the correct one so check if there are multiple matches in the hex editor), replace the original epilogue instruction bytes with the instruction bytes have written down for your modified one. It might also be possible to just memory patch with OllyDbg and use the 'copy to executable' command. Instruction bytes look like this: 64E016C9 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14] 64E016CD 8A46 0B MOV AL,BYTE PTR DS:[ESI+B] 64E016D0 8886 70070000 MOV BYTE PTR DS:[ESI+770],AL 64E016D6 5F POP EDI 64E016D7 5E POP ESI 64E016D8 5B POP EBX 64E016D9 83C4 14 ADD ESP,14 64E016DC C2 0400 RETN 4 64E016DD CC INT3 The "8B7424 14" on the first line are 4 bytes for the instruction on the right of the line, "8A46 0B" on the second line are 3 bytes for the instruction on the right of that line etc. Once done load up the game with the hex edited bandtest.dll and find the epilogue for the BuildingClass::Import_Rare() function again and check if your hex edits match the patched code your wrote down earlier, the code patches you applied with a hex editor. I've attached a patched bandtest.dll, I have NOT checked if it works correctly with building revival. If the game crashes during startup or just after joining a server the file is incompatible with your version of 4.1.
The thing is that the tt is just worried it will cause more problems than it will solve, due to the fact that working with netcode is bug sensitive. I think...
Breaking the lifecycle contract of a GameObject is incredibly dangerous and, whilst it might work in limited test cases, you fail to see the wider implications. All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash. This is one of many resons why transitioning ANY object from Destroyed back to a "live" state will NEVER be officially supported. The only valid way to do this is to instantiate an entirely new GameObject instance... and it is not possible to create building controllers at run time because they are part of the level static data.
The reason provided was because TT didn't want to have a mismatch of client states. I can't digest that reason, as they have already altered client states with other fixes and patches.
Unlike vehicle objects, when buildings are destroyed they aren't deleted. They still exist. Ultraaow Newmaps has been running building restores on refineries, power plants and base defenses for quite a while now without issue. The only issue is syncing with client states of the destroyed flag which is what stops the factories from working without exiting and rejoining which will in fact sync the destroyed flag. Only clients who were in the server prior to the restoration have the flags still set as destroyed. I don't see what the problem is with patching this. If a server isn't running building restores then it won't affect them anyway since the building states will always remain as destroyed in that case. Also considering scripts are all executed server side and that behavior has worked bug free with building restores I don't see how that is an issue. Base defenses can be restored perfectly which rely on scripts to function. As can refineries, power plants, construction yards etc. I have also written my own plugin and tested this behavior extensively. The building controllers handle restores just fine without issue. And the scripts on building controllers are handled server side anyway where the flags do switch from destroyed to not destroyed just fine currently. So a client side change wouldn't have any affect on that behavior anyway. Overall, considering restores have been used everyday on a server for months if not years on a server without issue, (I only returned to playing renegade about 6 months ago) I don't see why we can't move to make this work client side as well. Right now, servers that use restores actually have greater client mismatches than they would with a client side fix as all clients running the latest scripts would have the same state rather than the differing ones they have now.
iRANian wrote on Sun, 04 May 2014 02:25 To find the function epilogue to patch open Renegade and attach OllyDbg, make sure Renegade is already in the main menu. in OllyDbg go to 0x006843E0 then follow the jump at the location. The new scripts 4.1 uses SSE heavily so the instructions for functions look kinda weird. Scroll up to find this kind of pattern at a function prologue: ORIGINAL RENEGADE CODE AS EXAMPLE, THE TT CODE LOOKS DIFFERENT BUT ACTS THE SAME: mov al, [esp+20h+var_11] test al, al jz short loc_68431E mov al, [ebx+770h] test al, al jnz short loc_68431E mov edx, [ebx-8] lea ecx, [ebx-8] call dword ptr [edx+94h] pop edi pop esi pop ebx add esp, 14h retn 4 All you really need is to find the check with 0x770 and a virtual function call to edx+0x94. Patch the epilogue so offset 0x770 is given the content of the byte stack variable that is tested for zero before the test for 0x770 being tested for zero in the code above. In this case: mov al, [esp+20h+var_11] test al, al Happens before: jz short loc_68431E mov al, [ebx+770h] So the epilogue needs to be patched so that offset 0x770 is updated with the content of [esp+20h+var_11]. Use OllyDbg to patch the epilogue in memory. then select and copy the patched instructions and save them somewhere. Undo these memory patches (select the patches and right click -> Undo Selection) then open bandtest.dll with a hex editor, then find the epilogue in of the function in your hex editor by searching for the instruction bytes for the original epilogue (obviously make sure you find the correct one so check if there are multiple matches in the hex editor), replace the original epilogue instruction bytes with the instruction bytes have written down for your modified one. It might also be possible to just memory patch with OllyDbg and use the 'copy to executable' command. Instruction bytes look like this: 64E016C9 8B7424 14 MOV ESI,DWORD PTR SS:[ESP+14] 64E016CD 8A46 0B MOV AL,BYTE PTR DS:[ESI+B] 64E016D0 8886 70070000 MOV BYTE PTR DS:[ESI+770],AL 64E016D6 5F POP EDI 64E016D7 5E POP ESI 64E016D8 5B POP EBX 64E016D9 83C4 14 ADD ESP,14 64E016DC C2 0400 RETN 4 64E016DD CC INT3 The "8B7424 14" on the first line are 4 bytes for the instruction on the right of the line, "8A46 0B" on the second line are 3 bytes for the instruction on the right of that line etc. Once done load up the game with the hex edited bandtest.dll and find the epilogue for the BuildingClass::Import_Rare() function again and check if your hex edits match the patched code your wrote down earlier, the code patches you applied with a hex editor. I've attached a patched bandtest.dll, I have NOT checked if it works correctly with building revival. If the game crashes during startup or just after joining a server the file is incompatible with your version of 4.1. Can you apply this patch to the latest tt bandtest.dll. The version you posted is from a few version back. I just tried it and it works with restores. Was able to buy a vehicle after restore just fine. I think this bandtest.dll is from the first 4.1 release with the disappearing airstrip plane.
My version is 4.10.6640 from 9 February 2014. I actually just updated from 4.0 to 4.1 because of the issues. It isn't doing any new updates for me so I assume Ihave the latest version.
iRANian wrote on Sun, 04 May 2014 11:03 My version is 4.10.6640 from 9 February 2014. I actually just updated from 4.0 to 4.1 because of the issues. It isn't doing any new updates for me so I assume Ihave the latest version. The bandtest you uploaded is not the latest. Yours is one of the earlier 4.1 releases that had the disappearing airstrip plane. I believe the latest version was released on ‎March or february? ‎26, ‎2014. Thats the created date on my bandtest.dll. I uploaded a video of the restores working with the bandtest you posted. It works exactly as intended. It fixes both the ability to purchase vehicles and infantry, and fixes the building death announcements as well. No negative side effects have been observed. https://www.youtube.com/watch?v=_7WWOvR5PUE I am trying the patch the latest file now and got up to the 770 part but I still trying to learn that debugging program and am having a little trouble following it. I will update you on whether I was able to complete your intructions. If you can iRANian, download the latest patch for TT from the website and see if you can patch it. The version you are on is not the latest and many bugs were fixed since that release. The one you uploaded was 6440. The latest is 6482. http://www.tiberiantechnologies.org/downloads
It does look that I'm using the older version, I'm getting all the bugs lol. Well the thing is I had 4.0. I ran the AUTO-UPDATER and it installed 4.1 for me and now it isn't auto-updating to the latest version. Lemme try downloading the 4.1 installer manually, like you suggested. I can update the latest bandtest.dll in about 10 minutes or so, hell the compiled instructions for the function that needs to be patched most likely are the same too, just the offset in the exe. Gotta acquire the LATEST 4.1 bandtest.dll first though! EDIT: Okay done!
Thanks man. I uploaded another video, this time of a refinery restoring, demonstrating that the harvester automatically rebuilds and the credit tick restarts perfectly. https://www.youtube.com/watch?v=qF3PVFHTusg
I did all those tests too, I did the patch originally as I finished a plugin which adds building revival console commands and I wanted the building state to update back to alive. I did a bunch of hacks in the plugin code so I eventually got all the building state working except the 'IsDetroyed' BuildingGameObj member variable, (which is the offset 0x770). I figured that out after I noticed I wasn't getting building under attack and building destroyed announcements for the building after it was revived and I checked the server code. http://www.renegadeforums.com/index.php?t=msg&th=40368&start=0&
Heres my source and dll for the modified version of your plugin you released for 4.0. This works perfect on 4.1. Most of the hacks actually aren't needed with 4.1 such as the powerplant ones. Simply toggling base power on was enough to power all the buildings on including the base defenses. If anyone wants to see it in action download the latest bandtest that iranian uploaded and join my test server called dblaney testing gameplay, join here. http://www.renegadeforums.com/index.php?t=getfile&id=14941&
Interesting use of the 'repaired' EVA announcements, I approve. Very clever.
Thanks, hopefully we can change TT's mind and atleast get them to test what we have provided to show them that it doesn't cause any bugs. https://www.youtube.com/watch?v=sqps37FCmvQ Heres another test. I kill the obelisk, revive it, then kill it again and last revive it again. When its dead the weapon is off, and once revived works exactly as it should immediately (given that the power plant is alive if there is one), and when destroyed a second time, again works properly where the weapon is disabled. Restoring the building, once again brings it back to life. You can do this as many times as you want. It works perfectly every time. I have tested it on maps with power plants as well. If the power plant is dead when the obelisk is revived it will be powered off. If the power plant is subsequently revived the obelisk powers back on perfectly without any intervention.
Got one last video showing the ingame building restore powerups in action rather than the server console command. https://www.youtube.com/watch?v=TM2hBLbJfGg Both the Refinery and Airstrip are dead. I restore the Refinery first and it requests a new harvester but because the Airstrip is dead it can't build one. I then restore the Airstrip and because the Refinery had requested a Harvester earlier once the Airstrip is restored it immediately constructs the requested Harvester.
danpaul88 wrote on Sun, 04 May 2014 09:02 Breaking the lifecycle contract of a GameObject is incredibly dangerous and, whilst it might work in limited test cases, you fail to see the wider implications. All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash. This is one of many resons why transitioning ANY object from Destroyed back to a "live" state will NEVER be officially supported. The only valid way to do this is to instantiate an entirely new GameObject instance... and it is not possible to create building controllers at run time because they are part of the level static data. I think your understanding of how this works only applies to objects that aren't building controllers. Building controllers behave quite differently than other objects. Also the part you are worried about (the behavior of attached scripts) is already possible on the current scripts. The scripts attached to buildings are run server side and its already possible to restore a building server side. The issue being discussed here is syncing that restore with the client who doesn't have to deal with what scripts are attached to a building controller at all. Many servers have been running server side restores without issue. I think this should be investigated further than just outright denied. It really would provide a lot of benefits, possible even make a building like a construction yard worth protecting if it had some kind of restore role for other buildings. I have repeatedly destroyed and restored buildings multiple times in the same game to see if I could glitch the game out. No luck, everything worked flawlessly.
You still cause the killed event to be possibly called multiple times, which breaks the life cycle of the object. Whilst most scripts won't care about this some will and could crash the server.
None of the default game scripts have issues with it, and I assume only a very small amount of custom scripts will...and that's the responsibility for the server owner. Mind you that reviving buildings server side has been possible for YEARS now. The discussion pertains to fixing clients so players don't need to rejoin the server for the building to update from 'dead' to 'alive' on those clients who were in the server when the building was revived.
danpaul88 wrote on Mon, 05 May 2014 03:43 You still cause the killed event to be possibly called multiple times, which breaks the life cycle of the object. Whilst most scripts won't care about this some will and could crash the server. What you are worried about is already possible with the current scripts. We are looking for a client side fix here. I have proven that it works. There are so many ways to crash a server already with plugins. This isn't one of them from my experience. I don't see how this would make a crash anymore likely especially since this is entirely client side, and has nothing to do with the server at all. The servers behavior with this patch does not change at all. It behaves exactly the same. The servers technically don't even need the patch at all. This was already possible server side as explained. If a script has an issue with it then don't run building restores on the server. Problem solved. Given that though, I have yet to come across a script that has an issue with it.
This sounds like a great idea, I hope you guys look into it. If it works, and it looks like it does, it would add a lot to the game.
You, I really hope it does get into the next patch. The concerns that some of the dev team expressed have been addressed.
I thought you hoped it DOES get in the next patch? ;p
iRANian wrote on Wed, 07 May 2014 12:50 I thought you hoped it DOES get in the next patch? ;p Whoops fixed it. Chrome autocorrect or something did that. Also I have been running this client side patch the past few days without a single crash or glitch and have joined several different servers. Building restores also work perfectly on my test server including factories. On UltraAOW newmaps this patch fixes the missing building death announcements on restored buildings as well. (they only do restores of PP, Ref, Defenses) I recommend more people test it out. Just make a backup of your bandtest.dll and download this one. This is for the latest scripts version. http://www.renegadeforums.com/index.php?t=getfile&id=14941& Overall, I'd settle for a patch that only changes this.
Just wanna update you guys. I have been running the client side patch for over 2 weeks now without a single issue. Have played on all the major servers without issue.
danpaul88 wrote on Sun, 04 May 2014 10:02 All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash. I don't think this statement is quite right, unless the lifecycle does not have to wait for all scripts with a Created function to complete; because, I have encountered plenty of times (both in 3.4.4 and 4.1) that Created fired after Destroyed, I've got a few tricks that prevent destroyed from continuing if created of a script hasn't been completed yet as I've had crashing issues in the past due to uninitialized objects and variables
Jerad Gray wrote on Fri, 16 May 2014 14:53 danpaul88 wrote on Sun, 04 May 2014 10:02 All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash. I don't think this statement is quite right, unless the lifecycle does not have to wait for all scripts with a Created function to complete; because, I have encountered plenty of times (both in 3.4.4 and 4.1) that Created fired after Destroyed, I've got a few tricks that prevent destroyed from continuing if created of a script hasn't been completed yet as I've had crashing issues in the past due to uninitialized objects and variables I don't see how that could happen unless you're destroying objects in the initial Created cycle for all game objects, which is inadvisable and rather inefficient (why create objects if you're just going to destroy them instantly on game start?). If you can provide a reproduction case for that we will look into adding a fix in the code to ensure Created is always called before Destroyed (even if we end up doing something like if (!created) {Created();} Destroyed();)
danpaul88 wrote on Fri, 16 May 2014 07:56 Jerad Gray wrote on Fri, 16 May 2014 14:53 danpaul88 wrote on Sun, 04 May 2014 10:02 All GameObjects have a guarunteed lifecycle whereby they transition from Created -> Destroyed, usually via Killed unless removed from the level by a script or other event. Scripts attached to that object are free to make the assumption that they can clean up resources once Killed or Destroyed are called. Subsequently causing that GameObject to be alive again and triggering Damaged events or another Killed / Destroyed event in this case would cause that script to be in an invalid state and could result in a crash. I don't think this statement is quite right, unless the lifecycle does not have to wait for all scripts with a Created function to complete; because, I have encountered plenty of times (both in 3.4.4 and 4.1) that Created fired after Destroyed, I've got a few tricks that prevent destroyed from continuing if created of a script hasn't been completed yet as I've had crashing issues in the past due to uninitialized objects and variables I don't see how that could happen unless you're destroying objects in the initial Created cycle for all game objects, which is inadvisable and rather inefficient (why create objects if you're just going to destroy them instantly on game start?). If you can provide a reproduction case for that we will look into adding a fix in the code to ensure Created is always called before Destroyed (even if we end up doing something like if (!created) {Created();} Destroyed();) Last time I ran into it was caused by changing the player character on spawn, but that is one of the rare occurrences where I had complete control and could have found a way around it besides just making a flag external to the script to check. In the wild, I've seen it caused by things ranging from a separate timer doing clean up, to something a player does (for example once I saw a player die while at a PT (due to lag or a lockup which ever the case was they were still in the PT after their char died) and just as the player's character spawned they bought a character from the PT, the destroy flag on the scripts attached to the spawn character were called before the create due to the character being 'destroyed' and replaced with a new character. Mind you, this is only a problem if your storing an array index, or a pointer in your script (playerId for efficiency, or a pointer to a list being the most common occurance). Normally I just protect against it now by attaching a dummy script as the final step of create and then checking for the attached script on any classes that I've found can be called before create (Custom, Damaged, Killed, and Destroyed are the ones that come to mind) on any sensitive scripts (in all of ECW I've done this less than 50 times, and that's a good 4.27MB of code.
Jerad Gray wrote on Fri, 16 May 2014 15:48 <snipped nested quotes> Last time I ran into it was caused by changing the player character on spawn, but that is one of the rare occurrences where I had complete control and could have found a way around it besides just making a flag external to the script to check. In the wild, I've seen it caused by things ranging from a separate timer doing clean up, to something a player does (for example once I saw a player die while at a PT (due to lag or a lockup which ever the case was they were still in the PT after their char died) and just as the player's character spawned they bought a character from the PT, the destroy flag on the scripts attached to the spawn character were called before the create due to the character being 'destroyed' and replaced with a new character. Mind you, this is only a problem if your storing an array index, or a pointer in your script (playerId for efficiency, or a pointer to a list being the most common occurance). Normally I just protect against it now by attaching a dummy script as the final step of create and then checking for the attached script on any classes that I've found can be called before create (Custom, Damaged, Killed, and Destroyed are the ones that come to mind) on any sensitive scripts (in all of ECW I've done this less than 50 times, and that's a good 4.27MB of code. It's good practice to initialize any pointers to NULL in the constructor and then check != NULL in the Destroyed method. The spawn character change should be safe in 4.1 since the lifecycle had some fixed applied at that time which should ensure the correct ordering of events.
danpaul88 wrote on Fri, 16 May 2014 09:01 Jerad Gray wrote on Fri, 16 May 2014 15:48 <snipped nested quotes> Last time I ran into it was caused by changing the player character on spawn, but that is one of the rare occurrences where I had complete control and could have found a way around it besides just making a flag external to the script to check. In the wild, I've seen it caused by things ranging from a separate timer doing clean up, to something a player does (for example once I saw a player die while at a PT (due to lag or a lockup which ever the case was they were still in the PT after their char died) and just as the player's character spawned they bought a character from the PT, the destroy flag on the scripts attached to the spawn character were called before the create due to the character being 'destroyed' and replaced with a new character. Mind you, this is only a problem if your storing an array index, or a pointer in your script (playerId for efficiency, or a pointer to a list being the most common occurance). Normally I just protect against it now by attaching a dummy script as the final step of create and then checking for the attached script on any classes that I've found can be called before create (Custom, Damaged, Killed, and Destroyed are the ones that come to mind) on any sensitive scripts (in all of ECW I've done this less than 50 times, and that's a good 4.27MB of code. It's good practice to initialize any pointers to NULL in the constructor and then check != NULL in the Destroyed method. The spawn character change should be safe in 4.1 since the lifecycle had some fixed applied at that time which should ensure the correct ordering of events. Misread, never thought of it, not sure how the scripts are actually put together in the background. I've seen game engines where the script classes were just used to make the definitions, so the constructors were called once for a class on gameEngine load, not per attachment on each object. Guess I imagined that ren was the same so I never bothered with it.
The constructor is ALWAYS called, even before Created gets called. Setting your pointers to NULL in the class constructor should always be safe. (EDIT: I see you edited your post so the above is irrelevant now)
Please do this in some future patch
As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat.
Still i would like it
zunnie wrote on Thu, 29 May 2014 06:41 Still i would like it You need to offer incentives Zunnie, I suggest offering money or sexual favors. On a side note I was on a server yesterday and buildings were coming back to life just fine and all I'm running is the latest scripts release.
danpaul88 wrote on Thu, 29 May 2014 01:20 As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat. We don't want a new scripts release, we just want this file distributed through the auto updater. I don't know why you guys are resisting this so much. I have been running the patched bandtest.dll for over a month now without a single crash.
I agree with listening to the tt devs
dblaney1 wrote on Thu, 29 May 2014 19:32 danpaul88 wrote on Thu, 29 May 2014 01:20 As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat. We don't want a new scripts release, we just want this file distributed through the auto updater. I don't know why you guys are resisting this so much. I have been running the patched bandtest.dll for over a month now without a single crash. make a few little mods to your server and you think you know what's best for all of us....
The fact of the matter is that at this stage in the game, very few people would benefit from this "modification" anyway. Yes, some people would definitely reap something from this - but not very many, and certainly not enough to make such a fuss about it.
Mauler wrote on Thu, 29 May 2014 21:18 dblaney1 wrote on Thu, 29 May 2014 19:32 danpaul88 wrote on Thu, 29 May 2014 01:20 As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat. We don't want a new scripts release, we just want this file distributed through the auto updater. I don't know why you guys are resisting this so much. I have been running the patched bandtest.dll for over a month now without a single crash. make a few little mods to your server and you think you know what's best for all of us.... It would be good if you actually understood that this is a Client Side patch, so servers have absolutely nothing to do with this at all. The file in question doesn't even exist on the server.
dblaney1 wrote on Thu, 29 May 2014 22:25 Mauler wrote on Thu, 29 May 2014 21:18 dblaney1 wrote on Thu, 29 May 2014 19:32 danpaul88 wrote on Thu, 29 May 2014 01:20 As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat. We don't want a new scripts release, we just want this file distributed through the auto updater. I don't know why you guys are resisting this so much. I have been running the patched bandtest.dll for over a month now without a single crash. make a few little mods to your server and you think you know what's best for all of us.... It would be good if you actually understood that this is a Client Side patch, so servers have absolutely nothing to do with this at all. The file in question doesn't even exist on the server. I believe what my good friend is saying is that because you wrote some pedestrian code you think you know more than the tt devs
roszek wrote on Thu, 29 May 2014 22:34 dblaney1 wrote on Thu, 29 May 2014 22:25 Mauler wrote on Thu, 29 May 2014 21:18 dblaney1 wrote on Thu, 29 May 2014 19:32 danpaul88 wrote on Thu, 29 May 2014 01:20 As has already been stated countless times, there will be no more scripts releases for Renegade other than any bug fix releases required to fix bugs / crashes / anti-cheat. We don't want a new scripts release, we just want this file distributed through the auto updater. I don't know why you guys are resisting this so much. I have been running the patched bandtest.dll for over a month now without a single crash. make a few little mods to your server and you think you know what's best for all of us.... It would be good if you actually understood that this is a Client Side patch, so servers have absolutely nothing to do with this at all. The file in question doesn't even exist on the server. I believe what my good friend is saying is that because you wrote some pedestrian code you think you know more than the tt devs I only have two college degrees in Computer science/Software Engineering and Network Engineering, and contribute to several major open source projects with actual code that has been merged and used by millions of devices.
Lots of people have degrees in computing. In my experience that doesn't necessarily mean they know the first thing about computing... degrees just mean you memorized what you needed to know to pass a test, they're useful for getting your foot in the door as a graduate but beyond that you need to prove yourself in battle with the compiler and prove you know your stuff. But that's by the by, just saying that I'm not impressed by anyone who thinks quoting their degrees somehow indicates their level of competency. And, for the record, no, we will not be pushing an unverified third party file which wasn't generated by our build server to the patching system.
As the guy who is (at this point) basically in charge of any future scripts releases for Renegade, I am going to say that this feature will NOT be included (regardless of whether any future releases get made or not). Continuing to ask for it will not help, it will just make me even less likely to care about your feature. As of now, we have NO plans to push any further scripts builds in any case (if bugs show up that are game-breaking, we MAY consider a new build but as of right now there are no game-breaking bugs that we need to deal with)
If this were requested for APB, it would'be been done yesterday lol.
What they have done so far with the scripts will look good on their resume. Why take a chance on incorporating something that could cause more issues and require more work. Stick with what's solid and working. I am in no way saying that they are lazy or are only doing this to help their resume. I'm just saying that this is what I would do if I was them.
I don't even include scripts.dll or indeed any W3D based stuff on my CV... this is something I do in my free time and I don't expect anything from it.
jonwil wrote on Fri, 30 May 2014 07:59 As the guy who is (at this point) basically in charge of any future scripts releases for Renegade, I am going to say that this feature will NOT be included (regardless of whether any future releases get made or not). Continuing to ask for it will not help, it will just make me even less likely to care about your feature. Don't ask for it to go in, because the answer will be even more of a no? lol... zunnie wrote on Sun, 22 June 2014 13:11 If this were requested for APB, it would'be been done yesterday lol. Yeah, he's kinda right.
zunnie wrote on Mon, 23 June 2014 01:11 If this were requested for APB, it would'be been done yesterday lol. Actually no, I wouldn't add this feature for APB. At least not in the way that people are asking for here.
All this nonsense ignores the fact that allowing buildings to be revived is a pretty dubious Renegade "feature" LOL And what I mean by a "dubious Renegade feature" is that it's an absolutely terrible idea bar-fucking-none
Yeah being able to revive buildings when they were illegally destroyed or adding special features/game modes based on it is fucking terrible. Why would you ever want to do such a thing?
How do you illegally destroy a building?
I think it is valid for adding/changing game modes. (I doubt if I would like them, but that's another story.) I would integrate this fix if there would be a next TT scripts.dll release for Renegade, as I do not think it breaks anything for servers that do not attempt to revive buildings. (This wasn't so clear to me in August 2013 when it was originally requested, and I meant to investigate it but never got around to it. Sorry for that.)
EvilWhiteDragon wrote on Sat, 28 June 2014 11:45 How do you illegally destroy a building? Tunnel Beacon Building Hopping Ledge Beaconing on Glacier_Flying Killing the AGT above the map on Under Need I say more? I'm against building revival in terms of game modes, but the idea of having building revival incase one of the above occurs - I don't see why this is such a big deal. Iran even made the patch already.
Xpert wrote on Sun, 29 June 2014 00:29 EvilWhiteDragon wrote on Sat, 28 June 2014 11:45 How do you illegally destroy a building? Tunnel Beacon Building Hopping Ledge Beaconing on Glacier_Flying Killing the AGT above the map on Under Need I say more? I'm against building revival in terms of game modes, but the idea of having building revival incase one of the above occurs - I don't see why this is such a big deal. Iran even made the patch already. If you want the above, wouldn't it make more sense to fix/block these things rather than, as a workaround for when a mod is available, revive buildings?
StealthEye wrote on Sat, 28 June 2014 12:20 I think it is valid for adding/changing game modes. (I doubt if I would like them, but that's another story.) I would integrate this fix if there would be a next TT scripts.dll release for Renegade, as I do not think it breaks anything for servers that do not attempt to revive buildings. (This wasn't so clear to me in August 2013 when it was originally requested, and I meant to investigate it but never got around to it. Sorry for that.) Glad someone that was on the team has a reasonable response to this topic.
He resigned from the team four months ago; this is partly why TT stopped supporting stock Renegade - they have three(?) developers who have other commitments which they prioritise.
EvilWhiteDragon wrote on Sun, 29 June 2014 04:57 Xpert wrote on Sun, 29 June 2014 00:29 EvilWhiteDragon wrote on Sat, 28 June 2014 11:45 How do you illegally destroy a building? Tunnel Beacon Building Hopping Ledge Beaconing on Glacier_Flying Killing the AGT above the map on Under Need I say more? I'm against building revival in terms of game modes, but the idea of having building revival incase one of the above occurs - I don't see why this is such a big deal. Iran even made the patch already. If you want the above, wouldn't it make more sense to fix/block these things rather than, as a workaround for when a mod is available, revive buildings? Ya, wouldn't it make sense that the TT team fix/blocked these things?
Xpert wrote on Mon, 30 June 2014 16:31 EvilWhiteDragon wrote on Sun, 29 June 2014 04:57 Xpert wrote on Sun, 29 June 2014 00:29 EvilWhiteDragon wrote on Sat, 28 June 2014 11:45 How do you illegally destroy a building? Tunnel Beacon Building Hopping Ledge Beaconing on Glacier_Flying Killing the AGT above the map on Under Need I say more? I'm against building revival in terms of game modes, but the idea of having building revival incase one of the above occurs - I don't see why this is such a big deal. Iran even made the patch already. If you want the above, wouldn't it make more sense to fix/block these things rather than, as a workaround for when a mod is available, revive buildings? Ya, wouldn't it make sense that the TT team fix/blocked these things? Well, since I resigned of the TT team, I can't say for sure, but at the time the stance was to change bugs rather than possible gameplay. Tunnel beacon might have been intentional, and the other things could've been fixed when the TT team made some mapfixes. Apparently, public beta-testing didn't find these bugs when we were actively developing. As for building hopping I'm not sure what you mean btw. Oh and you seem to be quite angry at a team that consist of people who are (were) fixing Renegade in their free time. If you really need to be angry, then direct it at EA. When did they last showed any kind of support for Renegade?
Who said I'm angry? LOL? I'm not angry at all. I'm only responding to what you said. You talk about those things making sense to be fixed server side. I'm only saying, if it makes sense to fix them, then why didn't TT do it? Just like building revival. Iran made a fix for it to update the PTs, but no one has a provided a solid reason as to why it shouldn't be included in the 4.x patch other than the "because it won't" statement.
The most likely reason for the issues Xpert mentioned is that TT mostly has/had coders, and not much mappers. I do not think the issues can be solved properly in code (only with very nasty map-specific checks or such to avoid side-effects). I agree that, ideally, TT would fix issues like these. Like I said, that does not go for the IsDestroyed thing; I was planning to integrate that, because although it is not a technically perfect solution to building revival, it does not do any harm either. I think jonwil rejected the change originally because it is hard to determine from the code whether the actions that are performed on building destruction are reverted correctly when the building is revived: it appears that they are not. Before making a change, we normally check the impact on other parts, to avoid breaking them, which in this case is quite time consuming and error prone: a quick glance at the related code raises a lot of questions on whether everything will be properly synchronized. A proper solution would most likely require a significant time investment. I am still not convinced that buildings can be revived "perfectly" - including all announcements, sound changes, etc. - and safely - without introducing other bugs, with the IsDestroyed change alone. I wouldn't be until I had done that research, and I wouldn't do that because there were more stressing issues. Therefore, I would normally reject the change. Yet, as pointed out in this topic, the exact side effects are less important, because all servers not attempting building revival will be unaffected anyway. This is much easier to check (I checked it when I wrote my previous post in this topic). That is the reason why I would still implement the change, even though I am not sure of the exact impact it has.
StealthEye wrote on Mon, 30 June 2014 14:58 The most likely reason for the issues Xpert mentioned is that TT mostly has/had coders, and not much mappers. I do not think the issues can be solved properly in code (only with very nasty map-specific checks or such to avoid side-effects). I agree that, ideally, TT would fix issues like these. Like I said, that does not go for the IsDestroyed thing; I was planning to integrate that, because although it is not a technically perfect solution to building revival, it does not do any harm either. I think jonwil rejected the change originally because it is hard to determine from the code whether the actions that are performed on building destruction are reverted correctly when the building is revived: it appears that they are not. Before making a change, we normally check the impact on other parts, to avoid breaking them, which in this case is quite time consuming and error prone: a quick glance at the related code raises a lot of questions on whether everything will be properly synchronized. A proper solution would most likely require a significant time investment. I am still not convinced that buildings can be revived "perfectly" - including all announcements, sound changes, etc. - and safely - without introducing other bugs, with the IsDestroyed change alone. I wouldn't be until I had done that research, and I wouldn't do that because there were more stressing issues. Therefore, I would normally reject the change. Yet, as pointed out in this topic, the exact side effects are less important, because all servers not attempting building revival will be unaffected anyway. This is much easier to check (I checked it when I wrote my previous post in this topic). That is the reason why I would still implement the change, even though I am not sure of the exact impact it has. With the change it is possible to get a state as if the building had never been destroyed at all. I have tested it extensively. Everything including the announcements, the construction of vehicles, even custom death animations like on the map seaside canyon revert properly. My restore plugin even handles radar coming back properly as well as rebuilding harvesters, and restoring power to other buildings when a Power Plant is revived. I have done extensive testing and for the most part its entirely bug free (I have yet to find any bugs). My veterency plugin works properly without modification as well. The killed event is called successfully even after being restored and veteran points are awarded. Hopefully something can be worked out about the future of stock renegade as its definitely quite obvious that many are not satisfied with the current situation regarding development.
You are probably right, but I would still want to check it. I never implement something relying only on what someone else says. I hope so too.
We've been reviving the PP's, Ref's and Defenses for at least 2 years now. No problems whatsoever. Quite a few people including server owners and developers would love to see this happening for the Infantry- and Vehicle Factories.
IF I was going to implement this (for Renegade or otherwise) I would be implementing this by a separate piece of netcode and other logic that specifically existed to "revive buildings" and undo whatever normally happened when a building died (with each building having its own separate logic to undo everything) rather than implementing it by modifying the current logic that sets the IsDestroyed flag. I would do it that way because a specific "hey, bring this building back to life" flag (and engine call) that did all the right things would ensure the buildings are brought back to life properly and every step required is taken (there are things that happen as a result of building destruction that aren't immediately obvious). Note that this doesn't imply I will be working on this feature, just that that is how I would implement it if I did work on it and how I would expect it to be implemented by anyone else who ended up doing scripts work for Renegade (if that should happen in the future)
That sounds nice but a way to set just the isdestroyed flag would be nice as well. Both options have their advantages and disadvantages. I do have building specific code in my restore plugin, such as the refinery requesting a new harvester from the base controller and the communications center reenabling radar when restored. The power plant also turns base power back on when restored. Base Defenses just reattach their appropriate script. The Weapons Factory, Airstrip, Barracks, and Hand of Nod actually don't need anything special. Just the isdestroyed flag set on the clients is needed for them to work properly. Probably best to reset cangeneratevehicles as well though. If the harvester was dead before the restore and there is a still a refinery it automatically builds the harvester. Ultimately its up to you how it would be done of course. Anyway, here's some examples of some of the revive commands code. class CommandREVIVENODPP : public ConsoleFunctionClass { public: const char* Get_Name() { return "revivenodpp"; } const char* Get_Help() { return "REVIVENODPP - Revives the Nod Power Plant."; } void Activate(const char* argumentsString) { Revive_Building(Find_Power_Plant(NOD)); Commands->Set_Building_Power(Find_Power_Plant(NOD), true); BaseControllerClass* base = BaseControllerClass::Find_Base(NOD); if (base) { base->Power_Base(true); } } }; class CommandREVIVEGDIREF : public ConsoleFunctionClass { public: const char* Get_Name() { return "revivegdiref"; } const char* Get_Help() { return "REVIVEGDIREF - Revives the GDI Refinery."; } void Activate(const char* argumentsString) { Revive_Building(Find_Refinery(GDI)); Find_Refinery(GDI)->As_BuildingGameObj()->As_RefineryGameObj()->Allow_Harvester_Spawn(); } };
dblaney1, you can argue all you want, but in the end the result is that the TT coders would want to be sure of the complete impact of such change. Just trying it and seeing if there's any difference is not the same as completely evaluating the code to determine noting out of the ordinary happens. Since such analysis took/will take a lot of time, this hasn't been done yet, and will not be done by the currently known TT members.
Also, given that you've just admitted you need a plugin to undo some of the effects tells us that simply setting the flag is NOT enough, despite the fact you keep insisting that it is. Thus there is more work required to properly revive a building at an engine level without requiring additional plugins to fix the state of various things.
The following events happen in the On_Destroyed event (called when a building is destroyed): BuildingGameObj IsDestroyed is set to true, BaseControllerClass::On_Building_Destroyed is called (this plays the "building destroyed" sound and sets the "base destroyed" flag if all buildings are dead), BaseControllerClass::Check_Prerequisites is called (this goes with the prerequisite logic where stuff you buy from the sidebar can have a flag that says "this building must exist/must be alive for the object to be purchasable") and the building is made visible in the single player encyclopedia. AirFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) ComCenterGameObj BaseControllerClass::Check_Radar is called (this toggles the radar depending on what buildings exist/are alive) NavalFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) PowerPlantGameObj BaseControllerClass::Check_Base_Power is called (this sets the base power as appropriate based on the buildings that are present and alive) RefineryGameObj Destroys any instances of the harvester preset, also disables any spawners that would spawn the harvester preset (said spawners are used for maps that have a refinery but no weapons factory) SoldierFactoryGameObj Sets the CanGenerateSoldiers flag to off. WeaponsFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) So yes more happens than just toggling the flag and any engine feature that might be added in the future would be undoing those other things that happen (e.g. turning CanGenerateSoldiers back on for a SoldierFactoryGameObj, restoring the harvester spawners for a RefineryGameObj etc)
danpaul88 wrote on Tue, 01 July 2014 01:14 Also, given that you've just admitted you need a plugin to undo some of the effects tells us that simply setting the flag is NOT enough, despite the fact you keep insisting that it is. Thus there is more work required to properly revive a building at an engine level without requiring additional plugins to fix the state of various things. The flag that needs fixing only needs fixing client-side, when you revive a building the flag is SET properly server-side but clients don't update the flag. The other things that are needed like updating power to the building, allowing Harvester to repsawn and allowing infantry/vehicle purchases have been known and have worked properly for about 6 years or so now. So I'm not really sure why it's being brought up.
jonwil wrote on Tue, 01 July 2014 01:43 The following events happen in the On_Destroyed event (called when a building is destroyed): BuildingGameObj IsDestroyed is set to true, BaseControllerClass::On_Building_Destroyed is called (this plays the "building destroyed" sound and sets the "base destroyed" flag if all buildings are dead), BaseControllerClass::Check_Prerequisites is called (this goes with the prerequisite logic where stuff you buy from the sidebar can have a flag that says "this building must exist/must be alive for the object to be purchasable") and the building is made visible in the single player encyclopedia. AirFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) ComCenterGameObj BaseControllerClass::Check_Radar is called (this toggles the radar depending on what buildings exist/are alive) NavalFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) PowerPlantGameObj BaseControllerClass::Check_Base_Power is called (this sets the base power as appropriate based on the buildings that are present and alive) RefineryGameObj Destroys any instances of the harvester preset, also disables any spawners that would spawn the harvester preset (said spawners are used for maps that have a refinery but no weapons factory) SoldierFactoryGameObj Sets the CanGenerateSoldiers flag to off. WeaponsFactoryGameObj BaseControllerClass::Check_Vehicle_Factory is called (this sets the CanGenerateVehicles flag appropriately based on the buildings that are present and alive) So yes more happens than just toggling the flag and any engine feature that might be added in the future would be undoing those other things that happen (e.g. turning CanGenerateSoldiers back on for a SoldierFactoryGameObj, restoring the harvester spawners for a RefineryGameObj etc) Everything you put there can be already be done. It works properly already. The only thing that doesn't work is syncing the client isdestroyed flag. Thats why it is confusing that you would want to write an entirely new netcode/engine feature for something that already works except for one thing.
If you need to call 5 or 6 other things and have a load of logic depending on the type of building then it is *not* working properly in the engine itself. A correct implementation of a revive building function in the engine would undo all the effects of building destruction without loads of other function calls being necessary. It would also allow new features added in future to be hooked into the revival code as necessary.
danpaul88 wrote on Tue, 01 July 2014 06:03 If you need to call 5 or 6 other things and have a load of logic depending on the type of building then it is *not* working properly in the engine itself. A correct implementation of a revive building function in the engine would undo all the effects of building destruction without loads of other function calls being necessary. It would also allow new features added in future to be hooked into the revival code as necessary. The building specific revival code could be put into the base scripts code. There actually already is a revive building function in the scripts but it just resets the health and sets isdestroyed on the server to false. That way if a server operator wants to make specific changes to the revival behavior they would still be able to do so. I don't see a real reason to make this behavior hardcoded into the engine. Simply syncing the isdestroyed flag and providing a built in function in the scripts that handles the revive behavior properly would be the safest way to do this in my opinion. It doesn't involve substantial changes to the engine and wouldn't affect servers that don't use restores. Making large changes to the engine on the other hand, definitely could have adverse effects.
The current situation in regards to building revival on the server is fine; the building revival console commands plugin contains a full open-source implementation to revive all buildings and to set their state correctly and I know numerous people have already used the code, including dblaney1 and Xpert. The fact that the Revive_Building() command provided by scripts 4.0 only sets the IsDestroyed flag to false and does some other basic things is desirable over it implementing all the stuff to revive a building properly. For example you might want to add special logic to handle the Harvester when the Refinery or Weapons Factory get restored in your own mod, or you want base power to stay offline after restoring the Power Plant. Or you might want to attach your own custom scripts on a base defense after it has been revived. Not exactly common use cases but people might desire them.
iRANian wrote on Tue, 01 July 2014 07:29 The current situation in regards to building revival on the server is fine; the building revival console commands plugin contains a full open-source implementation to revive all buildings and to set their state correctly and I know numerous people have already used the code, including dblaney1 and Xpert. Exactly, no huge engine changes are needed, just a simple one to sync the client states. With that fix, the destroyed announcements and the ability to build units from a factory is fixed for clients which are the only things that currently are not working. Things like rebuilding harvesters, setting base power, the restarting of the refineries credit tick, etc work already.
TT team wants a proper fix, the random programmers want a hacky fix obviously TT wins
Ethenal wrote on Tue, 01 July 2014 08:49 TT team wants a proper fix, the random programmers want a hacky fix obviously TT wins There is nothing hacky about what we are doing. Everything we are using is right in the scripts api. We prefer it this way as it not only provides more flexibility, it also is less likely to break other parts of then completely changing the way the engine handles building controllers.