Author Topic: BC 1.1 - Secondary shield generators  (Read 5170 times)

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #60 on: September 21, 2011, 11:35:58 AM »
Your suggestion is brilliant.

I have got Foundation 2008 installed with all of the cool and interesting Ftech stuff such as phase cloak etc. I have even had a little fun by adding the phase cloak to the scimitar.

Despite this it never occured to me that, in a different script in a different directory, you could define the name of the shield generators in a list then access that list from a different script in a different directory.

The fact that this method needs Foundation is completely null and void because at the end of the day ShieldGenerators.py needs QBautostart and obviously QBautostart needs foundation - so nothing is lost  :)


I will go to the script and try to implement this method. I aim to have some results by the end of the day but
more than likely I will post back tomorrow.

 :angel Foundation :angel

EDIT:
I have discovered a bug in the ORIGINAL ShieldGenerators.py script. If I repeatedly disable the targetable Secondary or Primary shield generator the ingame strength of every shield eventually and permanently drops to null. By permanent I mean permanent, once the shield strength drops to nothing the shields never repair to full strength, even if both Primary and Secondary generators repair to 100% hit points.
Great men are not peacemakers! Great men are conquerors!

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #61 on: September 22, 2011, 10:24:01 AM »
EDIT: I don't normally double post but I doubt that the forum activity update for the thread is triggered when a user edits an existing post.

Naturally I am not very confident in the code I am putting down, given it's my first real experience with Python in the BC environment. However I was not expecting the errors that flew up:

Code: [Select]
####
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 140, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 52, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
NameError: GetShipType
####
####
Traceback (innermost last):
  File "c:\utopia\current\build\scripts\Bridge\EngineerCharacterHandlers.py", line 563, in AnnounceShields
ZeroDivisionError: float division
####
####
Traceback (innermost last):
  File "c:\utopia\current\build\scripts\Bridge\EngineerCharacterHandlers.py", line 680, in AnnounceSpecificShield
ZeroDivisionError: float division
####
####
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 140, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 52, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
NameError: GetShipType
####

The GetShipType error is the one I least expected. I have been unable to find the function in App.py, Foundation.py or MissionLib.py
I know a function is needed which returns the type (class) of ship the player is using so it is possible to access the specific Foundation plugin for that ship.

Second the zero division error is obvious given it only occurs when a float with a value of 0.0 is used in a division. I have set all the shield values of the real hidden primary generator to 0 but that error still shouldn't be occuring because of the failsafe code:

Code: [Select]
# some scripts in BC will report zero devision error if the value in shieldmax is 0, so work around
                if ShieldMax == 0.0:
                        ShieldMax = 0.1

Ideas as to why there is still a zero division error?

My version of your script is attached if you want to have a look at how I noobishly have messed up your work.
As always, thanks for your time  :) I know you've always got other things on your plate.
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: BC 1.1 - Secondary shield generators
« Reply #62 on: September 22, 2011, 12:24:57 PM »
Try importing LibQBautostart:
Code: [Select]
from Libs.LibQBautostart import *

Can I also see your current Hardpoint?

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #63 on: September 22, 2011, 12:31:41 PM »
About the ship type this is the method you're missing... if not included in QBautostart

Code: [Select]
def GetShipType(pShip):
    if pShip.GetScript():
        return string.split(pShip.GetScript(), '.')[-1]
    return None
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #64 on: September 22, 2011, 05:34:29 PM »
Thanks Sovereign and Defiant, I will include the code.  :bow:

And here is one scimitar hardpoint file. I presume the HP file is for the zero-division error.

EDIT:
I added the function given by USS Sovereign, now I get this.

Code: [Select]
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 144, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 56, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 14, in GetShipType
    return aString.split(pShip.GetScript(), '.')[-1]
NameError: aString
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 144, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 56, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 14, in GetShipType
    return aString.split(pShip.GetScript(), '.')[-1]
NameError: aString

I thought at first it was the variable name being the same as a data type (like that should matter) but obviously that didn't change a thing.
Script attached if you want to have a look.
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: BC 1.1 - Secondary shield generators
« Reply #65 on: September 23, 2011, 02:03:25 AM »
1. Read http://docs.python.org/tutorial/modules.html also you wrote aString instead of string.
But I still prefer importing a library instead of defining this function again.

2. Your Primary Shield Generator has MaxShield of 0. Use at least 1.

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #66 on: September 23, 2011, 05:59:26 AM »
I changed the name of the variable not because I was bored or wanted to convince myself that I wasn't just blindly pasting whatever code you posted. I did it because I got an error with the original variable name you gave. I thought maybe it was to do with it being named string, which is the name of a data type.  :lostit:

So put this in your pipe and smoke it.  :P
Code: [Select]
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 152, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 57, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 14, in GetShipType
    return string.split(pShip.GetScript(), '.')[-1]
NameError: string

And...
Try importing LibQBautostart:
Code: [Select]
from Libs.LibQBautostart import *

I pasted that code in under the other import statements and it spat this at me.
Code: [Select]
Traceback (innermost last):
  File ".\Scripts\Custom\Autoload\LoadEngineeringExtension.py", line 157, in ImportQBautostart
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 4, in ?
ImportError: [b]No module named LibQBautostart[/b]
I performed a full windows search of the BC directory for "LibQBautostart" with 0 results. I also manually looked in both \scripts\Lib and \scripts\custom\qbautostart\Libs

I'm running out of time on this. Damn you BC, damn you! I want my shield generators. I will stop at nothing to get my shield generators! :banghead:
Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: BC 1.1 - Secondary shield generators
« Reply #67 on: September 23, 2011, 06:06:41 AM »
For the "NameError: string": Read my link about importing modules.

LibQBautostart import: Remove it, seems it was never shipped outside of KM :(

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #68 on: September 23, 2011, 08:05:04 AM »
What the...  :lostit:

I have defined the function in ShieldGenerators above where I am calling the function. The interpreter knows the functions exists because it meets it before the call. It is in scope. What else could their be?

A NameError? My suspicion falls on this GetScript(). I don't even fully understand the statement being made in GetShipType().
You receive all the details about the players ship in argument pShip: GetShipType(pShip)
Then there is some form of a check to see if it's worth splitting the string: if pShip.GetScript():

return string.split(pShip.GetScript(), '.')[-1]

You create a string variable and assign it the return value of split().
This is where I get lost though because that function/method has two arguments. (delimeter, numOfLinesToCreate)
Quote
Code: [Select]
str.split(str="", num=string.count(str)).

Why is the second argument, which should be an integer, a full stop?
return string.split(pShip.GetScript(), '.')[-1]

Great men are not peacemakers! Great men are conquerors!

Offline Defiant

  • Posts: 398
  • Cookies: 1105
    • BC: Kobayashi Maru
Re: BC 1.1 - Secondary shield generators
« Reply #69 on: September 23, 2011, 08:19:37 AM »
Just look at the error, it tells you exactly what is missing. (It starts with s)

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #70 on: September 23, 2011, 09:55:52 AM »
I read a small, short introducers PDF tutorial posted on this forum. A few paragraphs in the author warns people that moddifying this game will sap your soul until "your such a geek that your wearing glasses thicker than triple glazing" :funny

Please don't mistake my whining for lack of enthusiasm.

?? NameError ??

 :angel Please enlighten me.  :angel
What coding crime have I commited against Python? Why does it deny me my Primary/Secondary shield generators?
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #71 on: September 23, 2011, 02:10:09 PM »
Quote from: Defiant
1. Read http://docs.python.org/tutorial/modules.html also you wrote aString instead of string.
But I still prefer importing a library instead of defining this function again.

QBautostart outside KM does not have this function included (GetShipType) IIRC.


Quote from: Bat66wat6
Code: [Select]
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 152, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 57, in RedefineShieldGenerators
    sShipType = GetShipType(pShip)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 14, in GetShipType
    return string.split(pShip.GetScript(), '.')[-1]
NameError: string

Defiant is right the error is quite clearly explained to you. The method is clearly referencing another module called string. Add this global declaration.
Code: [Select]
import string


Quote from: Bat66wat6
Code: [Select]
Traceback (innermost last):
  File ".\Scripts\Custom\Autoload\LoadEngineeringExtension.py", line 157, in ImportQBautostart
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 4, in ?
ImportError: [b]No module named LibQBautostart[/b]

You probably don't have that module, older QBautostarts used the following module: LibEngineering.
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #72 on: September 23, 2011, 07:09:46 PM »
Now it's an AttributeError

Code: [Select]
pPrimaryGen = <C ShipSubsystem instance at _6adc93c_p_ShipSubsystem>
pSecondaryGen = <C ShipSubsystem instance at _6ee5c48_p_ShipSubsystem>
activeShieldGen =  <C ShipSubsystem instance at _6adc93c_p_ShipSubsystem>
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 156, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 91, in RedefineShieldGenerators
    ShieldMax = activeShieldGen.GetMaxShields(Shield)
AttributeError: GetMaxShields
pPrimaryGen = <C ShipSubsystem instance at _6f37f68_p_ShipSubsystem>
pSecondaryGen = <C ShipSubsystem instance at _6f380c4_p_ShipSubsystem>
activeShieldGen =  <C ShipSubsystem instance at _6f37f68_p_ShipSubsystem>
Traceback (innermost last):
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 156, in NewShip
    RedefineShieldGenerators(pShip, ShieldGenerators)
  File ".\Scripts\Custom\QBautostart\ShieldGenerators.py", line 91, in RedefineShieldGenerators
    ShieldMax = activeShieldGen.GetMaxShields(Shield)
AttributeError: GetMaxShields

This snake is proving hard to charm.
I threw in some print statements and have found that activeShieldGen does have a value. The variables have the values i expected:

pPrimaryGen = <C ShipSubsystem instance at _6f37f68_p_ShipSubsystem>   :thumbsup:
pSecondaryGen = <C ShipSubsystem instance at _6f380c4_p_ShipSubsystem>   :thumbsup:
activeShieldGen =  <C ShipSubsystem instance at _6f37f68_p_ShipSubsystem>   :thumbsup:


This noob is being pulled out of one hole, taking a step then falling straight into another. :doh:
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #73 on: September 23, 2011, 08:11:13 PM »
I shall try to simplify with a very non related example but it will be probably something you'll understand.

c# example, c# as you know is a strong type language.

Code: [Select]
object o = 1;
int i = (int)o + 1;

Code: [Select]
v = MissionLib.GetSubsystemByName(MissionLib.GetPlayer(), "Shield Generator")
if v:
v = App.ShieldClass_Cast(v)
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #74 on: September 24, 2011, 05:45:50 AM »
I would love to reply and say I completely understand, however that would be a lie. :(

I have not coded in C# but have done some stuff in C and C++, so there is some similarity.

In the first code example you are showing me assignments that utilize the conversion function int() to ensure that non-integers aren't assigned to an integer data type.

The second example is the reason for lack of complete understanding. You get the class instance of property "Shield Generator" then use an IF to check if the instance exists. What you do inside the IF statement I am unsure. App.ShieldClass_Cast(v)

Just clutching at straws here but I also guess that my problem lies in the area of "trying to assign data to the wrong data type"
OR
Perhaps I am attempting to use a method (function) on the wrong data type? In the original (working) script before I messed things up the GetMaxShields() method was used on the variable Generator in the second for loop of RedefineShieldGenerators(), in my broken version I am trying to use the same method on variable activeShieldGen.
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #75 on: September 24, 2011, 11:12:59 AM »
Problem of the day is type casting, maybe this will be more familiar to you:
Code: [Select]
System::Object ^o = 1;
int i = safe_cast<int>(o) + 1;

C# samples
Code: [Select]
    public class BaseClass
    {
        protected int x = 0;
        protected int y = 0;

        public BaseClass(int valX, int valY)
        {
            x = valX;
            y = valY;
        }

        public int Subtract()
        {
            return x - y;
        }
    }

public class InheritedClass : BaseClass
    {
        public InheritedClass(int valX, int valY) : base(valX, valY)
        {

        }

        public int Add()
        {
            return x + y;
        }
    }

    static void Main(string[] args)
    {
// init inherited class as object
object o = new InheritedClass(2, 2);
// casting this as a base class I can't see the add method
((BaseClass)o).Subtract();
// cast it correctly then I can see the add method
((InheritedClass)o).Add();
    }

C++ example (CLR)
Code: [Select]
public ref class BaseClass
{
protected:
int x;
int y;

public:
BaseClass(int valX, int valY)
{
x = valX;
y = valY;
}

int Subtract()
{
return x - y;
}
};

public ref class InheritedClass : BaseClass
{
public:
InheritedClass(int valX, int valY) : BaseClass(valX, valY)
{

}

int Add()
{
return x + y;
}
};

int main(array<System::String ^> ^args)
{
// init inherited class as object
System::Object ^o = gcnew InheritedClass(2, 2);
// casting this as a base class I can't see the add method
(safe_cast<BaseClass^>(o))->Subtract();
// cast it correctly then I can see the add method
(safe_cast<InheritedClass^>(o))->Add();
        return 0;
}

Python example. This is a really bad example since the two examples above cannot be translated to python.
Code: [Select]
# lame example I know
class BaseClass:
    def __init__(self, valX, valY):
            self.x = valX
            self.y = valY
    def Subtract(self):
            return self.x - self.y

class InheritedClass(BaseClass):
    def __init__(self, base):
        BaseClass.__init__(self, base.x, base.y)
    def Add(self):
            return self.x + self.y

base = BaseClass(3, 2)
print base.Subtract()
# print base.Add() # this throws out an error
inherited = InheritedClass(base)
print inherited.Add()

I tried to show you is that you can't preform certain operations on datatypes without proper casting.

Now back to the issue at hand. If you actually studied the return types of MissionLib.GetSubsystemByName you would notice that it returns a Subsystem type and that method GetMaxShields is valid for Shield types.

I actually already gave you an answer and posted it in my python example, I'm not sure how you could have missed it. You cast it to shield type and it should work.

Code: [Select]
App.ShieldClass_Cast(activeShieldGen)
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #76 on: September 24, 2011, 02:43:31 PM »
Sweeping aside the fact that I said I was going through Python documentation and hadn't even heard of "type casting".

Straight onto the script as is. After implementing the change you spelled out the script now functions almost exactly as I wanted.  :bow:  :thumbsup:  :angel

The only remaining problem is that as I suspected when I first started on the script, the values of the each shield aren't being remembered. The default full strength shield values are being applied everytime a shield generator comes online. This is very wrong :nono:

Say for example, I pummel the primary shields and knock the "Primary Shield Generator" offline, the "Secondary Shield Generator" kicks in. Then when the Primary is repaired it comes on at full strength with all shields green again  :(


I am working on a way to store all the shield values of each shield generator in two lists.
pPrimaryGenShieldVals = []
pSecondaryGenShieldVals = []

When a generator is knocked offline all of the values are stored in it's list so they can be applied next time it comes online.

Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #77 on: September 24, 2011, 03:09:26 PM »
Quote
Sweeping aside the fact that I said I was going through Python documentation and hadn't even heard of "type casting".

You claim to have certain C/C++ programming experience, this is one of the basics in programming in C# or C++. You seem to lack the basic understanding of OOP principles.

Quote
I am working on a way to store all the shield values of each shield generator in two lists.
pPrimaryGenShieldVals = []
pSecondaryGenShieldVals = []
When a generator is knocked offline all of the values are stored in it's list so they can be applied next time it comes online.

To store the values I recommend using a dictionary, key should be an ObjectId and value the shield values. This way in the future you will be able to use this script for AI ships also.
Acta, non verba.
aka USS Sovereign

Offline Bat66wat6

  • Posts: 144
  • Cookies: 34
  • Running custom BC 1.1
Re: BC 1.1 - Secondary shield generators
« Reply #78 on: September 24, 2011, 03:41:24 PM »
You claim to have certain C/C++ programming experience, this is one of the basics in programming in C# or C++. You seem to lack the basic understanding of OOP principles.
I wasn't lying, I have done some things in C and C++ but never really covered the whole language. I admit it was wrong to simply say I had experience and not give any indication of just how much experience. I didn't intend to try and make myself seem smarter than I really was (especially since it's self-defeating), sorry  :facepalm: :doh:

Good point with the dictionary, I will use it instead of two seperate lists  :angel
Can you please elaborate on why specifically using a dictionary will allow me to use this script with AI ships? Currently the script works quite well for the AI Scimitar in BC 1.1; that is how I have been testing the script.
Great men are not peacemakers! Great men are conquerors!

Offline Mario

  • Senior Software Developer
  • Administrator
  • Posts: 2187
  • Cookies: 1706
  • Life is life
Re: BC 1.1 - Secondary shield generators
« Reply #79 on: September 24, 2011, 04:05:27 PM »
Code: [Select]
lStats = [90, 90, 90, 90, 90, 90] # you can store only the stats for one ship
dStats = {8090 : [90, 90, 90, 90, 90, 90], 8091 : [90, 90, 90, 90, 90, 90]} # you store the values for multiple ships.

So you go on and simply call
Code: [Select]
dStats[pShip.GetObjID] to get the stored status. I thought it was pretty much self explanatory.
Acta, non verba.
aka USS Sovereign