-
Posts
7,936 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Rick
-
I think handling the speeds of travel would be easy to do with trigger areas, but I'm talking more about influencing what paths get picked by weight (not sure if that happens in Civ).
-
Is there a way, using the current LE pathfinding system, to create weighted values for certain areas? This is a fairly common thing in 2D A* pathfinding where there are many ways to get to where you want to go but some are faster, even if they are longer, because of penalties of the area you are walking. An example would be roads vs tall grass. Tall grass would incur a walking penatly making it slower even though it might be a straight line, than using a road that zig zags but is easier to walk on. I would like to think recast could have "soft" obstacles that don't stop a path from being made with it, but make the path more expensive to walk than another path. Along those lines, having multiple versions of the grid would be nice because some characters you may want to use 1 mesh, and others you want to use another.
-
An easier way to do this instead of figuring out what script is attached to an entity would be to have your empty script actually take some kind of text data. This data would id what you want done in C++. Inside the Start() method of the script is where you would set the entity key to this text data, then in C++ you loop over the loaded entities reading this key and then branch what classes you want to associate the entity too. wtf, these tags on this site get so screwed up sometimes *sigh* Why do we get all this font **** to show up sometimes when I'm making code tags? The above was a rough example. A better example would be to make a factory system so you can just have the factory create an instance of the class directly from the string name instead of a big if statement. I did the above with LE 2 and the C# bindings but I used reflection to make the class instances where the type string was the actual class name. I then make a plugin system in C# that dynamically loaded DLL's. It was pretty cool because to add new functionality with a given class template I didn't have to adjust the main game exe, but just create a DLL and in the editor assign an entity this "type" string. Doing that in C++ is a little more difficult because of C++ objs, compilers, and DLL not playing nice together.
-
I've had issues with purchased characters and applying textures as well. I don't know enough about texturing to know what's going on though.
-
I agree that being able to check the path before using has benefit. In my game I would also like to know about the path to do some cost stuff for movement.
-
Try dbl clicking to bring up model viewer and from menu do calculate normals. See if that works.
-
You cast a ray and get the entity it hit. Then find out what that entity is somehow. You can set an entity key for all your entites and read that key from the hit entity.
-
2 common ways. Ray cast which is instant or an actual physics object that would more simulate an actual bullet. I find ray cast to be easier and less to deal with.
-
@BLaBZ I agree. Other usages I was thinking about was a game engine with your own editor. If you combine this with component design you can get some pretty flexible things made via an editor. You could add any properties to a game object without coding and do it via an editor.
-
Anytime! I love this stuff
-
I like the idea of being able to add dynamic properties at run-time. The following code shows how you can set this up. Instead of declaring a hardcoded amount of variables in a class you could just give it 1 Properties class and it can be dynamic! #include <string> #include <map> using namespace std; class Prop { public: virtual ~Prop() { } }; template<typename T> class Property : public Prop { private: T data; public: virtual ~Property() { } Property(T d) { data = d; } T GetValue() { return data; } }; class Properties { private: map<string, Prop*> props; public: ~Properties() { map<string, Prop*>::iterator iter; for(iter = props.begin(); iter != props.end(); ++iter) delete (*iter).second; props.clear(); } template<typename T> void Add(string name, T data) { props[name] = new Property<T>(data); } template<typename T> T Get(string name) { Property<T>* p = (Property<T>*)props[name]; return p->GetValue(); } }; int main() { Properties p; p.Add<int>("age", 10); int age = p.Get<int>("age"); return 0; }
-
If you attach an empty lua script they should now just be normal entities as far as I know. Make sure they have names in the editor and you should see them in the world->entities list.
-
What are your boxes? If it's csg boxes then you'll need to attach a lua script to them. Even an empty script will work. By doing this you are telling the engine to NOT collapse the csg into the rest of the csg which would make it impossible to get. If they are imported models then you shouldn't have to attach a script.
-
I don't think that's how you want to iterate over the list. Try: list<Entity*>::iterator iter; for(iter = world->entities.begin(); iter != world->entities.end(); ++iter) { string name = (*iter)->GetKeyValue("name"); } If you want to make it look easier you can use a macro: // top of a header #define foreach(iter, container) for(iter = container.begin(); iter != container.end(); ++iter) typedef list<Entity*>::iterator EntityIter; and use like: EntityIter iter; foreach(iter, world->entities) { string name = (*iter)->GetKeyValue("name"); } If all else fails just attach your project files here and I can take a look to see if anything obvious pops out.
-
There is currently no free/indie license. It's a cheap engine compared to some others so you get a 30 day trial. It's just a business decision on the part of LE that helps keep the engine cheap.
-
Show me how you assigned that callback for loading the map. An alternative method would be to just loop over the world.entities container after you load the map. It stores all the entities that got loaded.
-
This is from memory and not tested but it shows you the general idea. You might have to make a couple tweaks to make it work. // this is our base class "interface" // we'll derive any other classes we want to be collidable from this class class Collidable { public: virtual void Collision(Entity* collidedEntity, const Vec3& position, const Vec3& normal, float speed)=0; // pure virtual so if you derive a class from this you have to implement this in that class }; // Trigger.h (feel free to break the actual definition of Collision() into it's our source I just put it here to reduce typing // this is basically a wrapper class for the LE's Entity class to provide us with class level collision callback functionabilty class Trigger: public Collidable { private: Entity* entity; public: Trigger(Entity* e) { entity = e; } virtual void Collision(Entity* collidedEntity, const Vec3& position, const Vec3& normal, float speed) { // our game logic on what to do in a collision here } Entity* GetEntity() { return entity; } }; // App.h #pragma once #include "Leadwerks.h" #include "MyGameObject.h" #include list; using namespace std; using namespace Leadwerks; // declare the normal C collision hook. We'll only ever have this 1 in our entire application because // the purpose of this function is to just route the collision to the derived Collidable object void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); class App { private: list<Trigger*> triggers public: Window* window; Context* context; World* world; Camera* camera; App(); virtual ~App(); void LoadMapEntity(Entity* e); virtual bool Start(); virtual bool Loop(); }; // App.cpp // have all your other normal stuff but I'm only going to show the new stuff void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed) { // for each LE entity we attached our MyGameObject which derives from Collidable to we'll get that object back from the entity Collidable* c = ((Collidable*)entity0->GetEntityUserData()); // route the collision to this objects virtual function to be dealt with if(c != NULL) c->Collide(entity1, position, normal, speed); } void App::LoadMapEntity(Entity* e) { // I would do something more generic here like maybe say if indexof("trigger") so that it does this for everything you have trigger in the name for if(e->GetKeyValue("name") == "trigger1") { // make a trigger object passing in the entity to store Trigger* trig = new Trigger(e); // hook this entity up to the global collision callback e->AddHook(Entity::CollisionHook, (void*)CollisionHook); // assign the trig object pointer to this entities user data, which is just a generic storage place e->SetEntityUserData((void*)trig); // add to our trigger list triggers.push_back(trig); } } // please make sure in the editor that you have setup your collisions correctly so it will actually fire the collision callback
-
Looking into Lua-ENet and it looks like on github they have the C source. You should be able to plug that into the LE exe project, include Lua 5.1.4 in that project as well and then it would all compile together and you wouldn't need require() then.
-
I don't know about those. I'm using RakNet, but I made bindings to the RakPeer and BitStream and expose those to Lua and I have that working. In the past I use LoadLibrary() from lua I think to load a DLL. It seems LE does have it's own require() functions so not sure if it works. Have you tried it and had issues with it? This to note: if you plan on doing any mobile this may not work as I don't think you can load DLL type things on iOS and possibly android. This is my concern, and so that's why I've created the bindings in the LE exe itself so it's part of the main program.
-
This is what's a pain about the current process in C++ and it can get complicated. You can just make the CollisionHook() a normal standalone C function and not part of the class. This with it brings issues right? Because now you have scoping issues of what CollisionHook() can see because we all know global variables are evil and to avoid them. Luckily I believe there is a ->SetUserData() and GetUserData() function. This allows us to attach anything to our entities. In our case we would want to attach an object (like App (use 'this' when calling from within App class). Set this up after you've already assigned trigger to e though. trigger->SetUserData((void*)this); Then make sure your virtual collision function is actually part of the App class. So in your source you use App::Collision(etc) Now inside your CollisionHook() you use entity->GetUserData() and cast to App* and check if it's null. If it's not null then you can now call your App's collision virtual function passing in all the parameters. Now you are inside your App class and can access all of it's members. A better way would be to make a base class that has a virtual Collision() and holds an Entity*. Create one of these objects and assign it your 'e' variable. In your collisionhook cast to this base class and call it's virtual Collision(), which if you actually made a child class will call that collision function. Give that a try and if you need I can make an example to show how to do this.
-
So we have GetAppDataPath() to return a path. Then we concat a filename to that path to pass into one of the open/read whatever functions. The question is what slash should we use that'll work on all platforms when doing that? completePath = GetAppDataPath().."/"..filename --?? If it's different on each platform a function to handle this would be nice. In .NET they have Path.Combine(path, filename).
-
Can we get that documented because that's nice to know
-
What does that do? It's not documented: http://www.leadwerks.com/werkspace/page/documentation/_/command-reference/filesystem/
-
Read the entire file to a string. Coming from the .NET work and File.ReadAllText() is handy to just get the entire file contents into a string to play around with in 1 function call.
-
Yeah, there is a big layer of design that you aren't at yet. I normally make an Animation class and an AnimationManager class that stores a list of Animations. Then on init of the game I setup all animations required. Then I generally link actor states to animations since animations generally don't just play. They play for a reason and that reason is generally an actor state (dying, hurt, idle, running, ect). Now the Actor class is very generic but each actor can be created uniquely as I fill out it's animations, models, other data.