WIP Salvaging

Started by Pasadenasman, January 31, 2016, 10:23:17 AM

Pasadenasman

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 !

Lurler

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...

Pasadenasman

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.

ai_enabled

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.

ai_enabled

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.

Pasadenasman

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>

Pasadenasman





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 ?

ai_enabled

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!

Pasadenasman

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 !

ai_enabled

I understand your idea. Thank you for your effort!
I will write here when the patch become available.
Regards!

jeeplaw

Did this ever get resolved?

ai_enabled

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!

ai_enabled

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

Yrol Denjeah

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.
No Berries!

Wilmore

@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!
It doesn't matter what we think of God, but what He thinks of us.       - Pascal