Page 89 of 118
Re: Scripters cove
Posted: Sat Jan 16, 2016 3:36 pm
by Fritz
Svengali wrote:And as sidenote: Injection (or monkey-patching) is dangerous. In the end every AddOn developer looses the capability to control his own content and runtime behaviours of his/her own scripts. And clashes caused by this kind of thing are nearly impossible to spot.
What's even worse is that some things depend on the order of installation! If Spicy hermits is installed first, I could spot and "reproduce" it, but if not, it would simply override my script. And this would be a relatively simple case; in theory, there could be more than two OXPs involved!
Choose a cleaner approach whenever you can.
That's what I'm trying to do: Change as little as possible and keep the code simple!
Re: Scripters cove
Posted: Sat Jan 16, 2016 6:39 pm
by spara
You could check the hermits with system.entitiesWithScanClass when the player leaves the system and compare the positions with your beacons. Should not be too complicated.
If you don't want to destroy the beacon with the hermit, why do you need to track the death of the hermit? Do you mean to remove the beacon on system exit?
Re: Scripters cove
Posted: Sat Jan 16, 2016 7:18 pm
by Fritz
On system entry, I'll have to put beacons to all hermits stored in the player's database. When I do this, I'll additionally have to remove destroyed hermits. The beacon will remain though, because the "hermit memory" can't know that the hermit has been destroyed (In fiction, it's not a real beacon, because hermits don't have them, and the computer just stores the position, and calculates the orbit etc. in relation to other objects and beacons). I'll store the day of destruction, and after some time, the hermit will be rebuilt, at least if Spicy Hermit's isn't installed.
As I have mentioned in the Spicy Hermits thread, it would be possible to add boulders and other debris, perhaps even "construction ships", during the rebuilding time. But, sadly, it isn't worth to put too much effort into it, because destroyed hermits are very rare during normal playing. I've never destroyed one, and I've only once seen one being destroyed by NPCs.
Re: Scripters cove
Posted: Sat Jan 16, 2016 7:26 pm
by spara
Fritz wrote:I'll store the day of destruction, and after some time, the hermit will be rebuilt, at least if Spicy Hermit's isn't installed.
So you're creating something like [wiki]Station Validator[/wiki]?
Still sounds like something that could be handled in system.playerWillEnterSystem and system.playerWillExitSystem by cataloging hermits using system.entitiesWithScanClass and doing what ever you want to do with them. But maybe it's something different you have in mind
.
Re: Scripters cove
Posted: Sat Jan 16, 2016 7:43 pm
by Fritz
Not so complicated! As I said, destruction will be very rare for rock hermits, so all the effort in creating rebuilding phases, models (e.g. an asteroid with a smaller hole!) etc. would be wasted. I' only want to prevent destroyed hermits magically reappearing, because I'm certain that every player installing the OXP would try it! And because I'll have to store the positions anyhow, it won't be much additional work.
Re: Scripters cove
Posted: Sat Jan 16, 2016 9:20 pm
by spara
Ok, I see. Sorry for being a bit slow sometimes
. You want to create a beacon system _and_ a delayed rebuild.
I made the relocator instead of delayed rebuild for two reasons. First one being compatibility. Core tries to make sure that there is at least one hermit in all systems. It's for the core roles. There are fallbacks in case no hermit is found, but anyway. The second being simplicity in conjunction with the fact, that the player should not really know that the hermit is relocated. The knowledge spoils the illusion. If the player does not know it, then he/she assumes the hermit is gone and he/she has just found a new one.
Fritz wrote:As I said, destruction will be very rare for rock hermits...
Now that depends totally on the player. I'm fairly sure there aremany Ooniverses out there where hermits get destructed all the time.
Good luck with your project
.
Re: Scripters cove
Posted: Sat Jan 16, 2016 11:09 pm
by Fritz
Yes, I want to have both. First the destruction thing should have been phase 2 of my hermit beacon OXP. But I wanted to have the data structure prepared for this from the beginning, so that updating won't be a problem, and that's why I started to think about it already. With using the visual effect beacon (this is working already) the delaying reappearance shouldn't be much additional work, so I'll try to include it into the first version. Of course I'll have to consider moved hermits too - in this case I won't have to recreate the destroyed one. For the player, it will be a new hermit, even if he uses my beacon OXP. I could additionally create a new hermit at the old position, but that's optional, I don't know if I'll do it.
Core tries to make sure that there is at least one hermit in all systems.
Even without OXPs, the player can find himself within a system without hermits, if he destroys them. It is entirely his fault if he chooses to do so! So not recreating them during his next visit to a system won't change anything significantly.
The second being simplicity in conjunction with the fact, that the player should not really know that the hermit is relocated. The knowledge spoils the illusion. If the player does not know it, then he/she assumes the hermit is gone and he/she has just found a new one.
Then I hope that no player will read our discussions!
Re: Scripters cove
Posted: Sun Jan 17, 2016 8:12 am
by spara
Fritz wrote:Then I hope that no player will read our discussions!
Some might read them, but there's probably a big majority out there that does not follow the discussions regularly. And when the oxp is finished and bugs squished, the thread will fall out of sight.
I have one explanation though, if needed. In case hermits get destructed, the core spawns them back to their original places on system entry. An in-game explanation would be that they are built back. My oxp only changes the place they are built.
Re: Scripters cove
Posted: Tue Jan 19, 2016 11:02 pm
by ocz
How is the distance to a star defined, when the fuel scoops kickin to harvest witch fuel? (star size * distance constant? And if yes, what are the values?)
Edit:
Nevermind. I looked into it myself and found:
(Distance: sun <-> player.ship) / sun's radius ≈ 1.155
[color=#000080]system.sun.position.distanceTo(player.ship.position)/system.sun.radius[/color]
≈ 1.155
Around this distance-radius relation the fuel scoops start collecting witchfuel. At least at the suns of the planets Quator, Ra and Relaes it has been this way.
Edit2: To be even more specific: sqrtroot(4/3) [(4/3)^(1/2) ≈ 1.155] * sun's radius is the distance from the sun's core (position) in which the fuel scoops start to harvest witchfuel
Re: Scripters cove
Posted: Thu Feb 04, 2016 3:22 pm
by ocz
Yet again a noobish question, but I really want to make sure, I don't litter timers everywhere.
I'm writing an AI (priorityAI) this time and implemented a timer for repeated condition checking. Of course I could have used the priority list itself with timed reconsiderations, but as the method it repeats is more like a function of the ship (it's a simulated Torusdrive) than a decision the ship takes, I wanted to keep them independent from each other to a certain degree.
Here's what I've got:
Code: Select all
this.name = "Solar Harvester AI";
this.aiStarted = function() {
var ai = new worldScripts["oolite-libPriorityAI"].PriorityAIController(this.ship);
ai.setCommunicationsRole("scavenger");
ai.setParameter("_solarHarvesterReturnHome", false);
[...] // Methods implemented for the AI.
ai._solarHarvesterTorusDrive = function() {
-> var timer = this.ship._solarHarvesterTorusSpeedTimer;
if (this.ship.checkScanner().length !== 0 ||
this.ship.position.distanceTo(system.sun.position) < system.sun.radius * 1.48) {
if (timer.isRunning) this.ship.velocity = this.ship.heading.multiply(this.ship.maxSpeed);
// Drop out of Torus Speed to maxSpeed. Deceleration to set
// speed happens naturally afterwards.
timer.stop();
}
else this.ship.velocity = this.ship.heading.multiply(this.ship.maxSpeed * 32);
// Accelerate to or refresh Torus Speed (32*maxSpeed).
if (!this.ship && timer.isRunning) timer.stop(); //<- Will this do anything?
}
// Engage Torusdrive, check every 0.25 sec if there is something masslocking (excluding
// Planets/Suns, including asteroids/loot) and stop or maintain Torus Speed (refresh velocity).
-> this.ship._solarHarvesterTorusSpeedTimer = new Timer(ai, ai._solarHarvesterTorusDrive ,-1 ,0.25);
[...] // More AI methods.
ai.setPriorities([
[...] //Fighting, Fleeing and doing other stuff
// Go to sun
{
condition: !ai._solarHarvesterConditionReadyToHarvest,
behaviour: function () {
ai._solarHarvesterBehaviourGotoHarvestOrbitAboveSun();
-> this.ship._solarHarvesterTorusSpeedTimer.start();
},
reconsider: 20
}
].concat(ai.templateWitchspaceJumpAnywhere()));
}
Please take notice, how implemented the timer as a property of the ship-object (
this.ship._solarHarvesterTorusSpeedTimer
), to make it itself referable and controllable for the method it repeats. The timer itself is bound to the AI object variable (
ai
in
new Timer(
ai, ai._solarHarvesterTorusDrive ,-1 ,0.25);
)
To my knowledge (wiki) the timer should be removed when the ship is destroyed/docks/jumps out, as for once
ai
should be removed and then the object
this.ship
is also deleted.
But woe me, I found contradicting evidence.
Maybe this in itself was the mistake, but to check the timer I referred to it in the debug console by
this.hTimer = this.harvester._solarHarvesterTorusSpeedTimer
and the object behind
this.hTimer
was alive even after the ship's doom by
this.harvester.temperature = 1.1
. Does the timer stay alive, because something is still referring to it?
In another case I did not refer to the timer and blew the ship up, while in torus transit (running timer). The result:
Exception: TypeError: this.ship is undefined
Active script: Solar Harvester AI 0.1.0
solarHarvesterAI.js, line 50:
var timer = this.ship.AIScript._solarHarvesterTorusSpeedTimer;
Over and over again, every 0.25 seconds.
I don't want to create old timers or even still running once for each ship I launch with this AI.
I also tried:
this.entityDestroyed = function()
{
if (this.ship._solarHarvesterTorusSpeedTimer) {
if (this.ship._solarHarvesterTorusSpeedTimer.isRunning) this.ship._solarHarvesterTorusSpeedTimer.stop();
delete this.ship._solarHarvesterTorusSpeedTimer;
}
}
, but at this point
this.ship
is also not referable anymore.
Is there a method (way of scripting, not a certain function) you use, to make sure timers in priorityAIs die as they should?
Re: Scripters cove
Posted: Thu Feb 04, 2016 3:59 pm
by Svengali
Timers in ship scripts? Use .shipDied
and .shipRemoved
instead to clean up.
And you are right .entityDestroyed
is usally to late.
Re: Scripters cove
Posted: Thu Feb 04, 2016 6:54 pm
by ocz
I rewrote
this.ship._solarHarvesterTorusSpeedTimer
to
this._solarHarvesterTorusSpeedTimer
and therefore also changed
var timer = this.ship._solarHarvesterTorusSpeedTimer;
to
var timer = this.ship.AIScript._solarHarvesterTorusSpeedTimer;
and
this.ship._solarHarvesterTorusSpeedTimer.start();
to
this.ship.AIScript._solarHarvesterTorusSpeedTimer.start();
As the timer now hides behind a property of the custom AIscript, it is also still reachable for the
this.entityDestroyed
method after the ship is no more.
I tested the behavior:
Code: Select all
this.entityDestroyed = function()
{
log(this._solarHarvesterTorusSpeedTimer);
if (this._solarHarvesterTorusSpeedTimer) {
if (this._solarHarvesterTorusSpeedTimer.isRunning) {
this._solarHarvesterTorusSpeedTimer.stop();
log("stopped");
}
delete this._solarHarvesterTorusSpeedTimer;
log(this._solarHarvesterTorusSpeedTimer);
}
}
Resulting in:
------------------------
[color=#0000FF][b]> this.harvester.temperature = 1.1[/b][/color]
[color=#009000]1.1[/color]
[color=#000000][Timer nextTime: 462.058, interval: 0.25, running, function: anonymous]
stopped[/color]
------------------------
So, as the final message of
log(this._solarHarvesterTorusSpeedTimer)
is missing in the log I assume, the timer is history, or at least food for the garbage collector.
@Svengali: For now this works out for me, but I really believe, that timers that manipulate npc-ships and are created for them in first place belong into their objects.
I'll look into
.shipDied
and
.shipRemoved
methods.
Re: Scripters cove
Posted: Tue Feb 09, 2016 10:52 pm
by phkb
I want to create a group of pirates and have them sit (or patrol) a certain region of space, waiting for the player to show up, at which point they should attack immediately. I can create the pirates OK, but it's getting them to sit still or remain in the area that I'm struggling with.
I've tried:
but they still seem to get it into their head to motor off somewhere.
Re: Scripters cove
Posted: Wed Feb 10, 2016 7:31 am
by cim
phkb wrote:I want to create a group of pirates and have them sit (or patrol) a certain region of space, waiting for the player to show up, at which point they should attack immediately. I can create the pirates OK, but it's getting them to sit still or remain in the area that I'm struggling with.
I've tried:
but they still seem to get it into their head to motor off somewhere.
The standard pirate AI will make the group leader take them to a pirate lurking point. If none is set, and they aren't already on a main lane, the leader will pick a position on one of the lanes.
To set your own lurk position, wait until their AI has initialised (a second will do) and then do
Code: Select all
pirate.AIScript.oolite_priorityai.setParameter("oolite_pirateLurk", position);
pirate.AIScript.oolite_priorityai.reconsiderNow();
for each ship in the pirate group, starting with the group leader.
performStop()
will tell them to cut speed to zero - and they will - but on the next AI reconsideration they'll be off again.
...alternatively, give them an AI that's not the standard pirate AI, which you will need to do anyway to force an unconditional attack on the player.
Re: Scripters cove
Posted: Mon Feb 22, 2016 2:56 am
by phkb
Thanks for that previous reply, cim.
Another question, this time for someone who understands (or maybe only kind of understands) vectors. I want to create a entity and then send it on it's way at high speed in a random direction, but I don't want the random direction to be into the sun or planet. If I have a starting position set, how do I set the heading and velocity?