示例#1
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyGiveClientTo(PyObject* pyOterProxy)
{
	if(this->isDestroyed())
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",
			scriptName(), id());		
		PyErr_PrintEx(0);

		return 0;
	}

	if (pyOterProxy == NULL || !PyObject_TypeCheck(pyOterProxy, Proxy::getScriptType()))
	{
		PyErr_Format(PyExc_AssertionError, "%s[%d]::giveClientTo: arg1 not is Proxy!\n",
			scriptName(), id());
		PyErr_PrintEx(0);

		return 0;
	}

	// 如果为None 则设置为NULL
	Proxy* oterProxy = NULL;
	if(pyOterProxy != Py_None)
		oterProxy = static_cast<Proxy*>(pyOterProxy);
	
	giveClientTo(oterProxy);
	S_Return;
}
示例#2
0
//-------------------------------------------------------------------------------------
void Proxy::onDefDataChanged(const PropertyDescription* propertyDescription, 
		PyObject* pyData)
{
	uint32 flags = propertyDescription->getFlags();

	if((flags & ED_FLAG_BASE_AND_CLIENT) <= 0 || clientMailbox_ == NULL)
		return;

	// 创建一个需要广播的模板流
	MemoryStream* mstream = MemoryStream::ObjPool().createObject();

	propertyDescription->getDataType()->addToStream(mstream, pyData);

	Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
	(*pBundle).newMessage(ClientInterface::onUpdatePropertys);
	(*pBundle) << id();

	if(scriptModule_->usePropertyDescrAlias())
		(*pBundle) << propertyDescription->aliasIDAsUint8();
	else
		(*pBundle) << propertyDescription->getUType();

	pBundle->append(*mstream);
	
	g_privateClientEventHistoryStats.trackEvent(scriptName(), 
		propertyDescription->getName(), 
		pBundle->currMsgLength());

	sendToClient(ClientInterface::onUpdatePropertys, pBundle);
	MemoryStream::ObjPool().reclaimObject(mstream);
}
示例#3
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyClientAddr()
{ 
	if(isDestroyed())	
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",		
			scriptName(), id());		
		PyErr_PrintEx(0);
		return 0;																				
	}

	PyObject* pyobj = PyTuple_New(2);

	if(clientMailbox() == NULL || clientMailbox()->getChannel() == NULL || 
		clientMailbox()->getChannel()->pEndPoint() == NULL)
	{
		PyTuple_SetItem(pyobj, 0, PyLong_FromLong(0));
		PyTuple_SetItem(pyobj, 1, PyLong_FromLong(0));
	}
	else
	{
		const Network::Address& addr = clientMailbox()->getChannel()->pEndPoint()->addr();
		PyTuple_SetItem(pyobj, 0, PyLong_FromUnsignedLong(addr.ip));
		PyTuple_SetItem(pyobj, 1, PyLong_FromUnsignedLong(addr.port));
	}

	return pyobj;
}
示例#4
0
void Door::onLast()
{
   if (const char *lpcszScript = scriptName("onOpen"))
   {
      Console->executef(3, lpcszScript, scriptThis(), getId());
   }
}
示例#5
0
文件: pyvis.cpp 项目: b3sigma/fourd
bool LoadInitialModules(PyVis* pyVis) {
    std::string scriptName("EmbeddedBinding");
    std::string scriptNameShorthand("eb");
    if(!pyVis->LoadModule(scriptName)) {
        return false;
    }
    PyErr_Print();

    // So far this seems to be necessary to use EmbeddedBinding from the 
    // PyRun_SimpleString context, but they are still referencing the same module
    std::string importToSimple = std::string("import ") + scriptName; 
    PyRun_SimpleString(importToSimple.c_str()); 
    // Same, but now even more convenient! So like "eb.ScriptStep()"
    std::string importToSimpleShorthand = std::string("import ") + scriptName
        + std::string(" as ") + scriptNameShorthand;
    PyRun_SimpleString(importToSimpleShorthand.c_str());
    
    PyRun_SimpleString("import numpy"); // handy, was already loaded above anyway

    PyObject* scriptDict = pyVis->GetDict(scriptName);
    PyRun_String("ScriptCreate()", Py_eval_input, pyVis->consoleGlobalContextDict, scriptDict);
    pyVis->consoleLocalContextDict = scriptDict;

    PyObject* scriptStep = PyDict_GetItemString(scriptDict, "ScriptStep"); // borrowed ref
    pyVis->scriptStep = scriptStep;  // borrowed ref
    if(!scriptStep || !PyCallable_Check(scriptStep)) {
        printf("Error loading python potential step function linkage: no ScriptStep()\n");
        PyErr_Print();
        return false; 
    }

    return true;
}
示例#6
0
void CJavascriptStackTrace::Dump(std::ostream& os) const
{
  v8::HandleScope handle_scope(m_isolate);

  v8::TryCatch try_catch;

  std::ostringstream oss;

  for (int i=0; i<GetFrameCount(); i++)
  {
    v8::Handle<v8::StackFrame> frame = GetFrame(i)->Handle();

    v8::String::Utf8Value funcName(frame->GetFunctionName()), scriptName(frame->GetScriptName());

    os << "\tat ";

    if (funcName.length())
      os << std::string(*funcName, funcName.length()) << " (";

    if (frame->IsEval())
    {
      os << "(eval)";
    }
    else
    {
      os << std::string(*scriptName, scriptName.length()) << ":"
          << frame->GetLineNumber() << ":" << frame->GetColumn();
    }

    if (funcName.length())
      os << ")";

    os << std::endl;
  }
}
示例#7
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyGetTimeSinceHeardFromClient()
{ 
	if(isDestroyed())	
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",		
			scriptName(), id());		
		PyErr_PrintEx(0);
		return 0;																					
	}
	
	return PyFloat_FromDouble(this->getTimeSinceHeardFromClient()); 
}
示例#8
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyGetRoundTripTime()
{ 
	if (!hasFlags(ENTITY_FLAGS_DESTROYING) && isDestroyed())
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",		
			scriptName(), id());		
		PyErr_PrintEx(0);
		return 0;																				
	}

	return PyFloat_FromDouble(this->getRoundTripTime()); 
}
示例#9
0
//-------------------------------------------------------------------------------------
int VolatileInfo::pySetOptimized(PyObject *value)
{
	if (!PyBool_Check(value))
	{
		PyErr_Format(PyExc_AssertionError, "%s: set pitch value is not bool!\n",
			scriptName());
		PyErr_PrintEx(0);
		return 0;
	}

	optimized_ = value == Py_True;
	return 0;
}
示例#10
0
//-------------------------------------------------------------------------------------
int VolatileInfo::pySetRoll(PyObject *value)
{
	if (!PyFloat_Check(value))
	{
		PyErr_Format(PyExc_AssertionError, "%s: set roll value is not float!\n",
			scriptName());
		PyErr_PrintEx(0);
		return 0;
	}

	roll_ = (float)PyFloat_AsDouble(value);
	return 0;
}
示例#11
0
bool Turret::isTargetable (Player *player, float *minDist, float useRange)
{
	if (player && player->getTeam () != getTeam() && player->getVisibleToTeam (getTeam()) && !player->isDead())
		{
			if (const char* script = scriptName("verifyTarget")) {
            const char* pRet = Console->evaluatef("%s(%d);", script, player->getId());
            if (pRet[0] == 'F' || pRet[0] == 'f')
               return false;
         }

			Point3F playerPos = player->getLeadCenter();
			float dist = m_distf (getBoxCenter(), playerPos);

			if (dist < useRange)
				targetsTracked++;

			if (dist < *minDist)
				{
					TMat3F invMat;
					getNodeOffset (&invMat, "dummy muzzle", gunNode);
					invMat.inverse();
					m_mul (Point3F (playerPos.x, playerPos.y, playerPos.z), invMat, &playerPos);

					float ele = elevation (playerPos.x, playerPos.y, playerPos.z);
					float rotz = rotation (-playerPos.x, -playerPos.y);

					if (!inDeadZone (rotz, ele))
						{
					      SimContainerQuery collisionQuery;
					      collisionQuery.id = getId();
					      collisionQuery.type   = -1;
					      collisionQuery.mask   = SimTerrainObjectType | SimInteriorObjectType;
					      collisionQuery.detail = SimContainerQuery::DefaultDetail;
					      collisionQuery.box.fMin = getBoxCenter();
					      collisionQuery.box.fMax = player->getLeadCenter();

					      SimCollisionInfo collisionInfo;
							SimContainer* root = findObject(manager,SimRootContainerId,root);
					      root->findLOS(collisionQuery, &collisionInfo);
							if (!collisionInfo.object || collisionInfo.object == player)
								{
									*minDist = dist;
									return true;
								}
						}
				}
		}

	return false;
}
示例#12
0
void DumpJSStack()
{
    Local<StackTrace> st = StackTrace::CurrentStackTrace(25);

    OutputDebugStringA("\n\n--- Javascript Stack ---\n");
    for( int i = 0; i < st->GetFrameCount(); i++ )
    {
        Local<StackFrame> sf = st->GetFrame(i);

        char szOut[8 * 1024];
        String::Utf8Value scriptName(sf->GetScriptName());
        String::Utf8Value funcName(sf->GetFunctionName());
        sprintf(szOut, "%s (%d,%d):%s\n", *scriptName, sf->GetLineNumber(), sf->GetColumn(), *funcName);
        OutputDebugStringA(szOut);
    }
}
示例#13
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyGetEntitiesEnabled()
{ 
	if(isDestroyed())	
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",		
			scriptName(), id());		
		PyErr_PrintEx(0);
		return 0;																				
	}

	if(this->entitiesEnabled())
	{
		Py_RETURN_TRUE;
	}

	Py_RETURN_FALSE;
}
示例#14
0
//-------------------------------------------------------------------------------------
PyObject* Proxy::pyHasClient()
{ 
	if (!hasFlags(ENTITY_FLAGS_DESTROYING) && isDestroyed())
	{
		PyErr_Format(PyExc_AssertionError, "%s: %d is destroyed!\n",		
			scriptName(), id());		
		PyErr_PrintEx(0);
		return 0;																				
	}

	if(this->hasClient())
	{
		Py_RETURN_TRUE;
	}

	Py_RETURN_FALSE;
}
示例#15
0
void Player::applyDamage(int type,float value,const Point3F pos,
	const Point3F& vec,const Point3F& mom,int objectId)
{
   const char* script;
	if (!isGhost())
		if ((script = scriptName("onDamage")) != NULL) {
         const char* pVert;
         const char* pQuad;
         getDamageLocation(pos, pVert, pQuad);

			Console->evaluatef("%s(%s,%d,%g,\"%g %g %g\",\"%g %g %g\",\"%g %g %g\",%s,%s,%d);",
				script,scriptThis(),type,value,
				pos.x,pos.y,pos.z,
				vec.x,vec.y,vec.z,
				mom.x,mom.y,mom.z,
            pVert, pQuad,
				objectId);
      }
}
示例#16
0
void Player::kill ()
{
   if (isGhost() || dead)
      return;

	dead = true;
	damageLevel = data->maxDamage;
	setMaskBits (DamageMask);

	disableSupressionField();
	dieTime = manager->getCurrentTime();
	  
	if (const char* script = scriptName("onKilled"))
		Console->executef(2,script,scriptThis());

	type = CorpseObjectType;
	collisionMask = ServerCorpseCollisionMask;
	collisionImage.trigger = true;
	SimMessageEvent::post(this, manager->getCurrentTime() + CorpseTriggerTimeout, CorpseTriggerMsg);
	jetting = false;
}
示例#17
0
文件: base.cpp 项目: ihuangx/kbengine
//-------------------------------------------------------------------------------------
void Base::onDefDataChanged(const PropertyDescription* propertyDescription, 
		PyObject* pyData)
{
	if(initing())
		return;

	if(propertyDescription->isPersistent())
		setDirty();
	
	uint32 flags = propertyDescription->getFlags();

	if((flags & ED_FLAG_BASE_AND_CLIENT) <= 0 || clientMailbox_ == NULL)
		return;

	// 创建一个需要广播的模板流
	MemoryStream* mstream = MemoryStream::createPoolObject();

	propertyDescription->getDataType()->addToStream(mstream, pyData);

	Network::Bundle* pBundle = Network::Bundle::createPoolObject();
	(*pBundle).newMessage(ClientInterface::onUpdatePropertys);
	(*pBundle) << id();

	if(pScriptModule_->usePropertyDescrAlias())
		(*pBundle) << propertyDescription->aliasIDAsUint8();
	else
		(*pBundle) << propertyDescription->getUType();

	pBundle->append(*mstream);
	
	g_privateClientEventHistoryStats.trackEvent(scriptName(), 
		propertyDescription->getName(), 
		pBundle->currMsgLength());

	// 按照当前的设计来说,有clientMailbox_必定是proxy
	// 至于为何跑到base里来和python本身是C语言实现有关
	static_cast<Proxy*>(this)->sendToClient(ClientInterface::onUpdatePropertys, pBundle);
	MemoryStream::reclaimPoolObject(mstream);
}
示例#18
0
void
ProjectPackager::startAudioDecoder(QStringList flacFiles, QStringList wavpackFiles)
{
    // we can't do a oneliner bash script straight out of a QProcess command
    // line, so we'll have to create a purpose built script and run that
    QString scriptName("/tmp/rosegarden-audio-decoder-backend");
    m_script.setFileName(scriptName);

    // remove any lingering copy from a previous run
    if (m_script.exists()) m_script.remove();

    if (!m_script.open(QIODevice::WriteOnly | QIODevice::Text)) {
        puke(tr("<qt><p>Unable to write to temporary backend processing script %1.</p>%2</qt>").arg(scriptName).arg(m_abortText));
        return;
    }

    QTextStream out(&m_script);
    out << "# This script was generated by Rosegarden to combine multiple external processing"      << endl
        << "# operations so they could be managed by a single QProcess.  If you find this script"   << endl
        << "# it is likely that something has gone terribly wrong. See http://rosegardenmusic.com" << endl;

    int errorPoint = 1;

    // The working directory must be the key to why tar is not failing, but
    // failing to do anything detectable.  Let's cut apart m_filename...
    QFileInfo fi(m_filename);
    QString dirname = fi.path();
    QString basename = QString("%1.%2").arg(fi.baseName()).arg(fi.completeSuffix());

    // There were mysterious stupid problems running tar xf in a separate
    // QProcess step, so screw it, let's just throw it into this script!
    out << "tar xzf \"" << basename << "\" || exit " << errorPoint++ << endl;

    // Decode FLAC files
    QStringList::const_iterator si;
    for (si = flacFiles.constBegin(); si != flacFiles.constEnd(); ++si) {
        QString o1 = (*si);

        // the file strings are things like xxx.wav.rgp.flac
        // without specifying the output file they will turn into xxx.wav.rgp.wav
        // thus it is best to specify the output as xxx.wav
        //
        // files from new project packages have rg-23324234.flac files, files
        // from old project packages have rg-2343242.wav.rgp.flac files, so we
        // want a robust solution to this one... QFileInfo::baseName() should
        // get it
        QFileInfo fi(o1);
        QString o2 = QString("%1/%2.wav").arg(fi.path()).arg(fi.baseName());

        // we'll eschew anything fancy or pretty in this disposable script and
        // just write a command on each line, terminating with an || exit n
        // which can be used to figure out at which point processing broke, for
        // cheap and easy error reporting without a lot of fancy stream wiring
        //
        // (let's just try escaping spaces &c. with surrounding " and see if
        // that is good enough)

RG_DEBUG << "flad -d " << o1 << " -o " << o2;

        out << "flac -d \"" <<  o1 << "\" -o \"" << o2 << "\" && rm \"" << o1 <<  "\" || exit " << errorPoint << endl;
        errorPoint++;
    }

    // Decode WavPack files
    for (si = wavpackFiles.constBegin(); si != wavpackFiles.constEnd(); ++si) {
        QString o = (*si);

        // NOTE: wvunpack -d means "delete the file if successful" not "decode"
        out << "wvunpack -d \"" <<  o << "\" || exit " << errorPoint << endl;
        errorPoint++;
    }

    m_script.close();

    // run the assembled script
    m_process = new QProcess;

    // set to the working directory extracted from m_filename above, as this is
    // was apparently the reason why tar always failed to do anything
    m_process->setWorkingDirectory(dirname);
    m_process->start("bash", QStringList() << scriptName);
    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(finishUnpack(int, QProcess::ExitStatus)));

    // wait up to 30 seconds for process to start
    m_info->setText(tr("Decoding audio files..."));
    if (!m_process->waitForStarted()) {
        puke(tr("<qt>Could not start backend processing script %1.</qt>").arg(scriptName));
        return;
    }
}
示例#19
0
void
ProjectPackager::startAudioEncoder(QStringList files)
{
    m_info->setText(tr("Packing project..."));

    // (we could do some kind of QProcess monitoring, but I'm feeling lazy at
    // the moment and this will at least make us look busy while we chew)
    // go into spinner mode
    m_progress->setMaximum(0);

    // we can't do a oneliner bash script straight out of a QProcess command
    // line, so we'll have to create a purpose built script and run that
    QString scriptName("/tmp/rosegarden-audio-encoder-backend");
    m_script.setFileName(scriptName);

    // remove any lingering copy from a previous run
    if (m_script.exists()) m_script.remove();

    if (!m_script.open(QIODevice::WriteOnly | QIODevice::Text)) {
        puke(tr("<qt><p>Unable to write to temporary backend processing script %1.</p>%2</qt>").arg(m_abortText));
        return;
    }
    
    // build the script
    QTextStream out(&m_script);
    out << "# This script was generated by Rosegarden to combine multiple external processing"      << endl
        << "# operations so they could be managed by a single QProcess.  If you find this script"   << endl
        << "# it is likely that something has gone terribly wrong. See http://rosegardenmusic.com" << endl;

    QStringList::const_iterator si;
    int errorPoint = 1;
    for (si = files.constBegin(); si != files.constEnd(); ++si) {
        QFileInfo fi(*si);
        QString filename = QString("%1.%2").arg(fi.baseName()).arg(fi.completeSuffix());
        QString o = QString("%1/%2").arg(m_packDataDirName).arg(filename);

        // we'll eschew anything fancy or pretty in this disposable script and
        // just write a command on each line, terminating with an || exit n
        // which can be used to figure out at which point processing broke, for
        // cheap and easy error reporting without a lot of fancy stream wiring
        out << "wavpack -d \"" << o << "\" || exit " << errorPoint << endl;
        errorPoint++;
    }

    // Throw tar on the ass end of this script and save an extra processing step
    //
    // first cheap trick, m_packDataDirName.rg is our boy and we know it
    QString rgFile = QString("%1.rg").arg(m_packDataDirName);

    // second cheap trick, don't make a tarball in tmpdir and move it, just
    // write it at m_filename and shazam, nuke the tmpdir behind us and peace out
    out << "tar czf \"" << m_filename << "\" " << rgFile.toLocal8Bit() << " " <<  m_packDataDirName.toLocal8Bit() <<  "/ || exit " << errorPoint++ << endl;

    m_script.close();

    // run the assembled script
    m_process = new QProcess;
    m_process->setWorkingDirectory(m_packTmpDirName);
    m_process->start("bash", QStringList() << scriptName);
    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)),
            this, SLOT(finishPack(int, QProcess::ExitStatus)));
}
示例#20
0
void Turret::shoot (bool playerControlled, Player* targetPlayer)
{
   if (data && data->isSustained == false) {
	   if (data && data->projectile.type == -1)
	   	{
	   		if (!isGhost())
	   			if (const char* script = scriptName("onFire"))
	   				Console->executef(2, script, scriptThis());
	   	}
	   else
	   	{
	   		float energy = getEnergy();
	   		if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1)
	   			{
                  TMat3F muzzleTransform;
	   				getMuzzleTransform(0, &muzzleTransform);
	   				Projectile* bullet = createProjectile(data->projectile);

	   				if (!playerControlled && data->deflection)
	   					{
	   						static Random random;
	   						EulerF angles;
	   					   muzzleTransform.angles (&angles);
	   						angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
	   						muzzleTransform.set (angles, muzzleTransform.p);
	   					}
	   				else
	   					if (playerControlled)
	   						{
	   							Point3F start = muzzleTransform.p;
	   							muzzleTransform = getEyeTransform ();
	   							aimedTransform (&muzzleTransform, start);
	   							muzzleTransform.p = start;
	   						}

	   				bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());

	   	         if (bullet->isTargetable() == true) {
	   	            if (targetPlayer != NULL) {
	   						if (GameBase* mo = targetPlayer->getMountObject())
	   		               bullet->setTarget(static_cast<ShapeBase*>(mo));
	   						else
	   		               bullet->setTarget(targetPlayer);
                     } else if (playerControlled) {
                        ShapeBase* pClosest   = NULL;
                        Point3F    closeHisPos;
                        float      closestVal = -2.0f;
                        SimSet::iterator itr;
                     
                        Point3F lookDir;
                        getEyeTransform().getRow(1, &lookDir);
                        lookDir.normalize();

                        SimContainerQuery collisionQuery;
                        SimCollisionInfo  info;
                        collisionQuery.id     = getId();
                        collisionQuery.type   = -1;
                        collisionQuery.mask   = Projectile::csm_collisionMask;
                        collisionQuery.detail = SimContainerQuery::DefaultDetail;
                        collisionQuery.box.fMin = getEyeTransform().p;
                        SimContainer* pRoot = (SimContainer*)manager->findObject(SimRootContainerId);

                        SimSet* pSet = dynamic_cast<SimSet*>(manager->findObject(PlayerSetId));
                        AssertFatal(pSet != NULL, "No player set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           Player* pPlayer = dynamic_cast<Player*>(*itr);

                           if (!pPlayer || pPlayer->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pPlayer->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pPlayer)
                                 continue;
                           }

                           Point3F hisPos = pPlayer->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              pClosest   = pPlayer;
                              closeHisPos = hisPos;
                           }
                        }

                        pSet = dynamic_cast<SimSet*>(manager->findObject(MoveableSetId));
                        AssertFatal(pSet != NULL, "No moveable set?");
                        for (itr = pSet->begin(); itr != pSet->end(); itr++) {
                           if (((*itr)->getType() & VehicleObjectType) == 0)
                              continue;

                           ShapeBase* pObject = dynamic_cast<ShapeBase*>(*itr);
                           
                           if (pObject->getVisibleToTeam(getTeam()) == false)
                              continue;

                           collisionQuery.box.fMax = pObject->getBoxCenter();
                           if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) {
                              if (info.object != (SimObject*)pObject)
                                 continue;
                           }

                           Point3F hisPos = pObject->getBoxCenter();
                           hisPos -= getLinearPosition();
                           hisPos.normalize();

                           float prod = m_dot(hisPos, lookDir);
                           if (prod > 0.0f && prod > closestVal) {
                              closestVal = prod;
                              closeHisPos = hisPos;
                              pClosest   = pObject;
                           }
                        }

                        // We need to find the current FOV, and take the percentage of
                        //  it specified in the .dat file for this turret.  Only if the
                        //  do product is greater than this, do we allow the target to
                        //  be set...
                        //
                        float myFov   = (fov / 2.0) * data->targetableFovRatio;
                        float compCos = cos(myFov);
                        if (compCos > 0.996f)   // hack for single precision math.  It's very
                           compCos = 0.996;     // hard to get more precise answers from the dot prod.

                        if (pClosest != NULL && closestVal > compCos)
                           bullet->setTarget(pClosest);
                     }
                  }

	   				if (data->maxGunEnergy)
	   					{
	   						float e;
	   						e = energy > data->maxGunEnergy ? data->maxGunEnergy : energy;

                        float pofm = e / float(data->maxGunEnergy);

	   						bullet->setEnergy (e, pofm);

	   						energy -= e;
	   						setEnergy (energy);
	   					}

                  SimGroup *grp = NULL;
                  if(SimObject *obj = manager->findObject("MissionCleanup"))
                     grp = dynamic_cast<SimGroup*>(obj);
                  if(!manager->registerObject(bullet))
                     delete bullet;
                  else
                  {
                     if(grp)
                        grp->addObject(bullet);
                     else
                        manager->addObject(bullet);
                  }

	   				waitTime = manager->getCurrentTime() + data->reloadDelay;

	   				if (animThread)
	   					{
	   						setFireThread ();
	   						animThread->SetPosition (0.0);
	   					}
	   				
	   				fireCount++;
	   				setMaskBits (ShootingMask);
	   			}
	   	}
   } else {
      if (data && data->projectile.type == -1) {
         if (!isGhost())
            if (const char* script = scriptName("onFire"))
               Console->executef(2, script, scriptThis());
      }
      else {
         float energy = getEnergy();
         if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1) {
            TMat3F muzzleTransform;
            getMuzzleTransform(0, &muzzleTransform);
            Projectile* bullet = createProjectile(data->projectile);

            if (!playerControlled && data->deflection) {
               static Random random;
               EulerF angles;
               muzzleTransform.angles (&angles);
               angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection;
               muzzleTransform.set (angles, muzzleTransform.p);
            } else if (playerControlled) {
               Point3F start = muzzleTransform.p;
               muzzleTransform = getEyeTransform ();
               aimedTransform (&muzzleTransform, start);
               muzzleTransform.p = start;
            }

            bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId());
            AssertFatal(bullet->isSustained() == true, "Error, must be sustained bullet");
            SimGroup *grp = NULL;
            if(SimObject *obj = manager->findObject("MissionCleanup"))
               grp = dynamic_cast<SimGroup*>(obj);
            if(!manager->registerObject(bullet))
               delete bullet;
            else
            {
               if(grp)
                  grp->addObject(bullet);
               else
                  manager->addObject(bullet);
            }

            if (animThread) {
               setFireThread ();
               animThread->SetPosition (0.0);
            }
            
            fireCount++;
            setMaskBits (ShootingMask);

            m_fireState  = Firing;
            m_beganState = wg->currentTime;

            m_pProjectile = bullet;
            m_pTarget     = targetPlayer;
            
            if (m_pTarget)
               deleteNotify(m_pTarget);
         }
      }
   }
}
示例#21
0
void Turret::updateMove (PlayerMove *move, float interval)
{
   if (data->isSustained == false) {
	   if (getControlClient() && state != EXTENDED)
	   	{
	   		if (!isGhost())
	   			extend (interval);
	   	}

		if (state != EXTENDED)
			move = NULL;

	   float oTR = turretRotation;
	   float oTE = turretElevation;

	   if (move && (!animThread || animThread->getPriority() != -1 ||
	   		animThread->getPosition() >= 1.0))
	   	{
#if 0
	   		float maxSpeed = data->speed * data->speedModifier * interval;
	   		float moveFrac = interval * 32;
#else
	   		float maxSpeed = data->speed * data->speedModifier;
	   		float moveFrac = interval * 16;
#endif
	   		float pitch = m_clamp(move->pitch,-maxSpeed,maxSpeed);
	   		float turn = m_clamp(move->turnRot,-maxSpeed,maxSpeed);
	   		turretElevation += pitch * moveFrac;
	   		turretRotation += turn * moveFrac;

	   		wrapElevation ();
	   		if (maxElevation != minElevation)
	   			{
	   				if (turretElevation > maxElevation)
	   					turretElevation = maxElevation;
	   			
	   				if (turretElevation < minElevation)
	   					turretElevation = minElevation;
	   			}
	
	   		wrapRotation ();
	   		if (maxRotation != minRotation)
	   			{
	   				if (turretRotation > maxRotation)
	   					turretRotation = maxRotation;
	   			
	   				if (turretRotation < minRotation)
	   					turretRotation = minRotation;
	   			}
	   	
	   		if (move->trigger)
	   			{
	   				if (!isGhost ())
	   					shoot (true);
	   			}
	   	
	   		if (move->jumpAction && !isGhost())
            {
               const char *fn = scriptName("jump");
               if(fn)
                  Console->executef(2, fn, scriptThis());
            }
	   	}

	   if (elevationThread && maxElevation != minElevation)
	   	elevationThread->SetPosition ((turretElevation - minElevation) / (maxElevation - minElevation));
	   	
	   if (rotationThread)
	   	{
	   		if (!isEqual (maxRotation, minRotation))
	   			rotationThread->SetPosition ((turretRotation - minRotation) / (maxRotation - minRotation));
	   		else
	   			rotationThread->SetPosition (turretRotation / M_2PI);
	   	}

	   // this is for the firing anim...
	   if (animThread && state == EXTENDED)
	   	animThread->AdvanceTime (interval);

	   // this is for the power anim...
	   if (animThread && isGhost())
	   	{
	   		if (state == EXTENDING)
	   			extend (interval);
	   		else
	   			if (state == RETRACTING)
	   				retract (interval);
	   	}

	   if (!isGhost ())
	   	{
	   		// Need to animate on the server to get the
	   		// node transforms.
	   		image.shape->animate ();

	   		if (oTE != turretElevation)
	   			setMaskBits (ElevationMask);
	   		if (oTR != turretRotation)
	   			setMaskBits (TRotationMask);
	   	}

	} else {
	   if (getControlClient() && state != EXTENDED) {
	      if (!isGhost())
	         extend (interval);
	   }

		if (state != EXTENDED)
			move = NULL;

	   float oTR = turretRotation;
	   float oTE = turretElevation;

	   if (move && (!animThread || animThread->getPriority() != -1 ||
	   		animThread->getPosition() >= 1.0))
	   {
	   	float maxSpeed = data->speed * interval;
	   	float pitch = m_clamp(move->pitch,-maxSpeed,maxSpeed);
	   	float turn = m_clamp(move->turnRot,-maxSpeed,maxSpeed);
	   	float moveFrac = interval * 32;
	   	turretElevation += pitch * moveFrac;
	   	turretRotation += turn * moveFrac;

	   	wrapElevation ();
	   	if (maxElevation != minElevation) {
	   		if (turretElevation > maxElevation)
	   			turretElevation = maxElevation;
	   	
	   		if (turretElevation < minElevation)
	   			turretElevation = minElevation;
	   	}
	
	   	wrapRotation ();
	   	if (maxRotation != minRotation) {
	   		if (turretRotation > maxRotation)
	   			turretRotation = maxRotation;
	   	
	   		if (turretRotation < minRotation)
	   			turretRotation = minRotation;
	   	}
	
	   	if (move->trigger && m_fireState == Waiting) {
	   		if (!isGhost ())
	   			shoot(true, NULL);
	   	} else if (!move->trigger && m_fireState == Firing) {
	   		if (!isGhost())
	   			unshoot();
         }
	
	   	if (move->jumpAction && !isGhost()) {
            if (m_fireState == Firing)
               unshoot();

            const char *fn = scriptName("jump");
            if(fn)
               Console->executef(2, fn, scriptThis());
         }
	   }

	   if (elevationThread && maxElevation != minElevation)
	   	elevationThread->SetPosition ((turretElevation - minElevation) / (maxElevation - minElevation));
	   	
	   if (rotationThread) {
	   	if (!isEqual (maxRotation, minRotation))
	   		rotationThread->SetPosition ((turretRotation - minRotation) / (maxRotation - minRotation));
	   	else
	   		rotationThread->SetPosition (turretRotation / M_2PI);
	   }

	   // this is for the firing anim...
	   if (animThread && state == EXTENDED)
	   	animThread->AdvanceTime (interval);

	   // this is for the power anim...
	   if (animThread && isGhost()) {
	   	if (state == EXTENDING)
	   		extend (interval);
	   	else if (state == RETRACTING)
	   	   retract (interval);
	   }

	   if (!isGhost ()) {
	   	// Need to animate on the server to get the
	   	// node transforms.
	   	image.shape->animate ();

	   	if (oTE != turretElevation)
	   		setMaskBits (ElevationMask);
	   	if (oTR != turretRotation)
	   		setMaskBits (TRotationMask);
	   }
   }
}
示例#22
0
bool CDialogLoader::ProcessScript(IMScript& script, const string& groupName, TDialogScriptMap& outScriptMap)
{
#if 0
	DiaLOG::Log(DiaLOG::eAlways, "Script: %s with %d lines", script.name, script.lines.size());
	for (int i=0; i<script.lines.size(); ++i)
	{
		IMScriptLine& line = script.lines[i];
		DiaLOG::Log(DiaLOG::eAlways, "actor=%s sound=%s anim=%s facial=%s lookat=%s delay=%f",
			line.actor,line.sound,line.anim,line.facial,line.lookat,line.delay);
	}
#endif

	string scriptName (groupName);
	scriptName+=".";
	scriptName+=script.name;

	if (script.lines.empty())
	{
		GameWarning("[DIALOG] CDialogLoader::ProcessScript: DialogScript '%s' has no lines. Discarded.", scriptName.c_str());
		return false;
	}

	CDialogScript* pScript = new CDialogScript(scriptName);
	pScript->SetVersionFlags(CDialogScript::VF_EXCEL_BASED, true);

	bool bDiscard = false;
	int nLine = 1;
	std::vector<IMScriptLine>::iterator iter = script.lines.begin();
	std::vector<IMScriptLine>::iterator end = script.lines.end();

	string animName;

	for (; iter != end; ++iter, ++nLine)
	{
		// process the line
		const IMScriptLine& line = *iter;
		int actor  = 0;
		int lookAt = 0;

		// Actor
		if (!GetActor(line.actor, actor))
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Line %d: Cannot parse 'Actor' statement. Discarding.", scriptName.c_str(), nLine);
			break;
		}
		if (actor < 1 || actor > CDialogScript::MAX_ACTORS)
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Line %d: Actor%d given. Must be within [1..%d]. Discarding.", scriptName.c_str(), nLine, actor, CDialogScript::MAX_ACTORS);				
			break;
		}

		bool bUseAGEP = false;
		bool bUseAGSignal = false;
		bool bSoundStopsAnim = false;

		const char* lineAnimName = line.anim;
		if (CryStringUtils::stristr(lineAnimName, "ex_") == lineAnimName)
		{
			// use AG Exact Positioning
			bUseAGEP = true;
			lineAnimName+=3;

			if (*lineAnimName == 0)
			{
				bDiscard = true;
				GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Line %d: Invalid AnimName '%s'. Discarding", scriptName.c_str(), nLine, line.anim);				
				break;
			}
		}

		if (lineAnimName[0] == '$')
		{
			// use AG Signal
			bUseAGSignal = true;
			++lineAnimName;

			if (*lineAnimName == 0)
			{
				bDiscard = true;
				GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Line %d: Invalid AnimName '%s'. Discarding", scriptName.c_str(), nLine, line.anim);				
				break;
			}
		}

		int animNameLen = strlen(lineAnimName);
		if (animNameLen >= 2 && lineAnimName[animNameLen-1] == '$')
		{
			bSoundStopsAnim = true;
			--animNameLen;
		}
		animName.assign (lineAnimName, animNameLen);

		// LookAtTarget
		bool bLookAtGiven = line.lookat && line.lookat[0] != '\0';
		bool bLookAtSticky = false;
		bool bResetLookAt = false;
		if (bLookAtGiven && CryStringUtils::stristr(line.lookat, "$reset") != 0)
		{
			bResetLookAt = true;
			bLookAtGiven = false;
		}
		else if (bLookAtGiven && !GetLookAtActor(line.lookat, lookAt, bLookAtSticky))
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript: %s Line %d: Cannot parse 'LookAtTarget' statement. Discarding.", scriptName.c_str(), nLine);
			break;
		}
		if (bLookAtGiven && (lookAt < 1 || lookAt > CDialogScript::MAX_ACTORS))
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Line %d: LookAtTarget Actor%d given. Must be within [1..%d]. Discarding.", scriptName.c_str(), nLine, lookAt, CDialogScript::MAX_ACTORS);				
			break;
		}

		const char* facialExpression = line.facial.c_str();
		bool bResetFacial = false;
		if (CryStringUtils::stristr(facialExpression, "$reset") != 0)
		{
			bResetFacial = true;
			facialExpression = "";
		}

		const CDialogScript::TActorID actorID  = static_cast<CDialogScript::TActorID> (actor-1);
		const CDialogScript::TActorID lookAtID = lookAt <= 0 ? CDialogScript::NO_ACTOR_ID : static_cast<CDialogScript::TActorID> (lookAt-1);
		const bool bSuccess = pScript->AddLine(actorID, line.audioID, animName.c_str(), facialExpression, lookAtID, line.delay, line.facialWeight, line.facialFadeTime, bLookAtSticky, bResetFacial, bResetLookAt, bSoundStopsAnim, bUseAGSignal, bUseAGEP);
		if (!bSuccess)
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Cannot add line %d. Discarding", scriptName.c_str(), nLine);
			break;
		}
	}

	if (bDiscard == false)
	{
		// try to complete the script
		if (pScript->Complete() == true)
		{
			// add it to the map
			std::pair<TDialogScriptMap::iterator, bool> inserted = 
				outScriptMap.insert(TDialogScriptMap::value_type(pScript->GetID(), pScript));
			if (inserted.second == false)
			{
				bDiscard = true;
				GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Script already defined. Discarded", scriptName.c_str());				
			}
		}
		// completion not successful -> discard
		else
		{
			bDiscard = true;
			GameWarning("[DIALOG] CDialogLoader::ProcessScript '%s': Cannot complete Script. Discarded.", scriptName.c_str());
		}
	}

	// discard pScript
	if (bDiscard)
	{
		delete pScript;
	}

	return bDiscard == false;
}
示例#23
0
bool transferSysFiles( Options &options, bool bJustScript )
{
   Path binpath, libpath;

   // Under windows, the binary path is usually stored in an envvar.

   String envpath;
   if ( ! Sys::_getEnv( "FALCON_BIN_PATH", envpath ) || envpath == "" )
      envpath = FALCON_DEFAULT_BIN;

   binpath.setFullLocation(
      options.m_sFalconBinDir != "" ? options.m_sFalconBinDir: envpath );
   // copy falcon or falrun
   if ( options.m_sRunner != "" )
      binpath.setFilename( options.m_sRunner );
   else
      binpath.setFilename( "falcon.exe" );

   // our dlls are in bin, under windows.
   libpath.setFullLocation(
         options.m_sFalconLibDir != "" ? options.m_sFalconLibDir : envpath );

   if ( ! bJustScript )
   {
      Path tgtpath( options.m_sTargetDir + "/" + options.m_sSystemRoot +"/" );

      libpath.setFile( "falcon_engine" );
      libpath.setExtension( DllLoader::dllExt() );

      tgtpath.setFilename( binpath.getFilename() );
      if( ! copyFile( binpath.get(), tgtpath.get() ) )
      {
         warning( "Can't copy system file \"" + binpath.get()
               + "\" into target path \""+ tgtpath.get()+ "\"" );
         // but continue
      }

      tgtpath.setFilename( libpath.getFilename() );
      if( ! copyFile( libpath.get(), tgtpath.get() ) )
      {
         warning( "Can't copy system file \"" + libpath.get()
               + "\" into target path \""+ tgtpath.get()+ "\"" );
         // but continue
      }

      // and now the visual C runtime, if any
      copyRuntime( binpath, tgtpath );
   }

   // now create the startup script
   Path mainScriptPath( options.m_sMainScript );
   Path scriptPath( options.m_sTargetDir + "/" + mainScriptPath.getFile() + ".bat" );

   message( "Creating startup script \"" + scriptPath.get() + "\"" );
   FileStream startScript;
   if( ! startScript.create( scriptPath.get(), (BaseFileStream::t_attributes) 0777 ) )
   {
      error( "Can't create startup script \"" + scriptPath.get() + "\"" );
      return false;
   }

   startScript.writeString( 
      "@ECHO OFF\r\n"
      "set OLD_DIR=%CD%\r\n"
      "set target_dir=%~dp0\r\n"
      "cd %target_dir%\r\n");
   
   if( bJustScript )
   {
      startScript.writeString( "\"" + binpath.getFilename() + "\" " );
   }
   else
   {
      startScript.writeString( "   \""+options.m_sSystemRoot + "\\" + binpath.getFilename() + "\" " );
      startScript.writeString( "    -L \"" + options.m_sSystemRoot +";.\" " );
   }

   // we need to discard the extension, so that the runner decides how to run the program.
   Path scriptName( options.m_sMainScript );
   startScript.writeString( " \"" + scriptName.getFile() +"\" \"%*\"\r\n" );
   
   startScript.writeString( "cd %OLD_DIR%\r\n" );
   startScript.flush();

   return true;
}
示例#24
0
//-------------------------------------------------------------------------------------
void Proxy::giveClientTo(Proxy* proxy)
{
	if(isDestroyed())
	{
		char err[255];																				
		kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: %d is destroyed.", 
			scriptName(), id());			

		PyErr_SetString(PyExc_TypeError, err);														
		PyErr_PrintEx(0);	
		onGiveClientToFailure();
		return;
	}

	if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL)
	{
		char err[255];																				
		kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", scriptName());			
		PyErr_SetString(PyExc_TypeError, err);														
		PyErr_PrintEx(0);	
		onGiveClientToFailure();
		return;
	}

	Mercury::Channel* lpChannel = clientMailbox_->getChannel();

	if(proxy)
	{
		if(proxy->isDestroyed())
		{
			char err[255];																				
			kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is destroyed.", 
				scriptName(), proxy->id());			

			PyErr_SetString(PyExc_TypeError, err);														
			PyErr_PrintEx(0);	
			onGiveClientToFailure();
			return;
		}

		if(proxy->id() == this->id())
		{
			char err[255];																				
			kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is self.", 
				scriptName(), proxy->id());			

			PyErr_SetString(PyExc_TypeError, err);														
			PyErr_PrintEx(0);	
			onGiveClientToFailure();
			return;
		}

		EntityMailbox* mb = proxy->clientMailbox();
		if(mb != NULL)
		{
			ERROR_MSG(boost::format("Proxy::giveClientTo: %1%[%2%] give client to %3%[%4%], %5% has clientMailbox.\n") % 
					scriptName() %
					id() %
					proxy->scriptName() % 
					proxy->id() %
					proxy->scriptName());

			onGiveClientToFailure();
			return;
		}

		if(cellMailbox())
		{
			// 通知cell丢失客户端
			Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
			(*pBundle).newMessage(CellappInterface::onResetWitness);
			(*pBundle) << this->id();
			sendToCellapp(pBundle);
		}

		entitiesEnabled_ = false;
		clientMailbox()->addr(Mercury::Address::NONE);
		Py_DECREF(clientMailbox());
		proxy->onGiveClientTo(lpChannel);
		clientMailbox(NULL);
		addr(Mercury::Address::NONE);
		
		if(proxy->clientMailbox() != NULL)
		{
			// 通知client销毁当前entity
			Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
			(*pBundle).newMessage(ClientInterface::onEntityDestroyed);
			(*pBundle) << this->id();
			proxy->sendToClient(ClientInterface::onEntityDestroyed, pBundle);
			//Mercury::Bundle::ObjPool().reclaimObject(pBundle);
		}
	}
}
示例#25
0
//-------------------------------------------------------------------------------------
void Proxy::giveClientTo(Proxy* proxy)
{
	if(isDestroyed())
	{
		char err[255];																				
		kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: %d is destroyed.", 
			scriptName(), id());			

		PyErr_SetString(PyExc_TypeError, err);														
		PyErr_PrintEx(0);	
		onGiveClientToFailure();
		return;
	}

	if(clientMailbox_ == NULL || clientMailbox_->getChannel() == NULL)
	{
		char err[255];																				
		kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: no has client.", scriptName());			
		PyErr_SetString(PyExc_TypeError, err);														
		PyErr_PrintEx(0);	
		onGiveClientToFailure();
		return;
	}

	Network::Channel* lpChannel = clientMailbox_->getChannel();

	if(proxy)
	{
		if(proxy->isDestroyed())
		{
			char err[255];																				
			kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is destroyed.", 
				scriptName(), proxy->id());			

			PyErr_SetString(PyExc_TypeError, err);														
			PyErr_PrintEx(0);	
			onGiveClientToFailure();
			return;
		}

		if(proxy->id() == this->id())
		{
			char err[255];																				
			kbe_snprintf(err, 255, "Proxy[%s]::giveClientTo: target(%d) is self.", 
				scriptName(), proxy->id());			

			PyErr_SetString(PyExc_TypeError, err);														
			PyErr_PrintEx(0);	
			onGiveClientToFailure();
			return;
		}

		EntityMailbox* mb = proxy->clientMailbox();
		if(mb != NULL)
		{
			ERROR_MSG(fmt::format("Proxy::giveClientTo: {}[{}] give client to {}[{}], {} has clientMailbox.\n", 
					scriptName(),
					id(),
					proxy->scriptName(), 
					proxy->id(),
					proxy->scriptName()));

			onGiveClientToFailure();
			return;
		}

		if(cellMailbox())
		{
			// 当前这个entity如果有cell,说明已经绑定了witness, 那么既然我们将控制权
			// 交换给了另一个entity, 这个entity需要解绑定witness。
			// 通知cell丢失witness
			Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
			(*pBundle).newMessage(CellappInterface::onLoseWitness);
			(*pBundle) << this->id();
			sendToCellapp(pBundle);
		}

		// 既然客户端失去对其的控制, 那么通知client销毁这个entity
		Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
		(*pBundle).newMessage(ClientInterface::onEntityDestroyed);
		(*pBundle) << this->id();
		sendToClient(ClientInterface::onEntityDestroyed, pBundle);

		// 将控制权交换
		entitiesEnabled_ = false;
		clientMailbox()->addr(Network::Address::NONE);
		Py_DECREF(clientMailbox());
		proxy->setClientType(this->getClientType());
		proxy->setClientDatas(this->getClientDatas());
		this->setClientType(UNKNOWN_CLIENT_COMPONENT_TYPE);
		this->setClientDatas("");
		clientMailbox(NULL);
		proxy->onGiveClientTo(lpChannel);
		addr(Network::Address::NONE);
	}
}
示例#26
0
void CharCreationManager::HandleUploadMessage(MsgEntry* me, Client* client)
{
    Debug1(LOG_NEWCHAR, me->clientnum,"New Character is being created");

    psCharUploadMessage upload(me);

    if(!upload.valid)
    {
        Debug2(LOG_NET,me->clientnum,"Received unparsable psUploadMessage from client %u.",me->clientnum);
        return;
    }

    AccountID acctID = client->GetAccountID();
    if(!acctID.IsValid())
    {
        Error2("Player tried to upload a character to unknown account %s.", ShowID(acctID));

        psCharRejectedMessage reject(me->clientnum);

        psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET);
        psserver->RemovePlayer(me->clientnum,"Could not find your account.");
        return;
    }

    // Check to see if the player already has 4 accounts;
    csString query;
    query.Format("SELECT id FROM characters WHERE account_id=%d", acctID.Unbox());
    Result result(db->Select(query));
    if(result.IsValid() && result.Count() >= CHARACTERS_ALLOWED)
    {
        psserver->RemovePlayer(me->clientnum,"At your character limit.");
        return;
    }

    csString playerName =  upload.name;
    csString lastName =  upload.lastname;

    playerName = NormalizeCharacterName(playerName);
    lastName = NormalizeCharacterName(lastName);

    // Check banned names
    if(psserver->GetCharManager()->IsBanned(playerName))
    {
        csString error;
        error.Format("The name %s is banned", playerName.GetData());
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::RESERVED_NAME,
                                     (char*)error.GetData());
        reject.SendMessage();
        return;
    }

    if(psserver->GetCharManager()->IsBanned(lastName))
    {
        csString error;
        error.Format("The lastname %s is banned", lastName.GetData());
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::RESERVED_NAME,
                                     (char*)error.GetData());
        reject.SendMessage();
        return;
    }

    Debug3(LOG_NEWCHAR, me->clientnum,"Got player firstname (%s) and lastname (%s)\n",playerName.GetData(), lastName.GetData());

    ///////////////////////////////////////////////////////////////
    //  Check to see if the player name is valid
    ///////////////////////////////////////////////////////////////
    if(playerName.Length() == 0 || !FilterName(playerName))
    {
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::NON_LEGAL_NAME,
                                     "The name you specifed is not a legal player name.");

        psserver->GetEventManager()->SendMessage(reject.msg);
        return;
    }

    if(lastName.Length() != 0 && !FilterName(lastName))
    {
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::NON_LEGAL_NAME,
                                     "The name you specifed is not a legal lastname.");

        psserver->GetEventManager()->SendMessage(reject.msg);
        return;
    }

    Debug2(LOG_NEWCHAR, me->clientnum,"Checking player firstname '%s'..\n",playerName.GetData());
    ///////////////////////////////////////////////////////////////
    //  Check to see if the character name is unique in 'characters'.
    ///////////////////////////////////////////////////////////////
    if(!IsUnique(playerName))
    {
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::NON_UNIQUE_NAME,
                                     "The firstname you specifed is not unique.");

        psserver->GetEventManager()->SendMessage(reject.msg);
        return;
    }

    if(lastName.Length())
    {
        Debug2(LOG_NEWCHAR, me->clientnum,"Checking player lastname '%s'..\n",lastName.GetData());
        if(!IsLastNameAvailable(lastName, acctID))
        {
            psCharRejectedMessage reject(me->clientnum,
                                         psCharRejectedMessage::NON_UNIQUE_NAME,
                                         "The lastname you specifed is not unique.");

            psserver->GetEventManager()->SendMessage(reject.msg);
            return;
        }
    }
    ///////////////////////////////////////////////////////////////
    //  Check to see if the character name is on the reserve list.
    ///////////////////////////////////////////////////////////////
    int reservedName = IsReserved(playerName, acctID);
    if(reservedName == NAME_RESERVED)
    {
        csString error;
        error.Format("The name %s is reserved", playerName.GetData());
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::RESERVED_NAME,
                                     (char*)error.GetData());

        psserver->GetEventManager()->SendMessage(reject.msg);
        return;
    }


    csString error;
    if(!psserver->charCreationManager->Validate(upload, error))
    {
        error.Append(", your creation choices are invalid.");
        psCharRejectedMessage reject(me->clientnum,
                                     psCharRejectedMessage::INVALID_CREATION,
                                     (char*)error.GetData());

        reject.SendMessage();
        return;
    }

    ///////////////////////////////////////////////////////////////
    //  Create the psCharacter structure for the player.
    ///////////////////////////////////////////////////////////////
    psCharacter* chardata=new psCharacter();
    chardata->SetCharType(PSCHARACTER_TYPE_PLAYER);
    chardata->SetFullName(playerName,lastName);
    chardata->SetCreationInfo(upload.bio);

    psRaceInfo* raceinfo=psserver->GetCacheManager()->GetRaceInfoByNameGender(upload.race, (PSCHARACTER_GENDER)upload.gender);
    if(raceinfo==NULL)
    {
        Error3("Invalid race/gender combination on character creation:  Race='%d' Gender='%d'", upload.race, upload.gender);
        psCharRejectedMessage reject(me->clientnum);
        psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET);
        psserver->RemovePlayer(me->clientnum,"Player tried to create an invalid race/gender.");
        delete chardata;
        return;
    }
    chardata->SetRaceInfo(raceinfo);
    chardata->SetHitPoints(50.0);
    chardata->GetMaxHP().SetBase(0.0);
    chardata->GetMaxMana().SetBase(0.0);

    //range is unused here
    float x,y,z,yrot,range;
    const char* sectorname;
    InstanceID newinstance = DEFAULT_INSTANCE;

    //get the option entries for tutorial from the server options. Note it's tutorial:variousdata
    optionEntry* tutorialEntry = psserver->GetCacheManager()->getOptionSafe("tutorial","");
    sectorname = tutorialEntry->getOptionSafe("sectorname", "tutorial")->getValue();

    psSectorInfo* sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName(sectorname);

    if(!sectorinfo || PlayerHasFinishedTutorial(acctID, sectorinfo->uid))
    {
        raceinfo->GetStartingLocation(x,y,z,yrot,range,sectorname);
        sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName(sectorname);

        //As we aren't going in the tutorial disable the tutorial help messages disable them
        for(int i = 0; i < TutorialManager::TUTOREVENTTYPE_COUNT; i++)
            chardata->CompleteHelpEvent(i);
    }
    else
    {
        // Try tutorial level first.
        x = tutorialEntry->getOptionSafe("sectorx", "-225.37")->getValueAsDouble();
        y = tutorialEntry->getOptionSafe("sectory", "-21.32")->getValueAsDouble();
        z = tutorialEntry->getOptionSafe("sectorz", "26.79")->getValueAsDouble();
        yrot = tutorialEntry->getOptionSafe("sectoryrot", "-2.04")->getValueAsDouble();
    }

    bool sectorFound = true;

    if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name) == NULL)
    {
        Error2("Sector='%s' found but no map file was detected for it. Using NPCroom1", sectorname);
        sectorinfo = psserver->GetCacheManager()->GetSectorInfoByName("NPCroom1");
        if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name) == NULL)
        {
            Error1("NPCroom1 failed - Critical");
            sectorFound = false;
        }
        else if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name))
        {
            sectorFound = true;
        }
        else
        {
            sectorFound = false;
        }
    }
    else if(sectorinfo && EntityManager::GetSingleton().FindSector(sectorinfo->name))
    {
        sectorFound = true;
    }
    else
    {
        sectorFound = false;
    }


    if(!sectorFound)
    {
        Error2("Unresolvable starting sector='%s'", sectorname);
        psCharRejectedMessage reject(me->clientnum);
        psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET);
        psserver->RemovePlayer(me->clientnum,"No starting Sector.");
        delete chardata;
        return;
    }

    chardata->SetLocationInWorld(newinstance, sectorinfo, x, y, z, yrot);

    psTrait* trait;
//    CPrintf(CON_DEBUG, "Trait: %d\n", upload.selectedFace );
    trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedFace);
    if(trait)
        chardata->SetTraitForLocation(trait->location, trait);

    trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedHairStyle);
    if(trait)
        chardata->SetTraitForLocation(trait->location, trait);

    trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedBeardStyle);
    if(trait)
        chardata->SetTraitForLocation(trait->location, trait);

    trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedHairColour);
    if(trait)
        chardata->SetTraitForLocation(trait->location, trait);

    trait = psserver->GetCacheManager()->GetTraitByID(upload.selectedSkinColour);
    if(trait)
        chardata->SetTraitForLocation(trait->location, trait);

    gemActor* actor = new gemActor(gemSupervisor, cacheManager, entityManager, chardata,
                                   raceinfo->mesh_name,
                                   newinstance,
                                   EntityManager::GetSingleton().FindSector(sectorinfo->name),
                                   csVector3(x,y,z),yrot,
                                   client->GetClientNum());

    actor->SetupCharData();

    if(!upload.verify)
    {
        if(!psServer::CharacterLoader.NewCharacterData(acctID,chardata))
        {
            Error1("Character could not be created.");
            psCharRejectedMessage reject(me->clientnum);
            psserver->GetEventManager()->Broadcast(reject.msg, NetBase::BC_FINALPACKET);
            psserver->RemovePlayer(me->clientnum,"Your character could not be created in the database.");
            delete chardata;
            return;
        }
    }

    // Check to see if a path name was set. If so we will use that to generate
    // the character starting stats and skills.
    if(upload.path != "None")
    {
        // Progression Event name is PATH_PathName
        csString name("PATH_");
        name.Append(upload.path);
        ProgressionScript* script = psserver->GetProgressionManager()->FindScript(name.GetData());
        if(script)
        {
            // The script uses the race base character points to calculate starting stats.
            MathEnvironment env;
            env.Define("CharPoints", raceinfo->initialCP);
            env.Define("Actor", actor);
            script->Run(&env);
        }
    }
    else
    {
        //int cpUsage = psserver->charCreationManager->CalculateCPChoice( upload.choices ) +
        //              psserver->charCreationManager->CalculateCPLife(upload.lifeEvents );
        for(size_t ci = 0; ci < upload.choices.GetSize(); ci++)
        {
            CharCreationManager::CreationChoice* choice = psserver->charCreationManager->FindChoice(upload.choices[ci]);
            if(choice)
            {
                csString name(psserver->charCreationManager->FindChoice(upload.choices[ci])->name.GetData());
                Debug3(LOG_NEWCHAR, me->clientnum,"Choice: %s Creation Script: %s", name.GetData(), choice->eventScript.GetData());

                MathEnvironment env;
                env.Define("Actor", actor);
                if(choice->choiceArea == FATHER_JOB || choice->choiceArea == MOTHER_JOB)
                {
                    int modifier = (choice->choiceArea == FATHER_JOB) ? upload.fatherMod : upload.motherMod;
                    if(modifier > 3 || modifier < 1)
                        modifier = 1;

                    env.Define("ParentStatus", modifier);
                }
                ProgressionScript* script = psserver->GetProgressionManager()->FindScript(choice->eventScript);
                if(script)
                    script->Run(&env);
            }
            else
            {
                Debug2(LOG_NEWCHAR, me->clientnum,"Character Choice %d not found\n", upload.choices[ci]);
            }
        }
        for(size_t li = 0; li < upload.lifeEvents.GetSize(); li++)
        {
            MathEnvironment env;
            env.Define("Actor", actor);
            LifeEventChoiceServer* lifeEvent = psserver->charCreationManager->FindLifeEvent(upload.lifeEvents[li]);
            if(!lifeEvent)
            {
                Error2("No LifeEvent Script found: %d", upload.lifeEvents[li]);
                continue;
            }

            csString scriptName(lifeEvent->eventScript.GetData());
            Debug2(LOG_NEWCHAR, me->clientnum, "LifeEvent Script: %s", scriptName.GetDataSafe());

            ProgressionScript* script = psserver->GetProgressionManager()->FindScript(scriptName);
            if(script)
                script->Run(&env);
        }
    }

    if(!upload.verify)
    {

        if(reservedName == NAME_RESERVED_FOR_YOU)
        {
            AssignScript(chardata);
        }
        // This function recalculates the Max HP, Mana and Stamina of the new character
        chardata->RecalculateStats();

        // Make sure the new player have HP, Mana and Samina that was calculated
        chardata->SetHitPoints(chardata->GetMaxHP().Base());
        chardata->SetMana(chardata->GetMaxMana().Base());
        chardata->SetStamina(chardata->GetMaxPStamina().Base(),true);
        chardata->SetStamina(chardata->GetMaxMStamina().Base(),false);


        psServer::CharacterLoader.SaveCharacterData(chardata, actor);
        Debug1(LOG_NEWCHAR,me->clientnum,"Player Creation Complete");

        // Remove cached objects to make sure that the client gets a fresh character
        // list from the database if it logs out and in within 2 minutes.
        iCachedObject* obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("list",client->GetAccountID().Unbox()));
        if(obj)
        {
            obj->ProcessCacheTimeout();
            obj->DeleteSelf();
        }
        obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("auth",client->GetAccountID().Unbox()));
        if(obj)
        {
            obj->ProcessCacheTimeout();
            obj->DeleteSelf();
        }

        // Here everything is ok
        client->SetPID(chardata->GetPID());
        client->SetName(playerName);

        psCharApprovedMessage app(me->clientnum);
        if(app.valid)
            psserver->GetEventManager()->SendMessage(app.msg);
        else
            Bug2("Could not create valid psCharApprovedMessage for client %u.\n",me->clientnum);
    }
    else
    {
        psCharVerificationMesg mesg(me->clientnum);
        size_t z;
        //unfortunately count goes out of valid area so we need to check on charisma

        for(z = 0; z < psserver->GetCacheManager()->GetSkillAmount(); z++)
        {
            unsigned int rank = chardata->Skills().GetSkillRank((PSSKILL) z).Base();

            psSkillInfo* info = psserver->GetCacheManager()->GetSkillByID(z);
            csString name("Not found");
            if(info)
                name.Replace(info->name);

            if(rank > 0)
            {
                if(z >= PSSKILL_AGI && z <= PSSKILL_WILL)
                {
                    mesg.AddStat(rank, name);
                }
                else
                {
                    mesg.AddSkill(rank, name);
                }
            }
        }
        mesg.Construct();
        mesg.SendMessage();
    }

    delete actor;

    if(!upload.verify)
    {
        // Remove char data from the cache
        iCachedObject* obj = psserver->GetCacheManager()->RemoveFromCache(psserver->GetCacheManager()->MakeCacheName("char", chardata->GetPID().Unbox()));
        if(obj)
        {
            obj->ProcessCacheTimeout();
            obj->DeleteSelf();
        }
    }
}