Just some my random patches

Can you help improve your favourite game? Hardcore C mages, talented artists, and players with any level of experience are welcome!
Post Reply
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Just some my random patches

Post by Ignatus »

Here I'll put some patches to 2.5 client (and maybe other Freeciv components) that I find useful. Sorry, they are chaotic tweaks of a thing tweaked before me (some old version of pneu's Longturn client) so they need some time to be worked around to fit to other builds (that's why they are not yet on HostedRedMine, and because the version Longturn is played now gets deprecated).

The first patch to put here is Lua tweaks:
* client unit selection manipulation (focus.iterate() etc.)
* find cities and players by string names;
* Unit.hp, Unit.moves_left /in move fragments/, Unit.veteran /integer/
* direction.name(Direction)
* Tile:coords(), Tile:map_coords() - just example functions returning two values
* City.supported_count, City:supported_iterate()

Another patch is an attemptto protect from misclicking cheap techs in tech tree when loss percent is not 100% without confirming that you want the tech now (already published in Discord).
Attachments
immetech-2_5.patch
(11.64 KiB) Downloaded 334 times
my-2.5-lt-lua.patch
(18.06 KiB) Downloaded 354 times
Last edited by Ignatus on Wed Aug 07, 2019 6:13 am, edited 1 time in total.
cgalik
Posts: 8
Joined: Sun Oct 08, 2017 12:40 pm

Re: Just some my random patches

Post by cgalik »

Cool! Thanks for sharing!
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

This is my full Longturn 2.5 patch (mostly client). Original one is at https://github.com/longturn/freeciv.
Server:
New starting option -Luadbscript /path/to/database.lua to runwith fcdb from compile dir. Just hate installing things.
Client (gtk2):
Mostly working solution for avoiding tech tree misclick. If you click a tech that can potentially be or surely is cheaper than you bulbs stack, a popup appears for if you are resolute to get it now. Alas got_tech package is no more sent in newer versions.
Common Lua API:
  • new class:

    Code: Select all

    Spaceship
     .structurals -- number of structurals
     .components
     .modules
     .success_rate --0.0 to 1.0
     .travel_time -- 0.0 to ...
     .state --nil, "Building", "Launched" or "Arrived"
     .owner
     :exists() --true
    
    Note that you can't find.spaceship(???), you find.player(plr_id).spaceship.
  • new functions:

    Code: Select all

    Resource find.resource(int rc_id)
    Resource find.resource(string rc_name)
    City find.city(Player plr, string name) -- was only (Player,id)
    Player find.player(string name) --was only (id)
    string direction.name(Direction dir) --"North", "Southeast" etc.
    
    Note: on isometric maps, north is at top right corner.
  • Auxiliary packages with constants OUTPUT (SHIELD etc.), CITIZENS (HAPPY etc.) and ORDER (MOVE etc.), see below.
  • new properties and methods:
    • Player

      Code: Select all

      boolean  .is_male
      Spaceship .spaceship
      integer :civ_population() -- population of known cities in "thousands"
    • City (note that in Lua arrays are enumerated from 1, so you have to increase enum values to get right indices, but in functions it is not needed)

      Code: Select all

        int .food_stock;
        int .shield_stock;
        int .airlift;-- number of airlifts left
        bool .did_buy;
        bool .did_sell;
        int .surplus[OUTPUT.xxx+1]; /* Final surplus in each category. */
        int .waste[OUTPUT.xxx+1]; /* Waste/corruption in each category. */
        int .unhappy_penalty[OUTPUT.xxx+1]; /* Penalty from unhappy cities. */
        int .prod[OUTPUT.xxx+1]; /* Production is total minus waste and penalty. */
        int .citizen_base[OUTPUT.xxx+1]; /* Base production from citizens. */
        int .usage[OUTPUT.xxx+1]; /* Amount of each resource being used. */
        -- values related to how costly you can change current production
        int .before_change_shields;
        int .caravan_shields;
        int .disbanded_shields;
        int .last_turns_shield_surplus;
        (Unit_Type | Building_Type) production -- a function with arbitrary Lua result type
        -- supported units
        int .supported_count
        iterator(Unit) :supported_iterate()
        -- population/economy data
        table{[Player] = int} .nationalities --a function returning Lua table
        int :happy_count(CITIZEN.[HAPPY]?, FEELING.[FINAL]?) -- counts citizens so happy at this level, arguments are optional
        int :govcenter_dist() [code]
      -- see below for tile, calculated for city owner
      double :waste_level(OUTPUT.[SHIELD]?, int gc_dist?) -- 0.000 (all saved) to 1.000 (all wasted), gc_dist if to put the city owner's govcenter that close
      double :waste_level(string output = "shield", int gc_dist?)
      [/code]
    • Unit_Type

      Code: Select all

        int .move_rate;
        int .fuel;
        int .happy_cost;
    • Unit:

      Code: Select all

        int .fuel -- actually left fuel
       int .activity_count -- sum for all units doing X at a tile and divide on 10,
       			     -- if the operation cost is reached, the extra is built/terrain transformed
       int .hp
       int .moves_left -- in fragments
       int :move_rate() -- in fragments
       int .veteran
       bool :can_do_activity(string activity)
       int :activity_rate() --speed of increasing .activity_count per turn
       string activity
       int :attack_power(Unit target)
       int :defense_power(Unit attacker)
       double :win_chance(Unit target)
       
    • Tile

      Code: Select all

      (int,int) :nat_coords() --native coordinates in one function returning 2 values
      (int,int) coords--map coordinates
      int :map_distance(Tile to) --in steps "of an airplane"
      int :govcenter_dist(Player plr) -- steps to the nearest plr's govcenter, -1 if none
Client API (all clients):
  • See above: focus.add(Unit), focus.remove(Unit), focus.contains(Unit), focus.number(), focus.iterate()
  • control.da - table of DIPLOMAT_* and SPY_* action constants
  • Unit control methods:

    Code: Select all

    :airlift(CIty dest)
    :load(Unit transport)
    :move(Tile dest)-- by default path
    :upgrade()
    :select() --put into focus
    :unselect() --out of focus
    bool :selected()
    bool :occupied() -- looks transporting sth
    :build_city()
    bool :road() --next road, false iff the unit can't build a road where it is
    bool :road(string road)-- road by rule name (false if can't or no such road)
    bool :base(string base)--build this base (false iff can't or no such base)
    bool :mine()
    bool :irrigate()
    bool :transform()
    :request_activity(string name) --only non-targeted activities (not "Road"/"Base")
    :give_orders(string orders, bool vigilant = FALSE, bool repeat = FALSE) -- string may contain only '0'..'7' for moves or /[wbduthe]/i for orders
    :give_orders(table orders, bool vigilant = FALSE, bool repeat = FALSE)
    
    The last two methods are a command-line manual tool to give units some orders (2000 in a row max). You can command to your legion to establish a trade route in a middle of nowhere, just it will not do it. vigilan means the unit will stop executing them if an enemy unit appears around, repeat means the orders will be repeated as long as possible (unit will not automatically go back, u:give_orders({"North"}, false, true) will just send the unit as far north as possible), but not more than one full round in a turn. If a unit finds required terrain alteration done, it skips to the next order, if it can't move, orders are canceled.

    Activities in fc2.5: "Idle", "Pollution", "Mine", "Irrigate", "Sentry" (give_orders: last order only), "Pillage" (does not work), "Transform", "Fortifying" (request_activity only), "Fallout", "Base" (give_orders only), "Road" (give_orders only), "Explore" (request_acttivity only)

    Each order in the table form of Unit:give_orders() must be a string, a number or a subtable with some or all of fields "road", "base", "activity", "dir", "order"; a number is always interpreted as an order and a string is interpreted as something in aforementioned precedence. Some orders may be wrapped into subsequence {times=NN, order1, order2} to repeat order1, order2 NN times. Unspecified fields are filled automatically to what makes sense with the specified ones (e.g. if a direction is specified then it is a move order with no activity, road or base, and if a road is specified, the order is "Activity" and the activity is "Road"). Order types (if nothing else matched, first letter of a string is case-ignore compared to the specified):

    Code: Select all

        ORDER.MOVE = 0, "M" -- move a step into a direction dir
        ORDER.ACTIVITY = 1, "A" --do an activity
        ORDER.FULL_MP = 2, "W" -- wait until movepoints are full, stacking these orders gives no effect
        ORDER.BUILD_CITY = 3, "B" --build or join to a city
        ORDER.DISBAND = 4, "D"
        ORDER.BUILD_WONDER = 5, "U" -- help wonder
        ORDER.TRADE_ROUTE = 6, "T", "E" --establish TR when the caravan is in a city, use movement otherwise
        ORDER.HOMECITY = 7, "H" -- in the table form, string /^help ?wonder/i is equivalent to "U"
    
    Directions compass for non-isometric maps (for isometric ones, rotate 1/8 turn clockwise):

    Code: Select all

    "Northwest" "North" "Northeast"
            '0'   '1'   '2'
    "West"  '3'   (*)   '4' "East"
            '5'   '6'   '7'
    "Southwest" "South" "Southeast"
    
  • City:

    Code: Select all

      :occupied() --some units inside
        :has_walls()
Attachments
lt2_5-ignatus.patch
(85.09 KiB) Downloaded 331 times
Last edited by Ignatus on Tue Feb 18, 2020 6:10 pm, edited 1 time in total.
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

Hm, like, Pneu has ruled out all his own client API patches to that branch.
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

Updated version.
General:
  • (Tile).continent
  • Player properties and method:

    Code: Select all

    .team_number
    .team_rule_name
    .team_name_translated
    :dipl_rel(Player to_whom, string rel) - mostly FC2.6+ "DiplRel" requirement compatible. You are allied and teamed with yourself.
    :can_see_tile(Tile tile, int vlayer?) - vlayer may be VISION.MAIN (default) or VISION.INVIS (for submarines).
  • City properties and method:

    Code: Select all

    .is_virtual - checks if we really know the city, some functions below may get ones we don't.
    .trade_routes_count
    :trade_routes - table {[City partner] = int trade_value}. Partner cities may be virtual for us, only few their properties are known.
  • Tile methods:

    Code: Select all

    City :worked() - city that works the tile now,
      may give a virtual city with only id known, not even its real name
    int :output(int otype, City city?, bool celebrates?) - tile's would-be output of otype
     (optionally, for the city given, optionally, in case it celebrates)
    
  • Unit methods and property:

    Code: Select all

    Unit :transporter()
    int :vision_radius_sq(Tile at_which?) - at current tile if not specified
    table{{order=int, ...}}, bool, bool :orders() - orders, repeat, vigilant, three values
     compatible with client's :give_orders() parameters
    .orders_index - current order number (starting at 1), -1 if no orders
    :cargo_iterate()
  • string graphic_str, graphic_alt = (Unit_Type):graphic_tags()
Client:
  • Module client introduced. client_player() replaced on client.player(). Other funcs:

    Code: Select all

    client.state() - "Initial", "Disconnected", "Preparing", "Observing", "Playing" or "Gameover"
    client.center(tile) - centers map on the tile
    client.tileset_name() - current tileset
    client.option(string name, bool server_opt?) - gets client (or server, if server_opt) option value
    The last function returns results of various types: boolean options are true/false, integer and bitwise are integer, string and font are string, color are table {background=string,foreground=string}, video modes not yet supported. Enumeration options like "mapsize" return numeric values that are metatabled to stringify as human readable strings, so can be used as both numbers and strings.
  • New unit methods:

    Code: Select all

    :request_pillage(string target?) - pillage tile improvement.
     If the target (a base, a road, "Irrigation" or "Mine") is not specified and there are options,
     a dialog box is displayed by the server response.
    :unload_from(Unit transport) - unloads (reverse to :load(transport)).
     You must own the transport and/or the unit (so, you can unload single foreign unit leaving the rest inside)
    :unload(Unit other_unit) - unloads self from other_unit or other_unit from self, whatever is sane.
    
  • Method (City):cma_name() - translated name of current CMA, or _("custom"), or nil if the city is not under CMA.
  • Signals "unit_created" (Unit), "unit_moved" (Unit, Tile from, Tile to) and "unit_removed"(Unit) (the latter is called before the unit is cleared from the client map) are triggered by incoming packages.
EDIT: Uploaded new patch:
  • fixed {times=...} qualifier in give_orders;
  • Gtk2 client: "Load Lua script" button now keeps the directory within a session (something more should be done to remember it between sessions)
  • Client Lua API: (City):change_production(Unit_Type|Building_Type)
  • General Lua APIfor cities:

    Code: Select all

    int :specialists(string spec_rule_name) - number of citizens assigned to this duty
    int .martial_law
    int .unit_happy_upkeep
    
Ah, found true latest Git repository to be tweaked: https://github.com/longturn/freeciv/tree/LT2_5 (it also has combat_info event that was not in the version I've patched):
Attachments
lt2_5-ignatus3.patch
(122.44 KiB) Downloaded 331 times
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

My patches for Longturn 2.6 here: https://github.com/Ihnatus/freeciv
Currently, server option "bombardment_reveal" is included that can leave some bombarded units (or even the bombarder) hidden if they are otherwise. To see the messages, turn on "Unit: Attack succeeded" and "Unit: Attack failed" messages in the client.
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

As it was discovered, the patches above likely may randomly cause segfaults because some strings from Lua are not strduped and may be cleared by gc, or something. So use with care.
Ignatus
Elite
Posts: 644
Joined: Mon Nov 06, 2017 12:05 pm
Location: St.Petersburg, Russia
Contact:

Re: Just some my random patches

Post by Ignatus »

I was asked to put here some scripts that I've used with the patched client. I can't remember which ones I did and with which version, but here are some to get the idea.
Attachments
lua-2.5-client-hacked.zip
Lua scripts for this client
(4.06 KiB) Downloaded 284 times
Post Reply