Jump to content


Photo

Objects(in Game Things)


  • Please log in to reply
106 replies to this topic

#1 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 13 November 2005 - 09:07 AM

Ok, now when we have different object for each personnel, what to do with objects (i mean that in games, rifles, bodies and all stuff). Maybe we should also make one object for each object (hih), or just store all objects in one, and only add count varible?

I prefer second method, becouse then we don't have store all that magazines as objects, in other hand even when we take fisrt option there will be max, 10 000 objects (i think) wich is not such big number :)

Beetle
Posted Image

#2 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 13 November 2005 - 12:53 PM

Ok, now when we have different object for each personnel, what to do with objects (i mean that in games, rifles, bodies and all stuff). Maybe we should also make one object for each object (hih), or just store all objects in one, and only add count varible?

I prefer second method, becouse then we don't have store all that magazines as objects, in other hand even when we take fisrt option there will be max, 10 000 objects (i think) wich is not such big number :)

Beetle

<{POST_SNAPBACK}>

I'd suggest that making an instance for each object only makes sense if instances can differ. E.g. A grendade is a grendade. At least as long as it's either in storage in a base or being worn by personel. However, once you move to the battlescape, and someone throws it, it differs from other grenades, as it will have a position and time to detonation on the battlescape.
Likewise, a laser pistol indistinguishable from any other while in an armory, but on the battlescape it has "number of shots remaining".

So if we assume outside of a battlescape all weapons are reloaded (perhaps craft carry reloads?) then outside of the battlescape we can treat objects as just counts in inventory lists, but once we hit the battlescape they need to be instances.

Of course, if in a later version it's possible to customize weapons, then they will probably need to be instances all the time.

Cheers,
David
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#3 mikker

mikker

    Artwork Department

  • Xenocide Artwork Department
  • 2,211 posts

Posted 13 November 2005 - 01:07 PM

well, there IS a diffrence between each object. This is size, manufacture/shipment time, and of course price/resources needed. So they are diffrent in some ways.

Some people say that dreams are a portal to the subconscious. If that is so, I am a very disturbed person.

the truth about scientology

#4 UnFleshed One

UnFleshed One

    Programming Department

  • Xenocide Inactive
  • 304 posts

Posted 13 November 2005 - 05:32 PM

I think we should keep instanses all the time. Stacking similar objects into one and adding a number will save us a couple hundreds kilobytes of memory at max (which is very good if you write a program for DOS :)), but it has a good potential for unsolvable problems.

Edit:
That is, if something will ever be represented by its own instanse, it should be represented from the very begining and to the end of its lifetime. Things like grenades, jets and magazines are like that.
But things you can measure in liters, kilos or meters should be represented by one object for all substance in one location. Like one object will hold 300 units of elerium on the base and another will hold 50 units of elerium on a plane returning from a mission.

Edited by UnFleshed One, 13 November 2005 - 05:58 PM.

Darkness is under the candle.

#5 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 13 November 2005 - 07:50 PM

Yes some stuff like Xenium that will require 2 to 10 K instances could be "Joinable" into a single instance. Others like Weapons could be single instances (that would allow us to do weapon customization in the future).

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#6 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 15 November 2005 - 04:16 PM

Ok. I think that every object instance can hold count varible. For most of object it will be just 1, but it gives us two good things :)

First, elerium, alien alloys and such will be usning this number, so we will have only one object for all elerium in base.

Second, for magzines it will store number of bullets in given magazine. So after mission we could recalculate number of magzines and even store one not fully loaded magazine.

What do You think?

edit: of corse we can add some more sophisticated models using that idea.

edit2: I think that Object class should also have pointer (or just instance) of ObjectType class, which would be part of static data.

Edited by Beetle, 15 November 2005 - 04:52 PM.

Posted Image

#7 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 15 November 2005 - 09:44 PM

Some may not be joinable, so I would add at least the capability to disable it per instance.

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#8 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 22 November 2005 - 09:41 AM

So maybe something similiar to this:
???

Equpiment object mean that it's cariable by soldier (rifle, magazine, alien corpse)

Attached Files


Posted Image

#9 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 24 November 2005 - 04:58 PM

Can you transfer the design into the real definition in Pseudo C# for clarity (as we have been doing)? ... As it is it look good, but we need to be sure and that happens when you code it ;)

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#10 ATeX

ATeX

    Sound Department

  • Xenocide Inactive
  • 545 posts

Posted 24 November 2005 - 05:49 PM

Sorry for being offtopic: but is this classbased OOP? I think it looks great and it adds a lot of flexibility programmingwise. Reminds me of the old days with Java and C++ a few years ago. Keep up the good work!


cheers,

Thomas

#11 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 25 November 2005 - 09:53 AM

Yes i think we can call this OOP :)

going back to draw, all relations are inharitance, so in psaudo code it will be something like:
class ObjectType
{
  String typeName {get; set; }

  bool isJoinable() 
}

class JoinableObjectType : ObjectType
{
}

class EquipmentType : ObjectType
{
}

class MagazineType : EquipmentType
{
}

......

Beetle
Posted Image

#12 ATeX

ATeX

    Sound Department

  • Xenocide Inactive
  • 545 posts

Posted 26 November 2005 - 04:24 AM

yep, the tree structure brings back a lot of good ol' memories. Especially Java. btw, can't wait to see the alien AI :) has always been a big mystery for me.


cya later,

Thomas

#13 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 29 November 2005 - 11:36 AM

Ok, little upgraded version. Once again all arrows are inharitance :)

Attached Files


Edited by Beetle, 29 November 2005 - 11:37 AM.

Posted Image

#14 reist

reist

    Programming Department

  • Xenocide Programming Department
  • 130 posts

Posted 29 November 2005 - 05:46 PM

Ok, little upgraded version. Once again all arrows are inharitance :)

<{POST_SNAPBACK}>

I'm still trying to get all the code, so I'm not sure if anything I write here is usefull, but here goes :)

Aren't inheritance arrows supposed to be backwards, or am I just way to used to uml-like diagrams? :P

I just can't imaging how this design works. Are there any ideas(or even better - ideas written as code examples) of how this is going to be used?
Why use dual inheritance hirarchy? It looks to me like an object class w/ count inside it is all that's needed.
And one last - are there any object that don't have x/y sizes? 'cause it looks as if every concrete objectType has them.

#15 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 29 November 2005 - 06:13 PM

I'm still trying to get all the code, so I'm not sure if anything I write here is usefull, but here goes :)

Aren't inheritance arrows supposed to be backwards, or am I just way to used to uml-like diagrams?  :P


Yeay i think You are right, only i'm noty used to UML :) (yet)

I just can't imaging how this design works. Are there any ideas(or even better - ideas written as code examples) of how this is going to be used?
Why use dual inheritance hirarchy? It looks to me like an object class w/ count inside it is all that's needed.

"Types" Obejct are part of static game data, other are part of gamestate.

And one last - are there any object that don't have x/y sizes? 'cause it looks as if every concrete objectType has them.


For example elerium, allien alloys.
Posted Image

#16 reist

reist

    Programming Department

  • Xenocide Programming Department
  • 130 posts

Posted 29 November 2005 - 07:22 PM

Alright, but how will the whole thing be used?
If you can write some kind of pseudo-code that uses the design to show how things would be done when everything's in place, that would be really nice.

A couple of those "things" that will be needed in the game and can affect the design (not sure if this is a complete list or not):
- Pulling specific equipment from stores. Such as:
- - soldier-usable equipment to equip the soldiers.
- - plane-wepons to arm a plane + bullets/missiles/etc to load into the weapons.

- Loading a magazine/missile pack/etc into a weapon
- - Checking that these are a magazine and a weapon.
- - Checking that they're of the same type.
- - Doing the loading: magazine object inside weapon? (where's the number of rounds/bullets kept?)

- Collecting joinable objects (elerium, fuel, dead aliens...)
- - Checking that the object is joinable and has the same type as an object already in repository (plane, base stores). Yeah, I saw the design, I'm only noting it for the sake of completeness.
- - Doing the joining.

- Collecting everything from the battlescape
-- Collecting non-joinables
-- Collecting joinables (will need the previous example to work first)

Some of the items on this list are really no-brainers, but others I just can't see in this design.

#17 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 29 November 2005 - 09:50 PM

Mhh can you provide some pseudocode of how you would use that ;) that viewpoint always helps to design. If I have some time I will see if I can add some more insight into there. Do you remember there is already a design document for that already? It may bring some fresh ideas to the design.

Az master of the old threads, can you look that up?

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#18 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 30 November 2005 - 07:22 AM

Hi

I know it will be little complicated, but it wasn't my idea to make different object for 'almost' every in game object (maybe form know on i will call in game objects as items), but after all we agreed for this solution.

Some more thougts:
Soldier desired equipment can be made as a list of sharedPtr to EquipmentType objects.
Base stores all items as a linked lists, when we want to arm solider we itarate thru that and search what we need.

Number of bullets is keept in count in Magazine class. Arming weapon, hmm we have to add something to that chart to explicty say which magazines could be added to which weapons.

Joing joinable objects, we can said for simplicity that we will do only when new object arrive to base (from plane, workshop or from buying), then object after object if it is non-joinable add it to the list (with exception of magazine) (push_back, etc) and if it is joinable first shearch if there maybe is such an object in base stores.

Edited by Beetle, 30 November 2005 - 07:24 AM.

Posted Image

#19 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 01 December 2005 - 03:47 AM

Hi

I know it will be little complicated, but it wasn't my idea to make different object for 'almost' every in game object (maybe form know on i will call in game objects as items), but after all we agreed for this solution.

Some more thougts:
Soldier desired equipment can be made as a list of sharedPtr to EquipmentType objects.
Base stores all items as a linked lists, when we want to arm solider we itarate thru that and search what we need.

Number of bullets is keept in count in Magazine class. Arming weapon, hmm we have to add something to that chart to explicty say which magazines could be added to which weapons.

Joing joinable objects, we can said for simplicity that we will do only when new object arrive to base (from plane, workshop or from buying), then object after object if it is non-joinable add it to the list (with exception of magazine) (push_back, etc) and if it is joinable first shearch if there maybe is such an object in base stores.

<{POST_SNAPBACK}>

For what they’re worth, here’s my thoughts on items, please bear with me as my ideas are still somewhat stattershot. And my appologies to Reist, as I think I’ve stolen most of his ideas.

Firstly, considering items by themselves is only part of the story. There’s also the containers that hold items. At minimum there are:
1. Bases
2. People
3. Craft
4. Battlescape
5. items themselves
6. “shipping” container (representing items in transit)

Each of these containers has different behaviours when items are inserted or removed from them.
E.g. Inserting items into a base, the base will probably want to try joining items.
Inserting items into people, we need to keep the items distinct. E.g. We can’t join up magazines. Also, we need to consider not just an item’s mass, but also it’s size and where it can be put. E.g. is it in the hands? In the belt, the backpack, etc.

I’ve included items, because if you think about it, a weapon that takes a magazine is a container for the magazine.

An additional point, in Beetle’s item class diagram he’s been focusing on Joinable and non-joinable. But that’s not the only way of classifying objects, there’s also the distinction between “carryable” items (e.g. Weapons) and non-carryable (e.g. Xenium, Fuel, Craft missiles.)

I think there are 3 classes of items that derive from a base item class.
“Bulk” items: Xenium, Fuel, and other items that can’t go in the battlescape or people containers.
“equipment” items: Weapons, armour, equipment, etc. (Note that the equipment type may well have other specializations – but from the “item” view they’re the same class)
“magazines” – Which derive from carryable.

How an item behaves is a function of the item’s class, and the type of container it’s being moved into.

The reason for magazines being a separate class from carryable items is because a magazine has different “joining” semantics from an equipement item. For carryable and bulk items, if it’s joinable then the container can handle the join operation. Container just makes sure it has 1 instance of the item, then bumps up the item count. However, to join magazines, it needs assistance from the magazine itself. As the magazine is really a “conceptual” object, representing a collection of bullets.

Actually, this suggests an alternate implementation, where we map a magazine as an item container that holds ammunition. Then the process of inserting a magazine into a container depends on the container. If a person, the magazine remains as a discrete object, with it’s ammo. If inserting into a base, then container is emptied, and we wind up with a magazine and a number of ammo objects that are then “joined” into the base’s store. We get similar behaviour if we insert a loaded weapon into a base or a person. Where things become a bit more complicated is when we remove a magazine from a base container. We need to fill it, which only the magazine would know how to do.
Hmm. Division of labour:
Storing an item in a container is the container’s responsibility.
Reconstituting an item is the item’s responsibility. E.g. Extract rifle from base, rifle knows it wants a magazine, so tries to fetch one from the base. (Base will always be able to supply an empty magazine. Magazine then tries to fill itself from ammo in base.)

Final thought: What can we do with items (as generic items)?
Buy them (only base can do this)
Sell them (only base can do this)
Make them (only base can do this)
Move between bases.
Recover them from battlescape.
Equip people/craft.
Expend them.

Where I’m going here is that items don’t exist separate from their containers, and all the things we do with items correspond to putting items into or removing them from containers.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#20 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 01 December 2005 - 04:32 AM

Hi

I know it will be little complicated, but it wasn't my idea to make different object for 'almost' every in game object (maybe form know on i will call in game objects as items), but after all we agreed for this solution.

Some more thougts:
Soldier desired equipment can be made as a list of sharedPtr to EquipmentType objects.
Base stores all items as a linked lists, when we want to arm solider we itarate thru that and search what we need.

Number of bullets is keept in count in Magazine class. Arming weapon, hmm we have to add something to that chart to explicty say which magazines could be added to which weapons.

Joing joinable objects, we can said for simplicity that we will do only when new object arrive to base (from plane, workshop or from buying), then object after object if it is non-joinable add it to the list (with exception of magazine) (push_back, etc) and if it is joinable first shearch if there maybe is such an object in base stores.

<{POST_SNAPBACK}>


For what they’re worth, here’s my thoughts on items, please bear with me as my ideas are still somewhat stattershot. And my appologies to Reist, as I think I’ve stolen most of his ideas.

Firstly, considering items by themselves is only part of the story. There’s also the containers that hold items. At minimum there are:
1. Bases
2. People
3. Craft
4. Battlescape
5. items themselves
6. “shipping” container (representing items in transit)

Each of these containers has different behaviours when items are inserted or removed from them.
E.g. Inserting items into a base, the base will probably want to try joining items.
Inserting items into people, we need to keep the items distinct. E.g. We can’t join up magazines. Also, we need to consider not just an item’s mass, but also it’s size and where it can be put. E.g. is it in the hands? In the belt, the backpack, etc.

I’ve included items, because if you think about it, a weapon that takes a magazine is a container for the magazine.

An additional point, in Beetle’s item class diagram he’s been focusing on Joinable and non-joinable. But that’s not the only way of classifying objects, there’s also the distinction between “carryable” items (e.g. Weapons) and non-carryable (e.g. Xenium, Fuel, Craft missiles.)

I think there are 3 classes of items that derive from a base item class.
“Bulk” items: Xenium, Fuel, and other items that can’t go in the battlescape or people containers.
“equipment” items: Weapons, armour, equipment, etc. (Note that the equipment type may well have other specializations – but from the “item” view they’re the same class)
“magazines” – Which derive from carryable.

How an item behaves is a function of the item’s class, and the type of container it’s being moved into.

The reason for magazines being a separate class from carryable items is because a magazine has different “joining” semantics from an equipement item. For carryable and bulk items, if it’s joinable then the container can handle the join operation. Container just makes sure it has 1 instance of the item, then bumps up the item count. However, to join magazines, it needs assistance from the magazine itself. As the magazine is really a “conceptual” object, representing a collection of bullets.

Actually, this suggests an alternate implementation, where we map a magazine as an item container that holds ammunition. Then the process of inserting a magazine into a container depends on the container. If a person, the magazine remains as a discrete object, with it’s ammo. If inserting into a base, then container is emptied, and we wind up with a magazine and a number of ammo objects that are then “joined” into the base’s store. We get similar behaviour if we insert a loaded weapon into a base or a person. Where things become a bit more complicated is when we remove a magazine from a base container. We need to fill it, which only the magazine would know how to do.
Hmm. Division of labour:
Storing an item in a container is the container’s responsibility.
Reconstituting an item is the item’s responsibility. E.g. Extract rifle from base, rifle knows it wants a magazine, so tries to fetch one from the base. (Base will always be able to supply an empty magazine. Magazine then tries to fill itself from ammo in base.)

Final thought: What can we do with items (as generic items)?
Buy them (only base can do this)
Sell them (only base can do this)
Make them (only base can do this)
Move between bases.
Recover them from battlescape.
Equip people/craft.
Expend them.

Where I’m going here is that items don’t exist separate from their containers, and all the things we do with items correspond to putting items into or removing them from containers.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#21 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 01 December 2005 - 06:30 AM

When i splitted items into joinable and nonjoinable i was thinking that all carryable (by soldiers) items are not joinable. In other hand all other items are joinable (in fact there isn't many other items :P ) Currently craft weapons are joinable, but maybe we should also make them non-joinable ?

I think there are 3 classes of items that derive from a base item class.
“Bulk” items: Xenium, Fuel, and other items that can’t go in the battlescape or people containers.
“equipment” items: Weapons, armour, equipment, etc. (Note that the equipment type may well have other specializations – but from the “item” view they’re the same class)
“magazines” – Which derive from carryable.

Bulk -> JoinableObject
Equpiment -> Equpiment
Mazaines -> Magazine
* -> LoadOutWeaponType (i'm not sure of this position)
:) :)

I like your idea w magazines :), maybe base should contain only one big magazine for each type of bullets?

Buying and selling, i think we will add separate interface for that, becouse not only items but also craft and crew are buyable/hireable.

About shipping container, maybe we will make invisible craft for that? :P
Posted Image

#22 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 01 December 2005 - 12:51 PM

When i splitted items into joinable and nonjoinable i was thinking that all carryable (by soldiers) items are not joinable. In other hand all other items are joinable (in fact there isn't many other items :P ) Currently craft weapons are joinable, but maybe we should also make them non-joinable ?

Actually, what I was thinking was that all items are potentially joinable, it's the container that makes the decision if items are joined on insertion or not. e.g A Base container will always try to join items on insertion. A person container will never try to join items.
This would be supported by an item having two interfaces for adding to a container, one that's invoked to allow the item to be added to the container in a join mode, the other in non-join mode. Item class should also have a property IsJoinable() which can be invoked by the container to determine if joining is in fact possible. E.g. A rifle with custom add ons may not be joinable, but if dissassembled into component pieces (rifle, scope, magazine, etc.) it can. So an item may have an interface DissassembleForStorage()

Incidentally, I don't like the term "joinable", is "stackable" better?


I think there are 3 classes of items that derive from a base item class.
“Bulk” items: Xenium, Fuel, and other items that can’t go in the battlescape or people containers.
“equipment” items: Weapons, armour, equipment, etc. (Note that the equipment type may well have other specializations – but from the “item” view they’re the same class)
“magazines” – Which derive from carryable.

Bulk -> JoinableObject
Equpiment -> Equpiment
Mazaines -> Magazine
* -> LoadOutWeaponType (i'm not sure of this position)
:) :)

I'm not sure what the "LoadOutWeaponType" is. I'm thinking it represents an "inventory list" so that when a person/craft returns to base the person is restocked to match the list.

Additionally, if we go with items being able to be containers, then I don't think we need a seperate magazine type. Magazines are just another equipment item, which can contain ammunition.

I like your idea w magazines :), maybe base should contain only one big magazine for each type of bullets?

Not necessary, if we assume a base container will join items as default behaviour, then it will automatically consolidate all magazines of a given type into a single entry.

Buying and selling, i think we will add separate interface for that, becouse not only items but also craft and crew are buyable/hireable.

Don't confuse user interface with underlying objects.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#23 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 02 December 2005 - 05:02 AM

I doesn't mean user interface, but a class interface :)

LoadOutWeaponType is craft weapon.

We don't suppose to join equipment at base, since we want to have diffrent object for each item.
Posted Image

#24 reist

reist

    Programming Department

  • Xenocide Programming Department
  • 130 posts

Posted 02 December 2005 - 07:17 AM

For what they’re worth, here’s my thoughts on items, please bear with me as my ideas are still somewhat stattershot.  And my appologies to Reist, as I think I’ve stolen most of his ideas.

<{POST_SNAPBACK}>

Oh, don't worry about that :)
I didn't really have any concrete ideas yet (not much free time till next friday), just thoughts of what should be possible.

There's some good discussion going on now =b
I'd really recommend to write some code before the classes/objects exist to just see how you'd want to work with the class hirarchy(not necessarilly the any hirarchy defined here) in all the (or at least the most common) different situations. That'd help to see what classes and interfaces should exist and what they should do.
That's really why I asked if there's some code/pseudocode for all of this.

Edited by reist, 02 December 2005 - 07:20 AM.


#25 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 02 December 2005 - 05:11 PM

OK, trying to make my prior submission a bit more concrete.

Ignoring the base class, there are at least two classes of item.
class ItemCraft: items used by craft: Xenium, Sidewinder missiles etc.
class ItemTroop: items carried by troops.

There is the possibility of a third type, ItemMagazine, which is derived from ItemTroop. But I’m not yet convinced that it is needed. I think it can be replaced with ItemTroop’s that have an item container. (Although this is possibly a 3rd class of item.)

There’s a couple of other items that I’m not quite sure where they go. Specifically, Dead bodies, stunned bodies, and captured aliens. I’m temped to class them as troop items (as troops can pick them up, and the exist in the battlescape) the issue is you would never equip troops with these items when departing a base on a mission. (Possibly indicated by a member of the ItemTroop class.)

There are the following container classes.
ContainerXBase.
Represents items held in a base. Has rules:
1. Items are stored internally in “joined” form
2. Can store both ItemCraft and ItemTroop items

ContainerTroop
Represents items carried by a trooper. Has rules:
1. Items are stored in “unjoined” form.
2. Can only store ItemTroop items.
3. Needs to track location of items in the troops “backpack”.

ContainerCraft
Represents items carried by a craft for craft’s use. Has rules:
1. Items are stored in (probably) joined form.
2. Can only store ItemCraft items

ContainerBattlescape
Represents items on a battlescape. Has rules:
1. Items are stored in “unjoined” form
2. Can only store ItemTroop items?

ContainerItem
Represents the items that are inside an item. E.g. A magazine holding ammo. Has rules:
1. Items are stored in joined form.
2. Can only hold a very specific subset of ItemTroop items.

ContainerShipping
Represents items that are in transit. E.g. Salvage from a mission, transfer between bases.
1. Items are stored in joined form.
2. Can store both ItemCraft and ItemTroop items.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#26 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 03 December 2005 - 10:12 AM

That is a better aproximation to the design of the Items System. Lets see some class definition pseudocode.

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#27 reist

reist

    Programming Department

  • Xenocide Programming Department
  • 130 posts

Posted 03 December 2005 - 10:51 AM

Some ideas about dteviot's post. I'm going to rearrange it a bit...
(this is what I got after thinking for a little over an hour, so all of this is half thought through :P )

Ignoring the base class, there are at least two classes of item.
class ItemCraft: items used by craft: Xenium, Sidewinder missiles etc.
class ItemTroop: items carried by troops.

<{POST_SNAPBACK}>

If I understand it correctly, these two types have different behaviour (implementation/function calls), like removing exact number of items out of the total of ItemCraft, while not possible for ItemTroop.

There are the following container classes.
ContainerXBase. 
Represents items held in a base. Has rules:
1. Items are stored internally in “joined” form
2. Can store both ItemCraft and ItemTroop items

I think that'd mean that ItemTroop items have these functions:
1. join(ItemTroop): destroys the item and adds joinedItem.count
2. ItemTroop remove(): clones the item and decreases it's count by newItem.count
A general implementation could make new items have a count of 1. Then magazines could have they're own implementation with a count of X, by making a new class for them or by getting the needed count according to their name from somewhere else (xml files, static type classes?)

There’s a couple of other items that I’m not quite sure where they go.  Specifically, Dead bodies, stunned bodies, and captured aliens.  I’m temped to class them as troop items (as troops can pick them up, and the exist in the battlescape) the issue is you would never equip troops with these items when departing a base on a mission.  (Possibly indicated by a member of the ItemTroop class.)

A possibility(didn't think it all the way through yet) is to make stunned/dead aliens create an ItemTroop in battlescape with a pointer to it inside the alien's class.
When leaving the mission, we'd have two possibilities:
1. Mission complete: All ItemTroop with alien names (or some other identifier) will be removed, and all aliens will be taken as some other item type.
2. Run away: Do the same, but with a check for same pointer.
3. Alien wakes up: Run a loop through the soldiers (or have a map/list/whatever inside the battlescape) to find out if one of them has carries that alien. If so, move the woken alien to the troop's position and remove the ItemTroop from the troop. If not, just make the alien stand up and remove the ItemTroop from the battlescape.

Edited by reist, 03 December 2005 - 10:56 AM.


#28 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 03 December 2005 - 04:28 PM

That is a better aproximation to the design of the Items System. Lets see some class definition pseudocode.

Greetings
Red Knight

<{POST_SNAPBACK}>

Try this.

//==============================================================
class Item
{
public:
    string             itemName() const;
    int  virtual       getMass() const;
    bool virtual       isJoinable() const;
    bool virtual       isItemTroop() const { return false; };
    bool virtual       isItemCraft() const { return false; };
    bool virtual       hasContainer() const;
    Container& virtual getContainer();
    Item* virtual      clone(Container& fillFrom) const
    {
        new newItem();
        if (newItem->hasContainer())
        {
            newItem->fill(fillFrom);
        }
        return newItem;
    };
private:
    string itemName;
};

//==============================================================
class ItemCraft : public Item
{
public:
    bool virtual isItemCraft() const { return true; };
};

//==============================================================
class ItemTroop : public Item
{
public:
    bool virtual isItemTroop() const { return true; };
    int getXSize();
    int getYSize();
};



class Container
{
public:
    bool virtual  hasRoomFor(Item const& item);
    bool virtual  isLegalToHold(Item const& item);
    bool virtual  canInsert(Item const& item) {return isLegalToHold(item) && hasRoomFor(item);};

    void virtual  push_back(Item* item) = 0; 
    Item* virtual pop(string const& itemName)
    {
        if (1 == count(itemName))
        {
            return multipmap.pop(itemName);
        }
        else
        {
            --count;
            return multimap.find(itemName).clone(this);
        }
    };

    // these two need some care in implementation because of possible multiple instances
    Item* virtual find(string const& itemName);
    int   virtual count(string const& itemName); 

    // not sure about this one
    // possibly should return some sort of iterator.
    vector<string>  listItems();

    // Called to get this container to fill itself from another container
    // e.g. Magazine loading itself from base stores.
    // noop except for ContainerItem class
    void virtual fill(Container& takeFrom) {}
    {
        for (each subitem wanted in this container)
        {
            if (subitem in takeFrom)
            {
                this->push_back(takeFrom.pop(subitem));
            }
        }
    };

protected:
    void virtual addDistinct(Item* item) { multimap.push_back(item, 1); }
    void virtual addJoined(Item* item)
    {
        for each (subitem in item.listItems())
        {
            this->push_back(item.pop(subitem));
        }
        multimap.push_back(item, ++count);
    };

private:
    // internal storage is map that links itemName to an instance and a count.
    // caution, we   how do we handle unique instances with same name?
    multimap<string itemName, pair<int count, Item* item>> multimap;
};

//==============================================================
class ContainerXBase : public Container
{
    bool virtual isLegalToHold(Item const& item) { return true };
    void virtual push_back(Item* item)
    {
        if (item.isJoinable())
        {
            addJoined(item);
        }
        else
        {
            addDistinct(item);
        }
    }; 
};

//==============================================================
class ContainerCraft : public Container
{
    bool virtual isLegalToHold(Item const& item) { return item.isItemCraft(); };
    void virtual push_back(Item* item) {addJoined(item);};
};

//==============================================================
class ContainerTroop : public Container
{
    bool virtual isLegalToHold(Item const& item) { return item.isItemTroop(); };
    void virtual push_back(Item* item) {addDistinct(item);};
};

//==============================================================
class ContainerItem : public Container
{
    void virtual push_back(Item* item) {/* implementation */};
    void virtual fill(Container& takeFrom);
    bool virtual hasRoomFor(Item const& item) {/* implementation */};
    bool virtual isLegalToHold(Item const& item) {/* implementation */};
};

//==============================================================
class ContainerBattlescape : public Container
{
    bool virtual isLegalToHold(Item const& item) { return item.isItemTroop(); };
    void virtual push_back(Item* item) {addDistinct(item);};
};

//==============================================================
class ContainerShipping : public ContainerXBase
{
};

Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#29 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 04 December 2005 - 04:43 AM

I like it, defently more then my :)
One not important note :P maybe change from isItemTroop() to isTroopItem() (i don't only mean this method of corse) is more ituitive for me.

I really like it :)

I think that with this classes we would propably could go with only one class for static data representation :)

:beer:
Posted Image

#30 reist

reist

    Programming Department

  • Xenocide Programming Department
  • 130 posts

Posted 04 December 2005 - 06:30 AM

Yeah, this looks really good :P

#31 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 04 December 2005 - 12:33 PM

Its near shippable mode, just a couple of ideas you can toy with. Instead of having two methods like isTroopItem and isCraftItem you can use a double dispatching pattern to handle that with the added flexibility if that we find out that we need more items or more specific types they can be handled easily and wont require modify much source.

For the rest, excelent design.

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#32 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 04 December 2005 - 12:40 PM

I think that with this classes we would propably could go with only one class for static data representation

<{POST_SNAPBACK}>

I believe static data representation (and factory) can be handled by a static member in the Item class, and a virtual function or two in each derived class. A seperate class should not be necessary.

Assuming Rincewind & RK are happy with this design, someone's going to have to implement it. And by someone, I probably mean me. Which isn't likely to happen until next weekend.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#33 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 04 December 2005 - 01:42 PM

Hmm static member? I can't get it. We need a separate object (or part of the object) for every type of item. How can we do it with static member?

About implenetation since You already write so much we will wait even more then to next weekend :)
Posted Image

#34 UnFleshed One

UnFleshed One

    Programming Department

  • Xenocide Inactive
  • 304 posts

Posted 04 December 2005 - 04:20 PM

How will storage facility know how many things it can store? Is only mass that matters or should every item have a storageSize in some units (volume f.e.).

I mean, what if we decide one day to store a couple of micro black holes?
Darkness is under the candle.

#35 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 04 December 2005 - 05:09 PM

There should be something like mass and it's even already implemented in our item.xsd/.xml :)
Posted Image

#36 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 05 December 2005 - 03:50 AM

Hmm static member? I can't get it. We need a separate object (or part of the object) for every type of item. How can we do it with static member?

About implenetation since You already write so much we will wait even more then to next weekend :)

<{POST_SNAPBACK}>

Like this:
//==============================================================
class Item
{
public:
    static Item* classFactory(string const& itemName)
    {
        if (replicator.isEmpty())
        {
            initReplicator();
        }

        Item* item  = replicator.find(itemName);
        return item.clone();
    }

protected:
    virtual Item* clone() = 0;
    virtual void  loadFromXml(xmlElement)
    {
        // load Item static variables from xml. e.g.
        mass = extractIntFromXml(xmlElement)
    }

    void copyStaticData(Item const& dataSource);
    {
        mass = dataSource.mass;
    }

private:
    int mass;             // size of item in base store
    
    static void initReplicator()
    {
        replicator.push_back("Plasma Rifle",  new ItemTroopGun());
        replicator.push_back("MedKit",        new ItemTroop());
        loadStaticDataFromXml(); 
    }

    static void loadStaticDataFromXml(char const* itemName, Item* item)
    {
        for (each item in XML file)
        {
            Item* item = replicator.find(XmlElement.itemName);
            item->loadFromXml(xmlElement);
        }
    }

    static map<string const itemName, Item* masterCopy> replicator;
};

//==============================================================
class ItemTroop : public Item
{
public:
    virtual ItemTroop* clone() 
    {
        ItemTroop* itemTroop = new ItemTroop();
        itemTroop->copyStaticData(*this)
        return itemTroop;
    };

protected:
    virtual void  loadFromXml(xmlElement)
    {
        Item::loadFromXml(xmlElement);
        sizeX = extractIntFromXml(xmlElement);
        sizeY = extractIntFromXml(xmlElement);
    }

    void  copyStaticData(ItemTroop& dataSource);
    {
        Item::copyStaticData(dataSource);
        sizeX = dataSource.sizeX;
        sizeY = dataSource.sizeY;
    }

private:
    int sizeX;
    int sizeY;
};

//==============================================================
class ItemTroopGun : public ItemTroop
{
public:
    virtual ItemTroopGun* clone() 
    {
        ItemTroopGun* itemTroopGun = new ItemTroopGun();
        itemTroopGun->copyStaticData(*this)
        return itemTroopGun;
    };

protected:
    virtual void  loadFromXml(xmlElement);
    {
        ItemTroop::loadFromXml(xmlElement);
        range  = extractIntFromXml(xmlElement);
        damage = extractIntFromXml(xmlElement);
    }

    void  copyStaticData(ItemTroopGun& dataSource);
    {
        ItemTroop::copyStaticData(dataSource);
        range  = dataSource.range;
        damage = dataSource.damage;
    }

private:
    int range;
    int damage;
};

Incidentally, I was looking at item.xml and noticed this line
<item name="ITEM_AUTO_CANNON" clips="ITEM_A_C_HE_CLIP ITEM_A_C_AP_CLIP ITEM_A_C_IN_CLIP" xsi:type="rangedWeaponItemType">

Might I suggest this needs fixing, and any objections if I do so?
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#37 Guest_Azrael_*

Guest_Azrael_*
  • Guests

Posted 05 December 2005 - 04:25 AM

Incidentally, I was looking at item.xml and noticed this line
<item name="ITEM_AUTO_CANNON" clips="ITEM_A_C_HE_CLIP ITEM_A_C_AP_CLIP ITEM_A_C_IN_CLIP" xsi:type="rangedWeaponItemType">

Might I suggest this needs fixing, and any objections if I do so?

<{POST_SNAPBACK}>

Go ahead, I'm fixing the rest of the schemas (updating old names), if you want me to take a look, give me a shout ;)

#38 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 05 December 2005 - 10:35 AM

Hmm so you are supposing to not make static data classes at all and hold all static (i mean common for all same types) data in normal varible in each object.

.... When i think a little of it, i also like it ;) it's even more adjustable :)
Posted Image

#39 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 05 December 2005 - 12:35 PM

Go ahead, I'm fixing the rest of the schemas (updating old names), if you want me to take a look, give me a shout ;)

<{POST_SNAPBACK}>

I see you've updated facility.xml to change FAC_ALIEN_CONTAINMENT_FACILITY to FAC_XENOMORPH_HOLDING_FACILITY.
graphics.xml needs a similar change. (And while you're there you might like to add an XNET reference to the Facility as well, so it also shows up in the model view in XNET.

And on the programming side, someone needs to update HumanFacilityType.cpp to
FAC_XENOMORPH_HOLDING_FACILITY, and
HumanFacility.cpp still uses the old names
FAC_HANGAR_FACILITY
FAC_GENERAL_STORAGE_FACILITY
FAC_ALIEN_CONTAINMENT_FACILITY

I've been trying to fix this all weekend, but had one technical problem after another. Data transmission related, not code related.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#40 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 05 December 2005 - 12:48 PM

Its near shippable mode, just a couple of ideas you can toy with. Instead of having two methods like isTroopItem and isCraftItem you can use a double dispatching pattern to handle that with the added flexibility if that we find out that we need more items or more specific types they can be handled easily and wont require modify much source.

For the rest, excelent design.

Greetings
Red Knight

<{POST_SNAPBACK}>

I considered double dispatch. However, as that would have added 12 virtual functions I decided to leave it out of the psudo code to reduce the clutter.

My next job is going to be building up the items.xml list, so that I have a complete list of all items. I note that I may need to add a few more, depending on exactly how some items are implemented.

e.g. I may need a Fuel Tank item, to represent the fuel tank in a craft. Likewise I may need an ammo item for each clip type.

Also, the psudocode uses a multimap to store the items. This is definitely not a good match for ContainerCraft or ContainerItem. They will almost certainly need their own custom internal containers. (Again, I left this out to avoid cluttering the psudocode.)

Edited by dteviot, 05 December 2005 - 12:49 PM.

Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#41 UnFleshed One

UnFleshed One

    Programming Department

  • Xenocide Inactive
  • 304 posts

Posted 05 December 2005 - 08:44 PM

There should be something like mass and it's even already implemented in our item.xsd/.xml :)

<{POST_SNAPBACK}>


Yep, that's what I mean. Mass can be considered when equipping troops and crafts, but for storage volume works better. Unless we just use mass instead, which is ok, but too far fetched for my liking...
Darkness is under the candle.

#42 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 05 December 2005 - 09:22 PM

There should be something like mass and it's even already implemented in our item.xsd/.xml :)

<{POST_SNAPBACK}>


Yep, that's what I mean. Mass can be considered when equipping troops and crafts, but for storage volume works better. Unless we just use mass instead, which is ok, but too far fetched for my liking...

<{POST_SNAPBACK}>

I agree with UnFleshed. Mass is important for figuring out Troop encumberance. But for a base, volume is the important factor.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#43 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 06 December 2005 - 09:56 AM

Oh i got it, and agian you (both) have right :P I should make a more thinkng before post replaying i didn't even realized before that heavy thinks don''t to have be also big :)
Posted Image

#44 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 06 December 2005 - 11:44 AM

Hmm so you are supposing to not make static data classes at all and hold all static (i mean common for all same types) data in normal varible in each object.

.... When i think a little of it, i also like it ;) it's even more adjustable :)

<{POST_SNAPBACK}>

It's been pointed out to me by one of the architects at work that a factory that creates objects by cloning a prototype is a Prototype pattern, not a Factory pattern.
Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#45 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 06 December 2005 - 02:52 PM

It is a Prototype Factory pattern indeed: Prototype Factory Example.

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#46 guyver6

guyver6

    Captain

  • Xenocide Programming Department
  • 599 posts

Posted 10 December 2005 - 05:57 PM

Do I see pointers there? Raw pointers? OMFG
Posted Image
Sourceforge: guyver6
LinkedIn: Andrzej Haczewski
"A good business idea, they say, can be explained in one sentence. Similarly, each program entity should have one clear purpose."

Join #xenocide at irc.freenode.net.

#47 red knight

red knight

    Xenocide Project Leader

  • Xenocide Inactive
  • 3,310 posts

Posted 10 December 2005 - 08:16 PM

Dont worry that is just pseudo code, I prefer C# style for pseudocode but well not everyone likes it ;)

Greetings
Red Knight
Sourceforge Nick: flois - Federico Andres Lois
Visit my blog at: flois.blogspot.com

Posted Image

Pookie cover me, I am going in.

#48 dteviot

dteviot

    Programming Department

  • [Xenocide Senior Members]
  • 1,479 posts

Posted 11 December 2005 - 12:55 AM

Mentor Beetle,
The Items/Containers work is taking longer than anticipated.
However, I’ve had a bit of an inspiration, and am trying the following approach. I’ve come up with the concept of a “rack” which represents a collection of identical items, and each container stores items in “racks”. I can then get each item to tell the container what is the maximum number of items that can be put in a rack held by the container.
e.g.
A rifle can tell a ContainerBase that it can store millions of rifles in a rack, but it will tell a troop that the troop can only store one item in a rack, and it will tell a craft that it can’t store any rifles.
Likewise, bullets will tell the base than an unlimited number of bullet items can be stored in one rack, but the troop will be told that only a “clip” of bullets can be stored in a rack. (So the troop will create multiple racks, one for each “clip” of bullets.)
And a gun can have a container with a single rack, that can take no more than a “clip” of bullets.

I’m now trying to test this theory by creating some guns and ammo items, and a Base, Troop and Item Container.

Incidentally, I think I’ll use the term Inventory, instead of Container.

Here’s where I am at the moment:
1. I’ve got the Item class (and a number of derived classes) loading the fields I need from the XML. (And I’ve structured them such that adding the rest of the fields, or the additional item types should be a reasonably simple job.) These files are item.h, item.cpp and itemWithInventory.cpp, included in item.zip. These files could probably be checked into xenocide\src\core\gamestate, except that I’ve put class XmlParseUtil in the files as well, and it should really go somewhere else common\xml perhaps? There’s also a test stub class to exercise the code. And possibly that should be put in a separate file as well. (I’m not sure what the policy’s are.)
2. I’ve updated item.xml and item.xsd to make them easier to parse. These will need to be added to the repositiory.
3. I’ve also updated xmlchptr.h and xmlchptr.cpp, to add some additional functionality. These will need to be added to the repositiory.

At the current time I am unable to check items into the repository. Can someone please PM me with the account name and password I need to use. Thanks

Still to Do:
1. Get the Inventory classes working. At the moment I haven’t even finished writing the base class, let alone getting it to compile or work. If you’re interested, inventory.zip has the current state of these files.

Attached Files


Saving the world from the scum of the universe is hard work. Especially when you have to create the scum to begin with.

#49 rincewind

rincewind

    Programming Department

  • Xenocide Programming Department
  • 541 posts

Posted 11 December 2005 - 03:34 AM

Hi,

about the svn-account, contact mindstormmaster, he should be able to give you one.
Patch looking good, except two things:

- Try to use the typedefs we have, e.g. TSharedPtr instead of boost::shared_ptr
- Raw Pointers are EVIL: (return type of ItemPrototypeFactory::findPrototype)

Rincewind
Posted Image

I love boost!!! The next best thing since the invention of C++.

#50 Beetle

Beetle

    Programming Department

  • Xenocide Inactive
  • 350 posts

Posted 11 December 2005 - 10:53 AM

Hi

Yeap PM mindstormmaster, you should get your svn access with promotion :)

Mentor Beetle,

Officialy i was your mentor for about few days, so give up with that.

Currently i'm quite bussy with my RL (2 days more) :( this is way i was inactiv lately.

If you don't get your svn access i will upload your patches in few days (once again sorry for delay).

About rack idea, yeah that should simplify item managing. Don't have any objections about it :)


Beetle
Posted Image