1. We have added the ability to collapse/expand forum categories and widgets on forum home.
    Dismiss Notice
  2. All Civ avatars are brought back and available for selection in the Avatar Gallery! There are 945 avatars total.
    Dismiss Notice
  3. To make the site more secure, we have installed SSL certificates and enabled HTTPS for both the main site and forums.
    Dismiss Notice
  4. Civ6 is released! Order now! (Amazon US | Amazon UK | Amazon CA | Amazon DE | Amazon FR)
    Dismiss Notice
  5. Dismiss Notice
  6. Forum account upgrades are available for ad-free browsing.
    Dismiss Notice

[BNW] How to make a unit destroy a resource via pillaging?

Discussion in 'Civ5 - Creation & Customization' started by Karatekid5, Aug 12, 2018.

  1. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    146
    Gender:
    Male
    Location:
    Pennsylvania
    With most of the community deep into Civ 6 it seems a little lonely around here!

    So, for my newest custom civ I'm making a rather silly unit that I intend to be able to destroy sea resources (it makes sense in context) if the pillage action is performed while sitting on top of one. Having used FramedArchitecture's old Global Warming mod and seeing it destroy resources via its' coastal flood mechanics, I was able to find some code that it uses to do so. DestroyResource seems to be a variable, but I'm unsure of how to change this or make LUA code fire off on the pillage action.

    The code from FramedArchitecture's mod:

    Code:
    if ( DestroyResource ) then
                    local player = Players[targetPlot:GetOwner()];
                    local pActivePlayer = Players[Game.GetActivePlayer()];
                    local iResourceID = targetPlot:GetResourceType(Game.GetActiveTeam())
                    
                    if ( iResourceID ~= -1 ) then
                        targetPlot:SetResourceType(-1);
                        if ( player == pActivePlayer ) then
                            local text;
                            local heading;
                            text = Locale.ConvertTextKey("TXT_KEY_GW_LOST_RESOURCE", GameInfo.Resources[iResourceID].Description);
                            heading = Locale.ConvertTextKey("TXT_KEY_GW_LOST_RESOURCE_SHORT");
                             pActivePlayer:AddNotification(NotificationTypes.NOTIFICATION_GENERIC, text, heading, iX, iY);
                        end
                    end
                end
    This is just a snippet but it seems pretty simple. Still, would this work if it checked for an AI civ? and if the AI uses this unit against the player can it display a notification indicating it?

    One more thing regarding this unit, it uses the Submarine Granny2 file, and while I can easily set custom birth and selection sounds for it, I was wondering if it was possible to change the movement and attack sounds.

    Thanks in advance to anyone that helps!
     
  2. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    665
    Gender:
    Male
    Location:
    The Netherlands
    The main problem you're facing right now is that there does not exist a "hook" (I.e. an event that fires whenever a certain condition is met) for when a tile is pillaged.

    There are two ways you can go from here:
    1) Use Lua trickery to keep track of tiles with resources which your UU entered, and every turn check if such tile was pillaged. The drawback of this method is that it will have a delay (I.e. the resource is not immediately destroyed upon pillaging), and that it will also destroy resources on tiles that were pillaged that the UU enters, but that were not actually pillaged by the UU.
    2) Make your mod depend on the VMC/CP DLL, which adds GameEvents.TileImprovementChanged(...). (I.e. the hook you actually wish to use). The drawback of this is that your mod now relies on a DLL mod, of which only one can be active at the same time. (This may not necessarily be a problem, especially since the VMC/CP DLL is pretty much the most used DLL out there.)

    If you're using GameEvents then yes. Be cautious if you're starting to use Events though; they may not always fire for the AI, when a tile is not visible, when quick combat is enabled, etc.

    Yes, this is certainly possible. The code for it is pretty much already in the snippet you provided. Adding some extra pPlayer:IsHuman()-checks will do the trick.

    Unfortunately I know little of 3D modding, but I can recall that this should be possible. It's just that I don't know how (and where I read this) exactly...

    Some of us are still around here ;)
     
  3. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    146
    Gender:
    Male
    Location:
    Pennsylvania
    And that makes me very happy! :hug: As a Civ 5 player who hasn't really enjoyed Civ 6, it's nice to see that I'm not being left behind!


    Both options look tempting. While I have little experience with Civ 5 LUA (scripting for every game is wildly different ><), it would be nice to not require a custom DLL, especially since I plan to release this and I don't know how many community patch users will want to have a Civ in their game that's based on these. But at the same time using the DLL means less scripting involved and a more accurate ability. I still have to dig around the code more (what I found only displays the notification, not the routine for actually destroying the resource), but which of the two options do you think would be better? And for a human player check does there need to be a variable in the parenthesis? Or just True/False?


    No worries! I did find the Audio 3D sounds that the Submarine uses in the game's files, but I'm just not sure how to attach my modified scripts to the unit itself.
     
  4. MariusMagnus

    MariusMagnus Chieftain

    Joined:
    Mar 12, 2018
    Messages:
    41
    Hey, people are still modding the original Star Wars Battlefront 2. So as long as people still have an interest in the game there will always mods made for Civ V!

    While using the CP DLL accomplishes exactly what you want, you have to remember that the end user will not always be interested in having to use another mod just to use yours (unless your mod is specifically tailored for it, or course), especially if said mod edits the DLL. For Troller's non-DLL solution, you could reword your unit's ability and make mention that it must end its turn on a pillaged resource to destroy it. That would at the very least make it seem like an intentional balance rather than a bug. Of course, you could potentially implement both using lua to check if the CP is active or not. In the end, it's all up to you.

    Wouldn't it be possible to check if the tile is already pillaged when the unit enters said tile to avoid this problem?

    Nope, IsHuman() is a simple boolean test that takes no parameters. Although the former is outdated, you can usually just check the modiki or search the forums for reference on how certain lua methods work.
     
  5. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    665
    Gender:
    Male
    Location:
    The Netherlands
    Remember Super Mario 64, Super Mario World, etc.? Those things never seem to age either ;)

    I also forgot to mention that Mac and Linux users will not be able to use your mod either. They cannot use any DLL mod unfortunately.

    I consider civ5 modding to be a game of tradeoffs. There are many things that are straight up not possible to do, but with some minor tweaks a whole new world opens up.
    I'd personally go for the first suggestion, since it requires more planning ("will my unit die if I leave it here?"), and you may not always wish to destroy a resource.

    Hmm, that would probably work.

    I highly recommend the Excel sheets linked at the bottom of the first post in this thread: https://forums.civfanatics.com/threads/bnw-lua-api-reference.558353/
    I've extended the Lua methods sheet by methods introduced in the VMC/CP DLL (by straight up looking into its source code), which I'll attach to this post too. (I've also marked some methods as broken, since I couldn't get them to not crash when used)

    EDIT: Just realized I read that a bit wrong. These sheets don't explain how to use the methods, it just states what parameters they take and what values they return.
     

    Attached Files:

  6. Karatekid5

    Karatekid5 Chieftain

    Joined:
    Nov 11, 2012
    Messages:
    146
    Gender:
    Male
    Location:
    Pennsylvania
    Sounds good! My first attempt at this is probably gonna fail completely but I'll do what I can to try and make it work!


    Former Super Mario World ROMhacker here! :goodjob:


    I'll likely go with suggestion #1 then since it causes the least amount of complications. I'll also give that spreadsheet a read and see if I can figure this out. Do they contain code for checking resource tiles and their current state? Or is there another mod I can look at for reference? I think having the code check whether or not the unit ends the turn on a pillaged tile would be the most balanced way to do it like Maruis Magnus suggested. It also eliminates the need to keep track of tiles the unit has been to that turn. But won't it also destroy the player's pillaged resources?

    I'll post again when I have some code built! :)
     
  7. Troller0001

    Troller0001 Not an actual Troll

    Joined:
    Mar 9, 2016
    Messages:
    665
    Gender:
    Male
    Location:
    The Netherlands
    There are quite a few Plot-methods that check stuff like: get the resource on the plot, get the improvement on the plot, is the improvement on the plot pillaged, etc.

    A simple check of whether the plot is in the user's lands would prevent that.

    Spoiler :

    Some methods of interest (all found in the sheet)
    Code:
    pPlot:GetOwner() --returns the ID of the owner of the plot. -1 if it's neutral land
    pPlot:IsImprovementPillaged() --returns true if the improvement on the plot is pillaged. false if there's not. (not sure what happens if there is no improvement on that plot, but probably the latter)
    pPlot:GetImprovementType() --returns the ID of the improvement on the plot. Returns -1 if there is no improvement.
    pPlot:GetResourceType() --returns the ID of the resource on the plot. -1 if there's no resource
    
     
  8. whoward69

    whoward69 DLL Minion

    Joined:
    May 30, 2011
    Messages:
    8,090
    Location:
    Near Portsmouth, UK
    Pretty sure the snippet as given won't work for Oil, if the plot is already within the boundary of a city. The game core caches the resource counts as a city acquires tiles, so you need to jump through hoops of un-owning the tile, clearing the resource, then re-owning the tile. Check out how IDE does it - as that's where I borrowed the code for my Units - Herdsmen mod
     
    Troller0001 likes this.

Share This Page

Ebates: Get Paid to Shop