I was trying to run it/play around with, but after resolving the compilation error, the building placement system doesn't work properly.
The first Turret I try to place work perfectly, the others, it's just random ..
Here is a video that can explain better :
After spending some time on it, i still can't figure it out.
You can download the project, if one of you have time (it's a small one ) or here is the code i think it's responsible of it :
Code:
Turret* Turret.Create()
{
ObjectPtr tempParams=UID(3249259405, 1294192879, 2507658368, 1464910172); // get turret object parameters
// Every Turret points to the same mesh-instance. We need to duplicate the mesh so that it's unique for each Turret.
ObjectPtr newParams;
MeshPtr newMesh = new Mesh();
newMesh->add(*tempParams->mesh());
// Copy our material param too
MaterialPtr newMat = new Material();
newMat = UID(2213835078, 1185514479, 1447066557, 906687580); //tempParams->material(); // get the material from the .obj, assign to new material
//material = newMat; // Change pointer to that material
// Apply all the duplicates to the new ObjParamsPtr
newParams = tempParams;
newParams->mesh(1, newMesh);
newParams->mesh()->material(newMat);
// Create a new Turret in the world manager and return the pointer to that new Turret object.
Turret* turret;
if (Game.Obj* obj = Game.World.objCreateNear(*newParams, Matrix(newParams->scale(), Vec(0,0,0)))) // create new object at position and give objects default scaling
{
turret = CAST(Turret, obj);
turret->actor.group(AG_TURRET);
}
return turret;
}
Code:
void Turret.UpdateConstruction()
{
// Construct the turret, part-by-part
if (m_Constructed >= m_PartConstructTime)
{
++m_PartsShown;
m_PartsFlagged |= IndexToFlag(m_PartsShown); // Add the next part to the current flags using "binary or" (draw: part1 -> part1 + part2 -> part1 + part2 + part3 -> ...)
m_Constructed = 0;
// Mask will be set just before drawing the turret (see drawPrepare())
}
// Last part has been made visible; turret is now complete. Replace with proper turret (2 parts, skeleton, ..) and go to next state
if (m_PartsShown == Part8) // LAST PART IS VISIBLE (Is there a clean way to get the amount of elements in an enum?)
{
ObjectPtr tempParams=UID(1580207742, 1152603128, 734962056, 2386524293); // get turret object parameters
// Replace the current mesh
mesh = tempParams->mesh();
// Create the skeleton
Skeleton* newSkel = new Skeleton();
newSkel = tempParams->mesh()->skeleton();
skel.create(newSkel); // cskel will be used to handle the rotation of the turret-top
// Add the skeleton to the mesh
mesh()->skeleton(newSkel);
// Set up the actor so we can click on the turret and get/set params
actor.create(*tempParams->phys());
actor.group(AG_TURRET);
actor.obj(this);
m_CurrentState = STATE_BUILT; // Turret is constructed, and final new turret has been initialized: Go to the last state
InitParticles(); // Initialize particles
}
m_Constructed += Time.rd(); // Increment construction time for next mesh part
}
Code:
Bool TurretManager.PlaceTurret()
{
Turret temp;
// This is the first time we create a turret. Make one right away.
if (Turrets.elms() == 0)
{
// Create a turret (uses ObjCreateNear)
temp.Create();
}
// Only create a new turret if we didn't have one (unplaced) already
else if(!Turrets[Turrets.elms()-1].GetState() == STATE_BLUEPRINT)
{
// Create a turret (uses ObjCreateNear)
temp.Create();
}
return true;
}
Code:
Bool TurretManager.UpdateTurretPlacement()
{
if (Turrets.elms() && (Turrets)[Turrets.elms()-1].GetState() == STATE_BLUEPRINT)
{
// If we just convert the Mouse screen position to world position, it will be on a tilted plane (since the camera is tilted).
// We cannot use this world position as the position for our new turret.
// We cast a ray from before our mouse position in world space (mousepos - direction of screen) to behind (mousepos + direction of screen)
// If we hit the terrain, that's where we place our turret
Vec mousePos = ScreenToPos(Ms.pos());
Vec start = Vec(mousePos - ScreenToDir(Ms.pos())*10), // starting position of ray
end = Vec(mousePos + ScreenToDir(Ms.pos())*100); // ending position of ray
PhysHit phys_hit; // phys-hit object for receiving hit parameters if any
if(Physics.ray(start, end-start, &phys_hit, IndexToFlag(AG_TERRAIN))) // if ray hit the terrain
{
// If the turret that we have selected is a blueprint
if (Turrets[Turrets.elms()-1].GetState() == STATE_BLUEPRINT)
{
m_MouseHoveringLocation = phys_hit.plane.pos;
Turrets[Turrets.elms()-1].mesh()->material(m_OriginalTurretMat); // Set turret material to original one
// We can NOT place this turret on the road (check material of terrain on "pos". pos is on a horizontal plane)
// We check on a plane because for each point on that plane is only one corresponding point on the heightmap. there's no need for the Y(up)-value
MaterialPtr clicked = Game.World.hmMaterial(m_MouseHoveringLocation.xz());
if(clicked.id() != UID(2786128996, 1138576899, 2137332655, 3258567423))
{
m_DrawUnplaceableLocations = false; // Stop drawing where we can't place the turret
// Player has clicked the RMB, place the turret
if (Ms.b(0)) (Turrets)[Turrets.elms()-1].SetState(STATE_UNBUILT);
}
else // Turret can not be placed
{
Turrets[Turrets.elms()-1].mesh()->material(m_BlockedTurretMat); // Change colour of the turret to red
}
I made that project a long time ago (when I was still fairly new to programming). There are many things I don't remember from it, and many things I would probably do different now. in any case, I'll help with what we have here!
In the near future, I hope to bring out some more step-by-step tutorials for programming in Esenthel.
First of all: I am on my home PC and messed up my installation of visual studio 2015 (I had a couple of different versions installed and uninstalled those to save space on my Hard Drive.. Don't do that, really.. I can't get it to work even after a full reinstall). So, I can't compile the project.
Secondly: Since I can't compile, I need to see the video but it's set to private. Could you change the accessibility to public/ or direct link please?
Hey,
Yeah I know it's you, thanks for you share !
I had a system that worked (a bad one), but i didn't really like it, so i decided to check your source, see how it was going.
The video is on public now, you should be able to see it.
ps : I did the same with visual studio ... Terrible idea, I feel your pain bro' ^
I checked it just now and figured out the problem. I'm not sure how that stayed in there for so long, as it is a serious issue.
In TurretManager::UpdateTurretPlacement, there is a check to see if the mouse button is pressed.
Code:
if(Ms.b(0)) ..
This should be:
Code:
if(Ms.bp(0)) ..
After clicking on the GUI, I eat the mouse action so it doesn't also register as a click for the turret manager. However: Ms.b is true for EVERY FRAME that the button is down, so the eat() is useless. Changing to Ms.bp fixes this as it will be set to false again right after clicking on the GUI.
Also, there is a crash when you close the application. In the Turret Save/Load functions: Don't save/load m_Target. That was a very silly thing to do and should not be there.
Here, try with my version. I've made some more changes to UpdatePlacement() too. It's nothing spectacular, just a bit cleaner and possibly more correct.
It works perfectly thanks to you. I didn't have time to check it in depth, so I still don't know why it wasn't working for me (even after changing Ms.b to Ms.bp), I will look into it tomorrow.
Big thanks to you dude, still pretty new with esenthel, they are some thing that I need to work harder