/* =========================================================================== Copyright (C) 2015 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ // lodthing.cpp : Level of detail manager #include "lodthing.h" #include "player.h" #include "scriptexception.h" Event EV_LODTool_Spawn ( "lod_spawn", EV_CONSOLE, "s", "model", "Edit LOD on the specified model" ); Event EV_LODTool_Think ( "lod_think", EV_DEFAULT, NULL, NULL, "Called every frame to process the view thing." ); Event EV_LODTool_SetModel ( "lod_model", EV_DEFAULT, NULL, NULL, "Set the model of the current viewthing" ); Event EV_LODTool_SetYaw ( "lod_yaw", EV_CONSOLE, "f", "yaw", "Set the yaw of the model" ); Event EV_LODTool_SetRoll ( "lod_roll", EV_CONSOLE, "f", "roll", "Set the roll of the model" ); Event EV_LODTool_SetAngles ( "lod_angles", EV_CONSOLE, "f[0,360]f[0,360]f[0,360]", "pitch yaw roll", "Set the angles of the model" ); Event EV_LODTool_Discard ( "lod_discard", EV_CONSOLE, NULL, NULL, "Discard LOD changes" ); LODMaster LODModel; CLASS_DECLARATION(Listener, LODMaster, "lodmaster") { {&EV_LODTool_Spawn, &LODMaster::Spawn }, {&EV_LODTool_SetYaw, &LODMaster::PassEvent}, {&EV_LODTool_SetRoll, &LODMaster::PassEvent}, {&EV_LODTool_SetAngles, &LODMaster::PassEvent}, {&EV_LODTool_Discard, &LODMaster::PassEvent}, {NULL, NULL } }; void LODMaster::Init(void) { gi.AddCommand("lod_spawn", NULL); gi.AddCommand("lod_yaw", NULL); gi.AddCommand("lod_pitch", NULL); gi.AddCommand("lod_roll", NULL); gi.AddCommand("lod_angles", NULL); gi.AddCommand("lod_discard", NULL); } void LODMaster::Spawn(Event *ev) { const char *mdl; Vector forward, up, delta; Entity *ent; LODSlave *m_lodmodel; mdl = ev->GetString(1); if (!mdl || !*mdl) { ScriptError("Must specify a model name"); } gi.cvar_set("lod_tikiname", mdl); gi.cvar_set("lod_tool", "1"); ent = g_entities->entity; if (!ent) { return; } if (ent->IsSubclassOfPlayer()) { ((Player *)ent)->SetFov(80); ent->setOriginEvent(Vector(2000, 0, 0)); } if (m_current) { m_current->PostEvent(EV_Remove, 0); } m_lodmodel = new LODSlave; m_current = m_lodmodel; ent->angles.AngleVectorsLeft(&forward, NULL, &up); m_lodmodel->m_baseorigin = Vector(-1600, 0, 0); m_lodmodel->setOrigin(m_lodmodel->m_baseorigin); m_lodmodel->m_baseorigin = m_lodmodel->origin; delta = Vector("1 0 0"); delta.toAngles(); m_lodmodel->setAngles(delta); m_lodmodel->setScale(1.0f); Event *event = new Event(EV_LODTool_SetModel); event->AddString(mdl); m_lodmodel->ProcessEvent(event); if (!m_lodmodel->edict->tiki) { m_current = NULL; ScriptError("Error in model '%s', LOD model not spawned.", mdl); } for (int i = 0; i < MAX_FRAMEINFOS; i++) { m_lodmodel->Pause(i); } gi.SendConsoleCommand("cg_drawvidemodel 0\n"); gi.SendConsoleCommand("cg_shadows 0\n"); gi.SendConsoleCommand("ui_compass 0\n"); gi.SendConsoleCommand("r_fastsky 1\n"); gi.SendConsoleCommand("r_drawworld 0\n"); } void LODMaster::PassEvent(Event *ev) { if (!m_current) { ScriptError("No LOD Model"); } m_current->ProcessEvent(*ev); } CLASS_DECLARATION(Animate, LODSlave, "lodslave") { {&EV_LODTool_Think, &LODSlave::ThinkEvent }, {&EV_LODTool_SetModel, &LODSlave::SetModelEvent}, {&EV_LODTool_Discard, &LODSlave::Delete }, {NULL, NULL } }; void LODSlave::UpdateCvars(qboolean quiet, qboolean updateFrame) {} LODSlave::LODSlave(void) { m_baseorigin = origin; LODModel.m_current = this; edict->s.eType = ET_MODELANIM_SKEL; edict->s.renderfx |= RF_SHADOW; edict->s.renderfx |= RF_ADDITIVE_DLIGHT; PostEvent(EV_LODTool_Think, level.frametime); } static float lod_yaw = 0.0f; void LODSlave::ThinkEvent(Event *ev) { cvar_t *cvar; Entity *ent; Vector position; PostEvent(EV_LODTool_Think, level.frametime); lod_yaw += 2.0f; if (lod_yaw > 180.0f) { lod_yaw = lod_yaw - 360.0f; } cvar = gi.Cvar_Get("lod_pitch_val", "", 0); angles[0] = cvar->value; angles[1] = lod_yaw; setAngles(angles); ent = g_entities->entity; if (ent->IsSubclassOfPlayer()) { ((Player *)ent)->SetFov(80.0); ent->setOrigin(Vector(-4000, 0, 0)); } cvar = gi.Cvar_Get("lod_position", "", 0); sscanf(cvar->string, "%f %f %f", &position[0], &position[1], &position[2]); cvar = gi.Cvar_Get("lod_zee_val", "", 0); position[2] -= cvar->value; setOrigin(position); } void LODSlave::SetModelEvent(Event *ev) { str modelname = ev->GetString(1); setModel(modelname); if (edict->tiki) { NewAnim("idle"); SetFrame(); } } void LODSlave::Delete(Event *ev) { ScriptError("DELETE"); }