Okay, just talking this out to myself. No one needs to get involved yet
When you /spawn set heading, here's what happens -
In Command.cpp, first:
Code: Select all
spawn_set_values["heading"] = SPAWN_SET_VALUE_HEADING;
So that array element now = 29.
Next, the switch:
Code: Select all
case SPAWN_SET_VALUE_HEADING:{
sprintf(tmp, "%f", target->GetHeading());
target->SetHeading(atof(value) + 360, send_update);
break;
This sets the value that is going to be updated in the Database. Not concerned about the Math right now, just how this gets written.
Next, the 2nd switch:
Code: Select all
case SPAWN_SET_VALUE_HEADING:{
target->SetHeading(atof(value), send_update);
target->SetSpawnOrigHeading(target->GetHeading());
break;
This is where the spawn in the world changes heading visually, and I believe ALL SPAWNS with this guys spawns.id value are swiveling to the new heading -
in game, only (theoretically).
Then, the command gets processed and this code gets called in COMMAND_SPAWN_SET.
This is the critical part. What gets written to the DB?
Code: Select all
if((set_type >= SPAWN_SET_VALUE_RESPAWN && set_type <=SPAWN_SET_VALUE_LOCATION) || (set_type >= SPAWN_SET_VALUE_EXPIRE && set_type <=SPAWN_SET_VALUE_Z_OFFSET))
{
if(spawn->GetSpawnLocationID() > 0 && database.UpdateSpawnLocationSpawns(spawn))
which basically checks if the constant value is between certain ranges, then update the location (we should re-arrange these so they are not all over the map someday). In this case, SPAWN_SET_VALUE_HEADING == 29, and is between 25 and 30 (the first check). If so, save the updated location.
Okay, let's update the location information now -
Code: Select all
bool WorldDatabase::UpdateSpawnLocationSpawns(Spawn* spawn){
Query query;
query.RunQuery2(Q_UPDATE, "update spawn_location_placement set x=%f, y=%f, z=%f, heading=%f, x_offset=%f, y_offset=%f, z_offset=%f, respawn=%lu, expire_timer=%lu, expire_offset=%lu, grid_id=%lu where id = %lu",
spawn->GetX(), spawn->GetY(), spawn->GetZ(), spawn->GetHeading(), spawn->GetXOffset(), spawn->GetYOffset(), spawn->GetZOffset(), spawn->GetRespawnTime(), spawn->GetExpireTime(), spawn->GetExpireOffsetTime(), spawn->appearance.pos.grid_id, spawn->GetSpawnLocationPlacementID());
if(query.GetErrorNumber() && query.GetError() && query.GetErrorNumber() < 0xFFFFFFFF){
LogWrite(WORLD__ERROR, "World", "Error in UpdateSpawnLocationSpawns query '%s': %s", query.GetQuery(), query.GetError());
return false;
}
return true;
}
Because the WHERE clause specifies only the `id` column in the `spawn_location_placement` table, there should be no way that more than this 1 placement is getting updated in the database (spawn->GetSpawnLocationPlacementID()). Even if visually in-world, they are all flipping around, I theorize that's just a visual bug with how spawn.appearances get updated in the world.
If this is true, this is not critical then, though I would like to see it fixed eventually (to save anymore confusion). To fix this, we'd have to limit appearance updates to the current placement ID and not spawn_id for anything location-based.
Thoughts?
I'll test this theory out later when I get home. No code changes, just observing DB updates and /reload spawn after setting 1 spawn that affects many.