AtomicTorch Studio Forums

VoidExpanse => Modding info => Topic started by: Pasadenasman on January 31, 2016, 10:23:17 AM

Title: WIP Salvaging
Post by: Pasadenasman on January 31, 2016, 10:23:17 AM
Hi guys,

Fairly new to modding and i'm trying to learn/do some basic stuff. I'm considering giving some extractable ressources to debris floating in space. Before granting them differents ressources and quantity, i'm focusing on giving the asteroid miner (the civilian one) the possibility to "mine" debris. So i modified all the xml file of debris (debris barrel, solar panel etc) in the following way :
<root>
   <header>
      <id>debris_generic_barrel_02</id>
      <title>(Unused)</title>
      <enabled>1</enabled>
   </header>

   <gfx>
      <model>space_objects/debris_generic_barrel_01.obj</model>
      <textures>
         <diffuse>space_objects/debris_generic_barrel_01/dif_256_green.jpg</diffuse>
         <normal>space_objects/debris_generic_barrel_01/nrm_256.jpg</normal>
         <specular>space_objects/debris_generic_barrel_01/spec_256.jpg</specular>
      </textures>
   </gfx>

   <sfx>
      <!-- none-->
   </sfx>

   <data>
      <scale_range>0.5;0.5</scale_range>
      <rotation_range>-1.0;1.0</rotation_range>

      <physics>
         <mass>20</mass>
         <shapes>
            <shape>
               <type>box</type>
               <offset>0.000;0.000</offset>
               <angle>0</angle>
               <size>1.679;2.987</size>
               <mass>8</mass>
            </shape>
         </shapes>
      </physics>
      
      <type>1</type>
      <difficulty>1000</difficulty> <!-- how long will it take to mine asteroid -->

      <contents>
         <resource>
            <id>ore_glepsite</id>
            <quantity>500;800</quantity>
            <extraction>10</extraction>
         </resource>
         <resource>
            <id>ore_cyactite</id>
            <quantity>200;300</quantity>
            <extraction>5</extraction>
         </resource>
         <resource>
            <id>ore_fraclasite</id>
            <quantity>100;200</quantity>
            <extraction>2</extraction>
         </resource>
      </contents>
      
   </data>
</root>

and changed the harvester by the following :
<root>
   <header>
      <id>device_mining_civilian</id>
      <title>Civilian mining device</title>
      <description>The most basic mining device. It works... but not as well as you would like. The good thing about it is that you don't need any qualifications to use it, unlike other mining devices.</description>
      <enabled>1</enabled>
   </header>

   <gfx>
      <icon>items/devices/device_mining_civilian.png</icon>
   </gfx>

   <data>
      <type>9</type>
      
      <shops>
         <shops_level>1</shops_level>
         <faction_filter></faction_filter>
         <faction_only>0</faction_only>
         <faction_reputation>0</faction_reputation>
         <price>0</price>
      </shops>
      
      <flags>
         <flag>civilian</flag>
      </flags>

      <upgrades_max>0</upgrades_max>
      <upgrades>
         <!-- none -->
      </upgrades>

      <requirements>
         <!-- none -->
      </requirements>

      <effects>
         <!-- none -->
      </effects>

      <item_data>

         <durability>25000</durability> <!-- max durability -->

         <cooldown>1</cooldown> <!-- cooldown in seconds after initiation of usage -->

         <!-- DEVICE ACTIVATION
            determines a way the module can be activated
         -->
         <target>3</target> <!-- 0- N/A, 1- self, 2- area (around self), 3- object, 4- coordinates -->
         <target_parameters>
            <range>10</range> <!-- used for all except "self" and "area" mode. -->
            <area>10</area>
            <!-- determines area of effect on specified coordinates. only for "area", "target", "coordinates" -->
            <target_filter>asteroid,debris</target_filter>
            <!-- only for "target" mode. For target can be specified: asteroid, ship, crate, jumpgate, base -->
         </target_parameters>

         <!-- DEVICE ACTION
            determines how module effect should be applied
         -->
         <action_type>2</action_type> <!-- 0- N/A, 1- immediate, 2- per frame, 3- on complete -->
         <!-- the following configuration is only applicable for "per frame" and "on complete" modes -->
         <action_parameters>
            <duration>0</duration> <!-- 0 for infinite -->
            <cancel_on_move>1</cancel_on_move> <!-- module is disabled when ship moves -->
            <cancel_on_take_damage>1</cancel_on_take_damage> <!-- module is disabled when ship takes damage -->
            <cancel_on_deactivate>0</cancel_on_deactivate> <!-- module is disabled when user activates it again (in this case deactivates) -->
         </action_parameters>

         <!-- CUSTOM PARAMETERS
            can be any number parameters, also accessible through scripts
         -->
         <custom_parameters>
            <speed>300</speed>
            <amount>75</amount>
            <energy>40</energy>
         </custom_parameters>

         <!-- script definition for this module, must be valid filename -->
         <script>ModuleMining.js</script>

      </item_data>
   </data>
</root>

When trying to do so in game, i have the following notification on the top left of the screen : http://images.akamai.steamusercontent.com/ugc/610604005651531581/BC3397265173812EEA79F007B85B1A55F8C0DA8F/ (http://images.akamai.steamusercontent.com/ugc/610604005651531581/BC3397265173812EEA79F007B85B1A55F8C0DA8F/)

So any idea what can i do to fix this ? Thanks in advance !
Title: Re: WIP Salvaging
Post by: Lurler on January 31, 2016, 10:59:48 PM
Hm, my understanding is that you need to mark the debris with the same tag you are using in the device. Specifically "debris".
Though, to be honest I am not even sure that's possible. But probably yes. I do not see the same tag on asteroids though, so maybe this behavior is hardcoded...
Title: Re: WIP Salvaging
Post by: Pasadenasman on February 01, 2016, 03:16:21 AM
Hi,
Thanks for responding and yes. I cant see a tag on asteroids too... and i dunno if simply add a tag will do the trick. Maybe adding "mineable" on debris... maybe... will try this evening and post the result here.
Title: Re: WIP Salvaging
Post by: ai_enabled on February 01, 2016, 03:48:13 AM
The mining is not hardcoded at the game core code, it's implemented with Mining devices at mining device script "data\scripts\devices\ModuleMining.js" it calls GetAsteroidDescriptionByID() so it expect to work only with asteroids.

I think it's possible to introduce special mining device to "mine" debris, but then you need to make another device script for it.
Title: Re: WIP Salvaging
Post by: ai_enabled on February 01, 2016, 03:59:51 AM
I just checked and there are no special tag for debris, they are known by the game core as "spaceobject" tag.
So if you want your device to act on debris, you need to use "spaceobject" filter, not "debris".
You cannot introduce new tags :-(. It's hardcoded.
Title: Re: WIP Salvaging
Post by: Pasadenasman on February 01, 2016, 01:45:53 PM
So, i ve tried this and still not working. Got the same "unlocalized" notification en top left but this time, i got it with when pointing cursor on asteroids too. As you can see, this time, the notification doesn't mention : asteroids and "unlocalized", but just "unlocalized". So i guess the game just cant figure what kind of object i'm pointing or the script can't find the correct tags or item_id to do the job. At the end of the day, i got no clue of what is going on :D

So, here's where i am, i've modified a few things in the following files. Created a new script for the salvaging device based on the mining device.

http://steamcommunity.com/sharedfiles/filedetails/?id=613899165 (http://steamcommunity.com/sharedfiles/filedetails/?id=613899165)

ModuleSalvaging.js (Salvaging device script)

/*
Script can contain following functions:
OnUpdateCache - called when device is equipped or initialized, or some values are changed
OnStart - called when device is activated (for all)
OnFrame - called every frame (only for "per frame" mode)
OnFinished - called when device effect should be applied (only for "per frame" and "on complete")
*/

using(ship);
using(console);
using(generator);
using(game);
using(visual);
using(actions);

function OnUpdateCache(args)
{
    //(ship's cache)-based updates
    var mining_range_modifier = ship.GetFinalCacheValue(args.ship_id, "mining_range");
    args.range = args.range * mining_range_modifier;

    var mining_amount_modifier = ship.GetFinalCacheValue(args.ship_id, "mining_amount");
    args.custom_parameters.amount = args.custom_parameters.amount * mining_amount_modifier;

    var mining_speed_modifier = ship.GetFinalCacheValue(args.ship_id, "mining_speed");
    args.custom_parameters.speed = args.custom_parameters.speed * mining_speed_modifier;

    // console.Print("Mining range modifier current: " + mining_range_modifier);
    // console.Print("Mining amount modifier current: " + mining_amount_modifier);
    // console.Print("Mining speed modifier current: " + mining_speed_modifier);

    // console.Print("range now is " + args.range);
    // console.Print("amount now is " + args.custom_parameters.amount);
    // console.Print("speed now is " + args.custom_parameters.speed);
}

function OnStart(args)
{
    // console.Print("Mining module started");

    //calculate max_length property value based on speed and asteroid's difficulty
    var tags = game.GetGameObjectTags(args.target_id);
    args.duration = asteroid.difficulty / args.custom_parameters.speed;
    args.cooldown = args.duration;

    visual.DeviceActivateEffectOnObject(args.ship_id, args.device_id, "mining_visual_effect", args.duration, args.target_id);

    // console.Print("max_length now is " + args.duration);
    game.ShipPlaySound(args.ship_id, "mining_start_" + args.slot_id + "_" + args.target_id, "special/mining_start.ogg", 0, false);
    game.ShipPlaySound(args.ship_id, "mining_process_" + args.slot_id + "_" + args.target_id, "special/mining_process.ogg", 0.1, true);
}

function OnFrame(args)
{
    // console.Print("Mining module frame. Energy deduction");

    var energy = args.custom_parameters.energy * args.seconds_multiplier;
    var current = ship.GetCurrentValue(args.ship_id, "energy");

    if (current > energy)
    {
        ship.SetCurrentValue(args.ship_id, "energy", current - energy);
    }
    else
    {
        ship.DeviceDeactivate(args.ship_id, args.slot_id, true);
        game.SendNotificationError(game.GetShipOwner(args.ship_id), $n0001, $n0002); // Mining failed: Energy depleted.
    }
}

function OnFinished(args)
{
    visual.DeviceDeactivateEffect(args.ship_id, args.device_id, "mining_visual_effect");

    // console.Print("Mining module finished");
    actions.InvokeTrigger("onAsteroidMined", { asteroid_id: args.target_id });


    //parse asteroids contents, add whatever we want
    var shipId = args.ship_id;
    var spaceobjectId = args.target_id;
    var cont = game.GetAsteroidMiningListByID(asteroidId);
    var amount = args.custom_parameters.amount;
    var Q = 2.0; //dependency of mining amount and extraction difficulty
    var total_amount;
    var extraction_diff;
    var extracted;
    var items_money_added = 0;
    var something_extracted = 0;
    var cargo_full = false;
    var bSomethingLeft = false;

    // console.Print("Mining module finished with amount "+amount);

    for (var i = 0; i < cont.length; i++)
    {
        //formula of mining extraction
        total_amount = Math.max(0, Math.floor(Math.pow(Math.max(amount - 50, 0), 0.25) * cont.extraction) - 2);

        if (total_amount == 0 && cont.quantity > 0)
        {
            bSomethingLeft = true;
            continue;
        }
        // console.Print("Extracting " + cont.name + " : _diff" + extraction_diff + " total: " + total_amount);

        extracted = game.TryToRemoveContentFromAsteroid(spaceobjectId, cont.name, total_amount);

        if (extracted > 0)
        {
            something_extracted++;

            var res = ship.AddItem(shipId, cont.name, extracted);
            if (res != null)
            {
                items_money_added += game.GetItemPrice(cont.name) * res.quantity;

                //if item is resource, but wasn't added fully, then assume cargo is full
                if (res.type == "resource" && res.quantity < extracted)
                {
                    cargo_full = true;
                }
            }
            else
            {
                //if nothing was added, check if resource - nad if yes, cargo is full
                if (game.IsResource(cont.name))
                {
                    cargo_full = true;
                }
            }
        }
    }

    // give some experience
    if (items_money_added > 0)
    {
        var mining_exp_mult = 1 + ship.GetFinalCacheValue(args.ship_id, "mining_experience");
        ship.SetCurrentValueDelta(shipId, "experience", (mining_exp_mult * items_money_added) / 7);
        // console.Print("Mining experience multiplier: " + mining_exp_mult);
    }

    if (something_extracted <= 0)
    {
        if (!bSomethingLeft)
        {
            game.SendNotificationError(game.GetShipOwner(shipId), $n0003, $n0004); // Asteroid is depleted.
        }
        else
        {
            game.SendNotificationError(game.GetShipOwner(shipId), $n0005, $n0006); // Cannot extract.: To extract certain minerals, you need better mining equipment.
        }
    }

    if (cargo_full)
    {
        var player = game.GetShipOwner(shipId);
        game.SendNotificationError(player, $n0007, $n0008); // Your cargo hold is full.
        game.PlaySound(player, "items/generic_on_empty.ogg");
        game.PlayVoice(player, "cargo_hold_is_full");
    }

    game.ShipStopSound(args.ship_id, "mining_process_" + args.slot_id + "_" + args.target_id);
    game.ShipPlaySound(args.ship_id, "mining_start_" + args.slot_id + "_" + args.target_id, "special/mining_complete.ogg", 0, false);

    if (ship.GetFinalCacheValue(shipId, "see_asteroid_contents") > 0)
    {
        // // console.Print("Sending asteroid contents");
        ship.SendAsteroidContents(shipId, spaceobjectId);
    }

    game.AddStat(shipId, "asteroids_mined", 1);
}

function OnCancel(args)
{
    //// console.PrintError("Mining module canceled of " + args.cancel_reason);

    if (args.cancel_reason.indexOf("took_damage") >= 0)
    {
        game.SendNotificationError(game.GetShipOwner(args.ship_id), $n0009, $n0010); // Mining failed: You cannot mine if you are being attacked.
    }
    else if (args.cancel_reason.indexOf("move") >= 0)
    {
        game.SendNotificationError(game.GetShipOwner(args.ship_id), $n0011, $n0012); // Mining failed: You must not move during the mining process.
    }
    // else if (args.cancel_reason.indexOf("canceled") >= 0)
    // {
    // game.SendNotificationError(game.GetShipOwner(args.ship_id), $n0013, $n0014); // Mining canceled: You've canceled the mining process.
    // }

    visual.DeviceDeactivateEffect(args.ship_id, args.device_id, "mining_visual_effect");

    game.ShipStopSound(args.ship_id, "mining_process_" + args.slot_id + "_" + args.target_id);
}


Device_salvage_civilian.xml (item xml)

<?xml version="1.0" encoding="utf-8"?>

<root>
   <header>
      <id>device_salvage_civilian</id>
      <title>Civilian salvaging device</title>
      <description>The most basic mining device. It works... but not as well as you would like. The good thing about it is that you don't need any qualifications to use it, unlike other mining devices.</description>
      <enabled>1</enabled>
   </header>

   <gfx>
      <icon>items/devices/device_mining_civilian.png</icon>
   </gfx>

   <data>
      <type>9</type>
      
      <shops>
         <shops_level>1</shops_level>
         <faction_filter></faction_filter>
         <faction_only>0</faction_only>
         <faction_reputation>0</faction_reputation>
         <price>0</price>
      </shops>
      
      <flags>
         <flag>civilian</flag>
      </flags>

      <upgrades_max>0</upgrades_max>
      <upgrades>
         <!-- none -->
      </upgrades>

      <requirements>
         <!-- none -->
      </requirements>

      <effects>
         <!-- none -->
      </effects>

      <item_data>

         <durability>25000</durability> <!-- max durability -->

         <cooldown>1</cooldown> <!-- cooldown in seconds after initiation of usage -->

         <!-- DEVICE ACTIVATION
            determines a way the module can be activated
         -->
         <target>3</target> <!-- 0- N/A, 1- self, 2- area (around self), 3- object, 4- coordinates -->
         <target_parameters>
            <range>10</range> <!-- used for all except "self" and "area" mode. -->
            <area>10</area>
            <!-- determines area of effect on specified coordinates. only for "area", "target", "coordinates" -->
            <target_filter>spaceobject</target_filter>
            <!-- only for "target" mode. For target can be specified: asteroid, ship, crate, jumpgate, base -->
         </target_parameters>

         <!-- DEVICE ACTION
            determines how module effect should be applied
         -->
         <action_type>2</action_type> <!-- 0- N/A, 1- immediate, 2- per frame, 3- on complete -->
         <!-- the following configuration is only applicable for "per frame" and "on complete" modes -->
         <action_parameters>
            <duration>0</duration> <!-- 0 for infinite -->
            <cancel_on_move>1</cancel_on_move> <!-- module is disabled when ship moves -->
            <cancel_on_take_damage>1</cancel_on_take_damage> <!-- module is disabled when ship takes damage -->
            <cancel_on_deactivate>0</cancel_on_deactivate> <!-- module is disabled when user activates it again (in this case deactivates) -->
         </action_parameters>

         <!-- CUSTOM PARAMETERS
            can be any number parameters, also accessible through scripts
         -->
         <custom_parameters>
            <speed>300</speed>
            <amount>75</amount>
            <energy>40</energy>
         </custom_parameters>

         <!-- script definition for this module, must be valid filename -->
         <script>ModuleSalvaging.js</script>

      </item_data>
   </data>
</root>
Title: Re: WIP Salvaging
Post by: Pasadenasman on February 01, 2016, 01:46:40 PM




debris_generic_barrel_01.xml (debris item xml)

<?xml version="1.0" encoding="utf-8"?>

<root>
   <header>
      <id>debris_generic_barrel_01</id>
      <title>(Unused)</title>
      <enabled>1</enabled>
   </header>

   <gfx>
      <model>space_objects/debris_generic_barrel_01.obj</model>
      <textures>
         <diffuse>space_objects/debris_generic_barrel_01/dif_256_red.jpg</diffuse>
         <normal>space_objects/debris_generic_barrel_01/nrm_256.jpg</normal>
         <specular>space_objects/debris_generic_barrel_01/spec_256.jpg</specular>
      </textures>
   </gfx>

   <sfx>
      <!-- none-->
   </sfx>

   <data>
      <scale_range>0.5;0.5</scale_range>
      <rotation_range>-1.0;1.0</rotation_range>

      <flags>
         <flag>mineable</flag>
      </flags>
      
      <physics>
         <mass>20</mass>
         <shapes>
            <shape>
               <type>box</type>
               <offset>0.000;0.000</offset>
               <angle>0</angle>
               <size>1.679;2.987</size>
               <mass>8</mass>
            </shape>
         </shapes>
      </physics>
      
      <type>1</type>
      <difficulty>1000</difficulty> <!-- how long will it take to mine asteroid -->

      <contents>
         <resource>
            <id>ore_glepsite</id>
            <quantity>500;800</quantity>
            <extraction>10</extraction>
         </resource>
         <resource>
            <id>ore_cyactite</id>
            <quantity>200;300</quantity>
            <extraction>5</extraction>
         </resource>
         <resource>
            <id>ore_fraclasite</id>
            <quantity>100;200</quantity>
            <extraction>2</extraction>
         </resource>
      </contents>
      
   </data>
</root>

:o

Not sure that copying all of the files here is the good way to go. Is there any other way to do ?
Title: Re: WIP Salvaging
Post by: ai_enabled on February 01, 2016, 11:26:06 PM
There are two problems on the client side of the game:
1. it doesn't create physical collider (trigger) for debris (unlike asteroids and ships). So when you point over it, the game doesn't recognize it as object at all.
2. there is no localization string for generic "spaceobject" tag/type.

We will fix both issues with the next patch.

Regards!
Title: Re: WIP Salvaging
Post by: Pasadenasman on February 02, 2016, 02:10:21 AM
Really happy to ear that. Thanks in advance. My goal is to create some kind of salvaging/production system that will be in parallel of the mining one. Focusing on the production of some base/station/modules players can interact with and  be settled in a system as a personnal/group assets. Lot of work in perspective but rewarding if it works. I will probably post on the mod forum a description of what i m planning to do. See you !
Title: Re: WIP Salvaging
Post by: ai_enabled on February 02, 2016, 02:12:48 AM
I understand your idea. Thank you for your effort!
I will write here when the patch become available.
Regards!
Title: Re: WIP Salvaging
Post by: jeeplaw on March 13, 2017, 09:45:11 AM
Did this ever get resolved?
Title: Re: WIP Salvaging
Post by: ai_enabled on March 13, 2017, 11:19:39 PM
Sorry I absolutely forgot about this.
It was done in the separate branch of code but not tested thoroughly enough. We will test this and merge for the next patch.
Regards!
Title: Re: WIP Salvaging
Post by: ai_enabled on March 06, 2018, 05:13:26 AM
Better 1 year delay than never :-)
We've implemented this feature in v2.1.0 http://forums.atomictorch.com/index.php?topic=1012.msg6297#new
Title: Re: WIP Salvaging
Post by: Yrol Denjeah on April 02, 2018, 02:58:50 AM
Maybe the delays are a result of the weird thread title
"I" tought it was about salvaging Work In Progress Mods that were given up by other authors.
Title: Re: WIP Salvaging
Post by: Wilmore on July 02, 2018, 10:47:04 PM
@Pasadenasman Did you ever get to implement your mod for this? I think it's a brilliant idea and would love to use the mod!