1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

[TOT] Lua code snippet to use land units as a transporter

Discussion in 'Civ2 - Scenario Creation' started by SorFox, Dec 24, 2019.

  1. SorFox

    SorFox Chieftain

    Joined:
    Aug 29, 2015
    Messages:
    16
    Location:
    somewhere in Central Europe
    As far as I am aware of, the topic has been of interest for scenario developers quite a while. Many within the community have addressed the issue about transport mechanics to TheNamelessOne as well, but it was – sadly enough – never part of one of his releases. However, I think with Lua he gave us a tool to come pretty close to what the idea is all about.

    At least one dimension of the concept is to give a land unit (call it “truck”) the ability to carry other land units, like freighter units do on see domain. Before Lua I was never completely happy with the following workaround applied:
    • attaching sea units the paradrop ability and give them the right picture and name
    • declare ocean tiles as impassable terrain, and
    • give every real sea unit the ability to ‘override impassable terrain’ via rules.txt – except the truck unit.
    As a result, these units could only jump from city to city and deliver their ground unit freight, if they do not want to get lost on ground where they cannot move away any more.
    Apparently, with Lua and the civ.scen.onKeyPress function a nice option appeared to let a land unit do this job (of carrying other land units) in a more logic, efficient and straightforward way.

    Please find attached a basic solution for this concept which can be integrated into a TOT scenario using Lua events and TOTPP. The ‘events.lua’ file provides a working and adjustable implementation – feel free to incorporate and customize it to your needs!
    Moreover, to have a basic setup for doing some quick tests on your own, I have attached other files as well. Simply unpack them and copy the folder ‘landTransporter’ into your TOT scenario directory.

    Finally, I would like to thank three persons who made it possible to write the code. Firstly, the guy which most Civ2 enthusiast have to mention ;) TheNamelessOne, for giving us all the wonderful options with the TOTPP. Secondly, Prof. Garfield, with his tireless and highly appreciated effort to tackle the issue of Lua programming for the general community. Lastly and in particular, Knighttime, who helped me (as Lua newbie) every time I got stuck with all his super helpful tips.

    Happy Civing!
     

    Attached Files:

    Last edited: Jan 1, 2020
    Prof. Garfield and JPetroski like this.
  2. Prof. Garfield

    Prof. Garfield Deity Supporter

    Joined:
    Mar 6, 2004
    Messages:
    2,648
    Location:
    Ontario
    Congratulations! You've put together some complex code to achieve new functionality. You should be proud.

    I do have a fairly simple suggestion for improvement. At the moment,

    Code:
    local unitTypeAllowedToBeLoaded = civ.getUnitType(0)            
    local supplyTruckType = civ.getUnitType(1)                           
    
    Are both a single unit type. My suggestion is to make tables (indexed by unit type IDs) which are true when the unit is allowed to be loaded or a supply truck type respectively.
    That is, for example,
    Code:
    local cargoUnitType = {}
    cargoUnitType[0]=true
    
    and replace
    Code:
        if activeUnit.type ~= unitTypeAllowedToBeLoaded then
    
    with
    Code:
     
    if not(cargoUnitType[activeUnit.type.id]) then          
    
     
  3. SorFox

    SorFox Chieftain

    Joined:
    Aug 29, 2015
    Messages:
    16
    Location:
    somewhere in Central Europe
    I am! :lol: But now – after you said that – even more, thanks!

    Your enhancement is definitely needed in order to make the code more scalable and dynamic. Good point, this will go into version 2.0, where also a "dialog:addCheckbox" function should be integrated. Currently, if the truck is full always the first unit will be unloaded if "k" is pressed. But if one would for example allow five units to be loaded, maybe the player wants exactly to unload unit no. 3 out of 5. To be continued…

    But atm I am struggling with a different Lua problem, may I ask you @Prof. Garfield directly, to have a look at this issue?
     
  4. Prof. Garfield

    Prof. Garfield Deity Supporter

    Joined:
    Mar 6, 2004
    Messages:
    2,648
    Location:
    Ontario
    Something to think about for a version 2.0 is the fact that unit id numbers are not necessarily fixed. I'm not sure if/when the units id numbers are changed. I suspect it would be when saving the game, if the game notices a lot of 'dead' units in the roster, and it thinks it can save some space. Maybe you can use the 'carried by' attribute to record what unit is carrying what other unit. One way would be to save as many attributes of the carrier/carried as possible in an onSave event, so that if the game messes with the unit id numbers, the situation could be reconstructed.

    I have a checkboxMenu function in my text library, which might save you some work.
     
  5. tootall_2012

    tootall_2012 Prince

    Joined:
    Feb 11, 2012
    Messages:
    561
    Hi Sorfox,

    It's funny, just this week I was thinking if TNO ever came back there are two items I would dearly like to see him complete: the first was the ability to upload the units and rules files in Lua (instead of just the current terrain graphics) and thereby get rid of the need to use the bat program to switch files altogether. The second was to finalize his long planned transport mechanism.

    There were many features you implemented for MGE which I liked very much and as you may have seen even asked TNO to add your scroll bar function to ToTPP. I don't play lua scenarios without it, so thanks for your concept.

    I took a high level look at your transporter lua file and it seems quite interesting, though I still have to understand the details of how to implement it in a scenario. Could be of use in one of my planned scenarios, the Battle of Italy 1943 -45.

    Thanks for your work!
     
  6. SorFox

    SorFox Chieftain

    Joined:
    Aug 29, 2015
    Messages:
    16
    Location:
    somewhere in Central Europe
    Hi tootall_2012,

    Thanks for your warm words! But could it be that you mistake me for someone else?
    Honour to whom honour is due, which in this case – if I associate correctly – is "FoxAhead". Maybe I should change my name, too many foxes around here … ;)

    Although he’s also an autodidact on the field of programming, he (FoxAhead) is way more the technical guy – more in the league of Prof. Garfield. While I see myself more as a scenario designer, much more like you or JPetroski, just to give two examples. If one would start such silly stereotyped thinking at all and I just named you and John due to the fact that I like your scenarios very much, your ideas, creativity, thinking out of the box, historical knowledge etc. etc. But only in cooperation with the "real" technical experts we can get the most out of Civ2. Due to the very nature of this old game, which itself still proofs to be capable of development, as we can see with Lua. And that leads me to what you put so perfectly right in a different thread
    To make a long story short: I take the credit for this feature and pass the rest on. Many thanks!! :thumbsup:
     
  7. tootall_2012

    tootall_2012 Prince

    Joined:
    Feb 11, 2012
    Messages:
    561
    Yes you are correct. My sincere apologies to both you and FoxAhead for my mistake :o, but thank you still for your transporter module!
     
  8. JPetroski

    JPetroski Deity

    Joined:
    Jan 24, 2011
    Messages:
    2,493
    I've only been able to read this thread and haven't had a chance to check out the actual module yet, but I'm VERY excited to! You've just freed up some unit spaces for many scenarios in my head! This looks awesome!
     
  9. JPetroski

    JPetroski Deity

    Joined:
    Jan 24, 2011
    Messages:
    2,493
    I had a chance to play with this. This is extremely interesting how you've done this, and very intuitive!

    I'm not sure if you're aware of this, but I did some testing and not only have you created a LAND transporter, but you've also created an airlift system. If you change the truck's domain to "1," it can cross ocean tiles, and deposit units elsewhere. The only issue with this currently is that the units can unload into the ocean directly. This might actually be neat for certain units (think Navy Seals rescuing hostages on Somali pirate ships) but for most applications, it's probably undesirable. Perhaps consider having a check of what type of terrain tile the "truck" is on to see if unloading will work? This also would open up new possibilities:

    -You might have trains that carry units but can only deposit them at freight yards;
    -You might have helicopters that can only land infantry in clearings;

    (Edit: you might also add a check to ensure that a unit can only load on certain terrain so that you don't have a situation where a C-47 is picking up troops on the fly, and has to go to a special "airfield" terrain to do so).

    Etc.

    I do share Garfield's concern with the below, but hopefully you can work this out.

    I have to say I'm really impressed by reading your code. It's inspiring given that you call yourself a designer rather than a coder as it is miles above what I would hope to do myself, but given your inspiration, maybe I need to rethink things. I really need to just sit down and complete Prof. Garfield's lessons and try to complete a thing or two. It is great to see someone have success with this difficult task and I really like the way you've organized the code too - it's easy to read and understand exactly what each line is supposed to do. Maybe if I ever write my own, I'll "show my work" this way so that when it breaks, the great minds here can at least read my thought process line by line and help me figure out what went wrong.

    Just a tiny suggestion for a future upload:

    Please replace the first two lines of @UNITS_ADVANCED with
    11111111, 00000000, 0, 0000000000000000,0000000000000000,0000000000000000, 10000000 ;Infantry
    11111111, 00000000, 0, 0000000000000000,0000000000000000,0000000000000000, 10000000 ;Truck

    The single 1 in the G column will override sprites for everyone and let your units show regardless of what settings someone might have. They weren't appearing for me and while this is a simple fix for me as I know how to handle it, someone that's getting started might not recognize the issue.

    @SorFox, I'd like to give you my heartfelt congratulations on this and also to say thank you. You've broken new ground, come up with a really cool tool, and I'm excited to see what you come up with in version 2.0. I'm very, very, very excited to see if I can utilize this at all in a new scenario. Well done!!!!
     
  10. Knighttime

    Knighttime Warlord

    Joined:
    Sep 20, 2002
    Messages:
    148
    Congratulations @SorFox and thanks for posting this! I haven't tested it out yet but it's certainly a nice feature that could be useful in a variety of circumstances.

    I know for a fact that unit ID numbers get recycled -- meaning that whenever a new unit is created, it is assigned the lowest ID number that is not currently in use in the game. So whenever you store a unit ID number in a Lua table, you have to be very thorough about making sure that entry gets removed if the unit with that ID is killed. Adding code to onUnitKilled() can take care of that, but unfortunately I don't think this fires if a unit is disbanded :sad: so there may not be a perfect solution. In playing around with this type of thing, I've settled on storing the unit ID, unit type, and unit owner and checking all three of those whenever I reference that table entry. If the unit in the game with that ID has the same type and owner, then it's probably the same unit; but if either the type or the owner is different, then the original unit must have been killed/disbanded and the ID is now being used by a different unit that was created later.

    I had never heard (or considered) that the game itself might do other "compacting" of unit IDs by reassigning a different ID to an existing unit. I'd definitely be interested in knowing if anyone can confirm this and document a pattern for how/when that happens.
     
  11. Prof. Garfield

    Prof. Garfield Deity Supporter

    Joined:
    Mar 6, 2004
    Messages:
    2,648
    Location:
    Ontario
    Maybe check when a new unit is created instead. If the new unit's id matches something already in the table, then you know the old unit has been eliminated. You wouldn't catch units created from huts, but you can get units that are built and units created by events (though you'd have to check in every single create unit event, which could end up being a problem).

    I personally would try to work around this issue rather than try to do anything 'important' relying on the unit id. In OTR, we only use it to record combat 'reactions', which aren't a huge problem if they occasionally don't fire or get extra shots.

    I thought I read somewhere that these ID numbers are not preserved (or at least guaranteed to be preserved), but I can't find it now. Catfish's Saved Game File Format has a 'dynamic' id that is reset, but I don't know what that is. If the unit's ID number doesn't get reset, that would be helpful, and expand the scope of what the state table can do and record.

    Yes, this is something worth knowing. I'll have to think about how to do it.
     
  12. SorFox

    SorFox Chieftain

    Joined:
    Aug 29, 2015
    Messages:
    16
    Location:
    somewhere in Central Europe
    Since this issue seems to be a potential show-stopper I would like to share my thoughts – and in later posts I will comment the great feedback I got so far. Already big thanks, this thread has yet become a good example how a feature gets better by the cooperative work within the community!
    To start with, I was aware of the topic – simply because one of my “Lua trainers” posted it earlier. ;)
    Or, as put lately
    I can be mistaken and encompassing tests are still needed, but I can confirm as well that the game touches unit IDs only in the mentioned cases (killed or disbanded) and of course when a new unit is created/build – but not for an existing unit. I based my code on exactly this assumption. That's also the reason why I abandoned the originally planned procedure:
    • if loading a unit then civ.deleteUnit(unit)
    • if unloading the truck then civ.createUnit(unittype, tribe, tile)
    and instead decided to use a kind of "elevator procedure" in order to just teleport the unit to a different map and set it to "sleep". That is, the unit will stay a "physical unit" (though out of visibility), but with its unique ID and attributes. To summarize, I don’t see that the main use cases of the feature will be touched in a negative / unintended way by the ID issue.

    Of course there are some "special" cases to consider.

    Special Case One:

    Needs to be implemented: An automated (Lua) unload procedure of the carried units in case the truck gets killed, maybe with some damage for the affected load.

    Special Case Two:
    Of course the player will still be able to activate the loaded unit by means of the city menu. Consequently, all terrain (tiles) on the 2nd map should be specified as "impassable terrain". That goes on my "issues to tackle" list as well.

    Special Case Three:
    The player disbands the truck by chance or deliberately (by city menu if home city not "none"). Consequence: Since the carried units are bound to the carrier (within the table), they cannot be unloaded any more. But they will not be killed, they are just kind of "lost" on the 2nd map. And why should the player deliberately do this? This would deprive him/herself of the ability to continue using the units in the game. I do not see any exploitability from a players’ perspective (to e.g. gain an unjustified bonus). It can only happen by chance, but one could for example add some words in the Labels.txt file. Instead of one word "Disband", use "Disband (consider truck deletion issues)" to keep the player aware of.

    Special Case Four:
    The player disbands the truck load by chance or deliberately (by city menu if home city not "none") and then go to the truck and try to unload the – according to the state.table still loaded – units. Here we get an error message by Lua "\events.lua:158: bad argument #1 to 'teleportUnit' (civ.unit expected, got nil)". Solution: Apply a procedure to keep the code running (e.g. an extra loop with a kind of fake unit creation or filling of the state.table) on the one hand and a text message to the player on the other, kind of "Sorry sir, could it be that you disbanded the units loaded on the truck? In any case we have to report that we lost them and broke up the unloading procedure."

    As you can see, also for this case there is no exploitability scenario, like save the resource of the home cities by disbanding and then still unloading the truck – with units having a "none" home city instead. It's simply not possible.

    In either case (3 and 4) the easiest solution would be to mark the respective units as "non-disbandable" (Rules.txt, @UNITS_ADVANCED, G column) and activate the TOTPP feature "City screen unit disband", which disables the "Disband" option in the city screen's "Supported units" box for non-disbandable units. Just wanted to show also alternatives.

    Hopefully I was able to dispel some concerns and all my considerations and findings so far turn out to be true. Fingers crossed and happy New Year anyway! :)
     
    Last edited: Jan 2, 2020
    JPetroski likes this.
  13. SorFox

    SorFox Chieftain

    Joined:
    Aug 29, 2015
    Messages:
    16
    Location:
    somewhere in Central Europe
    That was the plan. And I really do appreciate it. Thanks!!
    However, to be fair and honest, not for nothing I named in the acknowledgment especially the two last guys… ;)
    I was aware that this feature is expandable and adjustable to a lot of different settings. However, I barely imagined the named options. Cool stuff! So, it’s great to see that there is potential and how the creativity of adjusting to individual needs already starts...
    Good that you mentioned it! Since I removed those "*.spr" files from my Civ2 directory, I completely forgot about the issue. It will be included in version 2.0, too.
     
  14. JPetroski

    JPetroski Deity

    Joined:
    Jan 24, 2011
    Messages:
    2,493
    The more I play around with this, the more I like it. It's a really cool trick to "park" the cargo unit elsewhere, so that only the "truck" unit's qualities matter.

    For example, one might name the "truck" "Guderian," allow that unit to cross impassable terrain, and forbid regular tanks from crossing it. Then, one might make forest terrain impassable, and voila, you have a "leader bonus" where Guderian can lead panzers across the Ardennes.

    Very, very, very nifty module, SorFox.
     
    SorFox likes this.

Share This Page