//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CBKeyboardState::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// IsKeyDown
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(Name, "IsKeyDown")==0)
	{
		Stack->CorrectParams(1);
		CScValue* val = Stack->Pop();
		int vKey;

		if (val->m_Type==VAL_STRING && strlen(val->GetString())>0)
		{
			char* str = val->GetString();
			if(str[0]>='A' && str[0]<='Z') str[0] += ('a' - 'A');
			vKey = (int)str[0];
		}
		else vKey = val->GetInt();

    	const Uint8* state = SDL_GetKeyboardState(NULL);
		SDL_Scancode scanCode = SDL_GetScancodeFromKey(VKeyToKeyCode(vKey));
		bool isDown = state[scanCode] > 0;

		Stack->PushBool(isDown);
		return S_OK;
	}

	else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
}
bool CScValue::SetProperty(const char* PropName, IWmeObject* Value)
{
    CScValue* Val = new CScValue(Game);
    Val->SetNative((CBScriptable*)Value);
    bool Ret =  SUCCEEDED(SetProp((char*)PropName, Val));
    delete Val;
    return Ret;
}
Exemple #3
0
void CScStack::Push(CScValue *Val) {
	m_SP++;

	if (m_SP < m_Values.GetSize()) {
		m_Values[m_SP]->Cleanup();
		m_Values[m_SP]->Copy(Val);
	} else {
		CScValue *val = new CScValue(Game);
		val->Copy(Val);
		m_Values.Add(val);
	}
}
Exemple #4
0
CSXFile::CSXFile(CBGame *inGame, CScStack *Stack): CBScriptable(inGame) {
	Stack->CorrectParams(1);
	CScValue *Val = Stack->Pop();

	m_Filename = NULL;
	if (!Val->IsNULL()) CBUtils::SetString(&m_Filename, Val->GetString());

	m_ReadFile = NULL;
	m_WriteFile = NULL;

	m_Mode = 0;
	m_TextMode = false;
}
char* CSXArray::ScToString()
{
	static char Dummy[32768];
	strcpy(Dummy, "");
	char PropName[20];
	for(int i=0; i<m_Length; i++){
		sprintf(PropName, "%d", i);
		CScValue* val = m_Values->GetProp(PropName);
		if(val){
			if(strlen(Dummy) + strlen(val->GetString()) < 32768){
				strcat(Dummy, val->GetString());
			}
		}

		if(i<m_Length-1 && strlen(Dummy)+1 < 32768) strcat(Dummy, ",");
	}
	return Dummy;
}
HRESULT CScValue::SetProp(char *Name, CScValue *Val, bool CopyWhole, bool SetAsConst)
{
    if(m_Type==VAL_VARIABLE_REF) return m_ValRef->SetProp(Name, Val);

    HRESULT ret = E_FAIL;
    if(m_Type==VAL_NATIVE && m_ValNative) {
        ret = m_ValNative->ScSetProperty(Name, Val);
    }

    if(FAILED(ret))
    {
        CScValue* val = NULL;

        m_ValIter = m_ValObject.find(Name);
        if (m_ValIter != m_ValObject.end())
        {
            val = m_ValIter->second;
        }
        if(!val) val = new CScValue(Game);
        else val->Cleanup();

        val->Copy(Val, CopyWhole);
        val->m_IsConstVar = SetAsConst;
        m_ValObject[Name] = val;

        if(m_Type!=VAL_NATIVE) m_Type = VAL_OBJECT;

        /*
        m_ValIter = m_ValObject.find(Name);
        if (m_ValIter != m_ValObject.end()){
        	delete m_ValIter->second;
        	m_ValIter->second = NULL;
        }
        CScValue* val = new CScValue(Game);
        val->Copy(Val, CopyWhole);
        val->m_IsConstVar = SetAsConst;
        m_ValObject[Name] = val;

        if(m_Type!=VAL_NATIVE) m_Type = VAL_OBJECT;
        */
    }

    return S_OK;
}
Exemple #7
0
CSXDate::CSXDate(CBGame *inGame, CScStack *Stack): CBScriptable(inGame) {
	Stack->CorrectParams(6);

	memset(&m_tm, 0, sizeof(m_tm));

	CScValue *valYear = Stack->Pop();
	m_tm.tm_year = valYear->GetInt() - 1900;
	m_tm.tm_mon = Stack->Pop()->GetInt() - 1;
	m_tm.tm_mday = Stack->Pop()->GetInt();
	m_tm.tm_hour = Stack->Pop()->GetInt();
	m_tm.tm_min = Stack->Pop()->GetInt();
	m_tm.tm_sec = Stack->Pop()->GetInt();

	if (valYear->IsNULL()) {
		time_t TimeNow;
		time(&TimeNow);
		memcpy(&m_tm, localtime(&TimeNow), sizeof(m_tm));
	}

	mktime(&m_tm);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CBScriptHolder::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// DEBUG_CrashMe
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "DEBUG_CrashMe")==0)
	{
		Stack->CorrectParams(0);
		BYTE* p = 0;
		*p = 10;
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ApplyEvent
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "ApplyEvent")==0)
	{
		Stack->CorrectParams(1);
		CScValue* val = Stack->Pop();
		HRESULT ret;
		ret = ApplyEvent(val->GetString());

		if(SUCCEEDED(ret)) Stack->PushBool(true);
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// CanHandleEvent
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "CanHandleEvent")==0)
	{
		Stack->CorrectParams(1);
		Stack->PushBool(CanHandleEvent(Stack->Pop()->GetString()));

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// CanHandleMethod
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "CanHandleMethod")==0)
	{
		Stack->CorrectParams(1);
		Stack->PushBool(CanHandleMethod(Stack->Pop()->GetString()));

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AttachScript
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "AttachScript")==0)
	{
		Stack->CorrectParams(1);
		Stack->PushBool(SUCCEEDED(AddScript(Stack->Pop()->GetString())));
		
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DetachScript
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "DetachScript")==0)
	{
		Stack->CorrectParams(2);
		char* Filename = Stack->Pop()->GetString();
		bool KillThreads = Stack->Pop()->GetBool(false);
		bool ret = false;
		for(int i=0; i<m_Scripts.GetSize(); i++)
		{
			if(CBPlatform::stricmp(m_Scripts[i]->m_Filename, Filename)==0)
			{
				m_Scripts[i]->Finish(KillThreads);
				ret = true;
				break;
			}
		}
		Stack->PushBool(ret);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsScriptRunning
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "IsScriptRunning")==0)
	{
		Stack->CorrectParams(1);
		char* Filename = Stack->Pop()->GetString();
		bool ret = false;
		for(int i=0; i<m_Scripts.GetSize(); i++)
		{
			if(CBPlatform::stricmp(m_Scripts[i]->m_Filename, Filename)==0 && m_Scripts[i]->m_State!=SCRIPT_FINISHED && m_Scripts[i]->m_State!=SCRIPT_ERROR)
			{
				ret = true;
				break;
			}
		}
		Stack->PushBool(ret);

		return S_OK;
	}
	else return CBScriptable::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CAdTalkHolder::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{	
	//////////////////////////////////////////////////////////////////////////
	// SetSprite
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "SetSprite")==0){
		Stack->CorrectParams(1);

		CScValue* Val = Stack->Pop();

		bool SetCurrent = false;
		if(m_CurrentSprite && m_CurrentSprite == m_Sprite) SetCurrent = true;

		SAFE_DELETE(m_Sprite);

		if(Val->IsNULL())
		{
			m_Sprite = NULL;
			if(SetCurrent) m_CurrentSprite = NULL;
			Stack->PushBool(true);
		}
		else
		{
			char* Filename = Val->GetString();		
			CBSprite* spr = new CBSprite(Game, this);
			if(!spr || FAILED(spr->LoadFile(Filename))){				
				Script->RuntimeError("SetSprite method failed for file '%s'", Filename);
				Stack->PushBool(false);
			}
			else {
				m_Sprite = spr;
				if(SetCurrent) m_CurrentSprite = m_Sprite;
				Stack->PushBool(true);
			}
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSprite
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetSprite")==0){
		Stack->CorrectParams(0);

		if(!m_Sprite || !m_Sprite->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_Sprite->m_Filename);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSpriteObject
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetSpriteObject")==0){
		Stack->CorrectParams(0);

		if(!m_Sprite) Stack->PushNULL();
		else Stack->PushNative(m_Sprite, true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "AddTalkSprite")==0){
		Stack->CorrectParams(2);

		char* Filename = Stack->Pop()->GetString();
		bool Ex = Stack->Pop()->GetBool();

		CBSprite* spr = new CBSprite(Game, this);
		if(!spr || FAILED(spr->LoadFile(Filename))){
			Stack->PushBool(false);
			Script->RuntimeError("AddTalkSprite method failed for file '%s'", Filename);
		}
		else {
			if(Ex) m_TalkSpritesEx.Add(spr);
			else m_TalkSprites.Add(spr);
			Stack->PushBool(true);			
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemoveTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "RemoveTalkSprite")==0){
		Stack->CorrectParams(2);

		char* Filename = Stack->Pop()->GetString();
		bool Ex = Stack->Pop()->GetBool();
		int i;

		bool SetCurrent = false;
		bool SetTemp2 = false;

		if(Ex){
			for(i=0; i<m_TalkSpritesEx.GetSize(); i++){
				if(stricmp(m_TalkSpritesEx[i]->m_Filename, Filename)==0){
					if(m_CurrentSprite==m_TalkSpritesEx[i]) SetCurrent = true;
					if(m_TempSprite2==m_TalkSpritesEx[i]) SetTemp2 = true;
					delete m_TalkSpritesEx[i];
					m_TalkSpritesEx.RemoveAt(i);
					break;
				}
			}
		}
		else{
			for(i=0; i<m_TalkSprites.GetSize(); i++){
				if(stricmp(m_TalkSprites[i]->m_Filename, Filename)==0){
					if(m_CurrentSprite==m_TalkSprites[i]) SetCurrent = true;
					if(m_TempSprite2==m_TalkSprites[i]) SetTemp2 = true;
					delete m_TalkSprites[i];
					m_TalkSprites.RemoveAt(i);
					break;
				}
			}

		}

		Stack->PushBool(true);
		if(SetCurrent) m_CurrentSprite = m_Sprite;
		if(SetTemp2) m_TempSprite2 = m_Sprite;

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetTalkSprite
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetTalkSprite")==0){
		Stack->CorrectParams(2);

		char* Filename = Stack->Pop()->GetString();
		bool Ex = Stack->Pop()->GetBool();
		bool SetCurrent = false;
		bool SetTemp2 = false;

		CBSprite* spr = new CBSprite(Game, this);
		if(!spr || FAILED(spr->LoadFile(Filename))){
			Stack->PushBool(false);
			Script->RuntimeError("SetTalkSprite method failed for file '%s'", Filename);
		}
		else {

			// delete current
			int i;
			if(Ex){
				for(i=0; i<m_TalkSpritesEx.GetSize(); i++){
					if(m_TalkSpritesEx[i]==m_CurrentSprite) SetCurrent = true;
					if(m_TalkSpritesEx[i]==m_TempSprite2) SetTemp2 = true;
					delete m_TalkSpritesEx[i];
				}
				m_TalkSpritesEx.RemoveAll();
			}
			else{
				for(i=0; i<m_TalkSprites.GetSize(); i++){
					if(m_TalkSprites[i]==m_CurrentSprite) SetCurrent = true;
					if(m_TalkSprites[i]==m_TempSprite2) SetTemp2 = true;
					delete m_TalkSprites[i];
				}
				m_TalkSprites.RemoveAll();
			}

			// set new
			if(Ex) m_TalkSpritesEx.Add(spr);
			else m_TalkSprites.Add(spr);
			Stack->PushBool(true);

			if(SetCurrent) m_CurrentSprite = spr;
			if(SetTemp2) m_TempSprite2 = spr;
		}
		return S_OK;
	}

	else return CAdObject::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CBObject::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{

	//////////////////////////////////////////////////////////////////////////
	// SkipTo
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "SkipTo")==0){
		Stack->CorrectParams(2);
		m_PosX = Stack->Pop()->GetInt();
		m_PosY = Stack->Pop()->GetInt();
		AfterMove();
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Caption
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "Caption")==0){
		Stack->CorrectParams(1);
		Stack->PushString(GetCaption(Stack->Pop()->GetInt()));

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetCursor
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetCursor")==0){
		Stack->CorrectParams(1);
		if(SUCCEEDED(SetCursor(Stack->Pop()->GetString()))) Stack->PushBool(true);
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// RemoveCursor
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "RemoveCursor")==0){
		Stack->CorrectParams(0);
		if(!m_SharedCursors) SAFE_DELETE(m_Cursor);
		else m_Cursor = NULL;
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetCursor
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetCursor")==0){
		Stack->CorrectParams(0);
		if(!m_Cursor || !m_Cursor->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_Cursor->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetCursorObject
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetCursorObject")==0){
		Stack->CorrectParams(0);
		if(!m_Cursor) Stack->PushNULL();
		else Stack->PushNative(m_Cursor, true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// HasCursor
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "HasCursor")==0){
		Stack->CorrectParams(0);

		if(m_Cursor) Stack->PushBool(true);
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetCaption
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetCaption")==0){
		Stack->CorrectParams(2);
		SetCaption(Stack->Pop()->GetString(), Stack->Pop()->GetInt());
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// LoadSound
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "LoadSound")==0){
		Stack->CorrectParams(1);
		char* Filename = Stack->Pop()->GetString();
		if(SUCCEEDED(PlaySFX(Filename, false, false)))
			Stack->PushBool(true);
		else
			Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// PlaySound
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "PlaySound")==0){
		Stack->CorrectParams(3);

		char* Filename;
		bool Looping;
		DWORD LoopStart;
		
		CScValue* val1 = Stack->Pop();
		CScValue* val2 = Stack->Pop();
		CScValue* val3 = Stack->Pop();

		if(val1->m_Type==VAL_BOOL){
			Filename=NULL;
			Looping = val1->GetBool();
			LoopStart = val2->GetInt();
		}
		else{
			if(val1->IsNULL()) Filename = NULL;
			else Filename = val1->GetString();
			Looping = val2->IsNULL()?false:val2->GetBool();
			LoopStart = val3->GetInt();
		}

		if(FAILED(PlaySFX(Filename, Looping, true, NULL, LoopStart))) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// PlaySoundEvent
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "PlaySoundEvent")==0){
		Stack->CorrectParams(2);

		char* Filename;
		char* EventName;
		
		CScValue* val1 = Stack->Pop();
		CScValue* val2 = Stack->Pop();

		if(val2->IsNULL()){
			Filename=NULL;
			EventName = val1->GetString();
		}
		else{
			Filename = val1->GetString();
			EventName = val2->GetString();
		}

		if(FAILED(PlaySFX(Filename, false, true, EventName))) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// StopSound
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "StopSound")==0){
		Stack->CorrectParams(0);
		
		if(FAILED(StopSFX())) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// PauseSound
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "PauseSound")==0){
		Stack->CorrectParams(0);
		
		if(FAILED(PauseSFX())) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// ResumeSound
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "ResumeSound")==0){
		Stack->CorrectParams(0);
		
		if(FAILED(ResumeSFX())) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsSoundPlaying
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "IsSoundPlaying")==0){
		Stack->CorrectParams(0);
		
		if(m_SFX && m_SFX->IsPlaying()) Stack->PushBool(true);
		else Stack->PushBool(false);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetSoundPosition
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetSoundPosition")==0){
		Stack->CorrectParams(1);
		
		DWORD Time = Stack->Pop()->GetInt();
		if(FAILED(SetSFXTime(Time))) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSoundPosition
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetSoundPosition")==0){
		Stack->CorrectParams(0);

		if(!m_SFX) Stack->PushInt(0);
		else Stack->PushInt(m_SFX->GetPositionTime());
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetSoundVolume
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetSoundVolume")==0){
		Stack->CorrectParams(1);
		
		int Volume = Stack->Pop()->GetInt();
		if(FAILED(SetSFXVolume(Volume))) Stack->PushBool(false);
		else Stack->PushBool(true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetSoundVolume
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetSoundVolume")==0){
		Stack->CorrectParams(0);

		if(!m_SFX) Stack->PushInt(m_SFXVolume);
		else Stack->PushInt(m_SFX->GetVolume());
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetShadowImage
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetShadowImage")==0){
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();
		if(m_ShadowImage) Game->m_SurfaceStorage->RemoveSurface(m_ShadowImage);
		m_ShadowImage = NULL;

		if(Val->IsString())
		{
			m_ShadowImage = Game->m_SurfaceStorage->AddSurface(Val->GetString());
			Stack->PushBool(m_ShadowImage!=NULL);
		}
		else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetShadowImage
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetShadowImage")==0){
		Stack->CorrectParams(0);
		if(m_ShadowImage && m_ShadowImage->m_Filename) Stack->PushString(m_ShadowImage->m_Filename);
		else Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetLightPosition
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetLightPosition")==0){
		Stack->CorrectParams(3);
		
		double x = Stack->Pop()->GetFloat();
		double y = Stack->Pop()->GetFloat();
		double z = Stack->Pop()->GetFloat();
		m_ShadowLightPos = D3DXVECTOR3(x, y, z);
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SoundFXNone
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SoundFXNone")==0)
	{
		Stack->CorrectParams(0);
		m_SFXType = SFX_NONE;
		m_SFXParam1 = 0;
		m_SFXParam2 = 0;
		m_SFXParam3 = 0;
		m_SFXParam4 = 0;
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SoundFXEcho
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SoundFXEcho")==0)
	{
		Stack->CorrectParams(4);
		m_SFXType = SFX_ECHO;
		m_SFXParam1 = (float)Stack->Pop()->GetFloat(0); // Wet/Dry Mix [%] (0-100)
		m_SFXParam2 = (float)Stack->Pop()->GetFloat(0); // Feedback [%] (0-100)
		m_SFXParam3 = (float)Stack->Pop()->GetFloat(333.0f); // Left Delay [ms] (1-2000)
		m_SFXParam4 = (float)Stack->Pop()->GetFloat(333.0f); // Right Delay [ms] (1-2000)
		Stack->PushNULL();

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SoundFXReverb
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SoundFXReverb")==0)
	{
		Stack->CorrectParams(4);
		m_SFXType = SFX_REVERB;
		m_SFXParam1 = (float)Stack->Pop()->GetFloat(0); // In Gain [dB] (-96 - 0)
		m_SFXParam2 = (float)Stack->Pop()->GetFloat(0); // Reverb Mix [dB] (-96 - 0)
		m_SFXParam3 = (float)Stack->Pop()->GetFloat(1000.0f); // Reverb Time [ms] (0.001 - 3000)
		m_SFXParam4 = (float)Stack->Pop()->GetFloat(0.001f); // HighFreq RT Ratio (0.001 - 0.999)
		Stack->PushNULL();

		return S_OK;
	}

	else return CBScriptHolder::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CAdLayer::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// GetNode
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "GetNode")==0)
	{
		Stack->CorrectParams(1);
		CScValue* val = Stack->Pop();
		int node = -1;
		
		if(val->m_Type==VAL_INT) node = val->GetInt();
		else{ // get by name
			for(int i=0; i<m_Nodes.GetSize(); i++){
				if( (m_Nodes[i]->m_Type==OBJECT_ENTITY && CBPlatform::stricmp(m_Nodes[i]->m_Entity->m_Name, val->GetString())==0) ||
					(m_Nodes[i]->m_Type==OBJECT_REGION && CBPlatform::stricmp(m_Nodes[i]->m_Region->m_Name, val->GetString())==0)){
					node = i;
					break;
				}					
			}
		}

		if(node<0 || node>= m_Nodes.GetSize()) Stack->PushNULL();
		else{
			switch(m_Nodes[node]->m_Type){
				case OBJECT_ENTITY:
					Stack->PushNative(m_Nodes[node]->m_Entity, true);
					break;
				case OBJECT_REGION:
					Stack->PushNative(m_Nodes[node]->m_Region, true);
					break;
				default:
					Stack->PushNULL();
			}
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddRegion / AddEntity
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "AddRegion")==0 || strcmp(Name, "AddEntity")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();

		CAdSceneNode* Node = new CAdSceneNode(Game);
		if(strcmp(Name, "AddRegion")==0)
		{
			CAdRegion* Region = new CAdRegion(Game);
			if(!Val->IsNULL()) Region->SetName(Val->GetString());
			Node->SetRegion(Region);
			Stack->PushNative(Region, true);
		}
		else
		{
			CAdEntity* Entity = new CAdEntity(Game);
			if(!Val->IsNULL()) Entity->SetName(Val->GetString());
			Node->SetEntity(Entity);
			Stack->PushNative(Entity, true);
		}
		m_Nodes.Add(Node);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// InsertRegion / InsertEntity
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "InsertRegion")==0 || strcmp(Name, "InsertEntity")==0)
	{
		Stack->CorrectParams(2);
		int Index = Stack->Pop()->GetInt();
		CScValue* Val = Stack->Pop();

		CAdSceneNode* Node = new CAdSceneNode(Game);
		if(strcmp(Name, "InsertRegion")==0)
		{
			CAdRegion* Region = new CAdRegion(Game);
			if(!Val->IsNULL()) Region->SetName(Val->GetString());
			Node->SetRegion(Region);
			Stack->PushNative(Region, true);
		}
		else
		{
			CAdEntity* Entity = new CAdEntity(Game);
			if(!Val->IsNULL()) Entity->SetName(Val->GetString());
			Node->SetEntity(Entity);
			Stack->PushNative(Entity, true);
		}
		if(Index < 0) Index = 0;
		if(Index <= m_Nodes.GetSize() - 1) m_Nodes.InsertAt(Index, Node);
		else m_Nodes.Add(Node);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DeleteNode
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "DeleteNode")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();

		CAdSceneNode* ToDelete = NULL;
		if(Val->IsNative())
		{
			CBScriptable* Temp = Val->GetNative();
			for(int i=0; i<m_Nodes.GetSize(); i++)
			{
				if(m_Nodes[i]->m_Region==Temp || m_Nodes[i]->m_Entity==Temp)
				{
					ToDelete = m_Nodes[i];
					break;
				}
			}
		}
		else
		{
			int Index = Val->GetInt();
			if(Index >= 0 && Index < m_Nodes.GetSize())
			{
				ToDelete = m_Nodes[Index];
			}
		}
		if(ToDelete==NULL)
		{
			Stack->PushBool(false);
			return S_OK;
		}

		for(int i=0; i<m_Nodes.GetSize(); i++)
		{
			if(m_Nodes[i]==ToDelete)
			{				
				SAFE_DELETE(m_Nodes[i]);
				m_Nodes.RemoveAt(i);
				break;
			}
		}
		Stack->PushBool(true);
		return S_OK;
	}

	else return CBObject::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CBSprite::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// GetFrame
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "GetFrame")==0)
	{
		Stack->CorrectParams(1);
		int Index = Stack->Pop()->GetInt(-1);
		if(Index<0 || Index>=m_Frames.GetSize())
		{
			Script->RuntimeError("Sprite.GetFrame: Frame index %d is out of range.", Index);
			Stack->PushNULL();
		}
		else Stack->PushNative(m_Frames[Index], true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DeleteFrame
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "DeleteFrame")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();
		if(Val->IsInt())
		{
			int Index = Val->GetInt(-1);
			if(Index<0 || Index>=m_Frames.GetSize())
			{
				Script->RuntimeError("Sprite.DeleteFrame: Frame index %d is out of range.", Index);
			}			
		}
		else
		{
			CBFrame* Frame = (CBFrame*)Val->GetNative();
			for(int i=0; i<m_Frames.GetSize(); i++)
			{
				if(m_Frames[i]==Frame)
				{
					if(i==m_CurrentFrame) m_LastFrameTime = 0;
					delete m_Frames[i];
					m_Frames.RemoveAt(i);
					break;
				}
			}
		}
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Reset
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "Reset")==0)
	{
		Stack->CorrectParams(0);
		Reset();
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// AddFrame
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "AddFrame")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();
		char* Filename = NULL;
		if(!Val->IsNULL()) Filename = Val->GetString();

		CBFrame* Frame = new CBFrame(Game);		
		if(Filename!=NULL)
		{
			CBSubFrame* Sub = new CBSubFrame(Game);			
			if(SUCCEEDED(Sub->SetSurface(Filename)))
			{
				Sub->SetDefaultRect();
				Frame->m_Subframes.Add(Sub);
			}
			else delete Sub;
		}
		m_Frames.Add(Frame);

		Stack->PushNative(Frame, true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// InsertFrame
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "InsertFrame")==0)
	{
		Stack->CorrectParams(2);
		int Index = Stack->Pop()->GetInt();
		if(Index<0) Index = 0;

		CScValue* Val = Stack->Pop();
		char* Filename = NULL;
		if(!Val->IsNULL()) Filename = Val->GetString();

		CBFrame* Frame = new CBFrame(Game);		
		if(Filename!=NULL)
		{
			CBSubFrame* Sub = new CBSubFrame(Game);			
			if(SUCCEEDED(Sub->SetSurface(Filename))) Frame->m_Subframes.Add(Sub);
			else delete Sub;
		}

		if(Index>=m_Frames.GetSize()) m_Frames.Add(Frame);
		else m_Frames.InsertAt(Index, Frame);

		Stack->PushNative(Frame, true);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Pause
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "Pause")==0)
	{
		Stack->CorrectParams(0);
		m_Paused = true;
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Play
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "Play")==0)
	{
		Stack->CorrectParams(0);
		m_Paused = false;
		Stack->PushNULL();
		return S_OK;
	}

	else return CBScriptHolder::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CUIWindow::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
    //////////////////////////////////////////////////////////////////////////
    // GetWidget / GetControl
    //////////////////////////////////////////////////////////////////////////
    if(strcmp(Name, "GetWidget")==0 || strcmp(Name, "GetControl")==0)
    {
        Stack->CorrectParams(1);
        CScValue* val = Stack->Pop();
        if(val->GetType()==VAL_INT)
        {
            int widget= val->GetInt();
            if(widget<0 || widget>=m_Widgets.GetSize()) Stack->PushNULL();
            else Stack->PushNative(m_Widgets[widget], true);
        }
        else
        {
            for(int i=0; i<m_Widgets.GetSize(); i++)
            {
                if(CBPlatform::stricmp(m_Widgets[i]->m_Name, val->GetString())==0)
                {
                    Stack->PushNative(m_Widgets[i], true);
                    return S_OK;
                }
            }
            Stack->PushNULL();
        }

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // SetInactiveFont
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "SetInactiveFont")==0)
    {
        Stack->CorrectParams(1);

        if(m_FontInactive) Game->m_FontStorage->RemoveFont(m_FontInactive);
        m_FontInactive = Game->m_FontStorage->AddFont(Stack->Pop()->GetString());
        Stack->PushBool(m_FontInactive!=NULL);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // SetInactiveImage
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "SetInactiveImage")==0)
    {
        Stack->CorrectParams(1);

        SAFE_DELETE(m_ImageInactive);
        m_ImageInactive = new CBSprite(Game);
        char* Filename = Stack->Pop()->GetString();
        if(!m_ImageInactive || FAILED(m_ImageInactive->LoadFile(Filename)))
        {
            SAFE_DELETE(m_ImageInactive);
            Stack->PushBool(false);
        }
        else Stack->PushBool(true);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // GetInactiveImage
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "GetInactiveImage")==0)
    {
        Stack->CorrectParams(0);
        if(!m_ImageInactive || !m_ImageInactive->m_Filename) Stack->PushNULL();
        else Stack->PushString(m_ImageInactive->m_Filename);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // GetInactiveImageObject
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "GetInactiveImageObject")==0)
    {
        Stack->CorrectParams(0);
        if(!m_ImageInactive) Stack->PushNULL();
        else Stack->PushNative(m_ImageInactive, true);

        return S_OK;
    }


    //////////////////////////////////////////////////////////////////////////
    // Close
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "Close")==0)
    {
        Stack->CorrectParams(0);
        Stack->PushBool(SUCCEEDED(Close()));
        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // GoExclusive
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "GoExclusive")==0)
    {
        Stack->CorrectParams(0);
        GoExclusive();
        Script->WaitFor(this);
        Stack->PushNULL();
        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // GoSystemExclusive
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "GoSystemExclusive")==0)
    {
        Stack->CorrectParams(1);
        char* Event = Stack->Pop()->GetString();
        GoSystemExclusive();

        if (Event != NULL)
        {
            ApplyEvent(Event);
        }
        Script->WaitFor(this);
        Stack->PushNULL();
        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // Center
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "Center")==0)
    {
        Stack->CorrectParams(0);
        m_PosX = (Game->m_Renderer->m_Width - m_Width) / 2;
        m_PosY = (Game->m_Renderer->m_Height - m_Height) / 2;
        Stack->PushNULL();
        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // LoadFromFile
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "LoadFromFile")==0)
    {
        Stack->CorrectParams(1);

        CScValue* Val = Stack->Pop();
        Cleanup();
        if(!Val->IsNULL())
        {
            Stack->PushBool(SUCCEEDED(LoadFile(Val->GetString())));
        }
        else Stack->PushBool(true);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // CreateButton
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "CreateButton")==0)
    {
        Stack->CorrectParams(1);
        CScValue* Val = Stack->Pop();

        CUIButton* Btn = new CUIButton(Game);
        if(!Val->IsNULL()) Btn->SetName(Val->GetString());
        Stack->PushNative(Btn, true);

        Btn->m_Parent = this;
        m_Widgets.Add(Btn);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // CreateStatic
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "CreateStatic")==0)
    {
        Stack->CorrectParams(1);
        CScValue* Val = Stack->Pop();

        CUIText* Sta = new CUIText(Game);
        if(!Val->IsNULL()) Sta->SetName(Val->GetString());
        Stack->PushNative(Sta, true);

        Sta->m_Parent = this;
        m_Widgets.Add(Sta);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // CreateEditor
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "CreateEditor")==0)
    {
        Stack->CorrectParams(1);
        CScValue* Val = Stack->Pop();

        CUIEdit* Edi = new CUIEdit(Game);
        if(!Val->IsNULL()) Edi->SetName(Val->GetString());
        Stack->PushNative(Edi, true);

        Edi->m_Parent = this;
        m_Widgets.Add(Edi);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // CreateWindow
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "CreateWindow")==0)
    {
        Stack->CorrectParams(1);
        CScValue* Val = Stack->Pop();

        CUIWindow* Win = new CUIWindow(Game);
        if(!Val->IsNULL()) Win->SetName(Val->GetString());
        Stack->PushNative(Win, true);

        Win->m_Parent = this;
        m_Widgets.Add(Win);

        return S_OK;
    }

    //////////////////////////////////////////////////////////////////////////
    // DeleteControl / DeleteButton / DeleteStatic / DeleteEditor / DeleteWindow
    //////////////////////////////////////////////////////////////////////////
    else if(strcmp(Name, "DeleteControl")==0 || strcmp(Name, "DeleteButton")==0 || strcmp(Name, "DeleteStatic")==0 || strcmp(Name, "DeleteEditor")==0 || strcmp(Name, "DeleteWindow")==0)
    {
        Stack->CorrectParams(1);
        CScValue* val = Stack->Pop();
        CUIObject* obj = (CUIObject*)val->GetNative();

        for(int i=0; i<m_Widgets.GetSize(); i++)
        {
            if(m_Widgets[i]==obj)
            {
                delete m_Widgets[i];
                m_Widgets.RemoveAt(i);
                if(val->GetType()==VAL_VARIABLE_REF) val->SetNULL();
            }
        }
        Stack->PushNULL();
        return S_OK;
    }
    else if SUCCEEDED(Game->WindowScriptMethodHook(this, Script, Stack, Name)) return S_OK;

    else return CUIObject::ScCallMethod(Script, Stack, ThisStack, Name);
HRESULT CSXMemBuffer::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// SetSize
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "SetSize")==0){
		Stack->CorrectParams(1);
		int NewSize = Stack->Pop()->GetInt();
		NewSize = max(0, NewSize);
		if(SUCCEEDED(Resize(NewSize))) Stack->PushBool(true);
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetBool
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetBool")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(bool))) Stack->PushNULL();
		else Stack->PushBool(*(bool*)((BYTE*)m_Buffer+Start));		

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetByte
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetByte")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(BYTE))) Stack->PushNULL();
		else Stack->PushInt(*(BYTE*)((BYTE*)m_Buffer+Start));

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetShort
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetShort")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(short))) Stack->PushNULL();
		else Stack->PushInt(65536 + *(short*)((BYTE*)m_Buffer+Start));		

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetInt / GetLong
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetInt")==0 || strcmp(Name, "GetLong")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(int))) Stack->PushNULL();
		else Stack->PushInt(*(int*)((BYTE*)m_Buffer+Start));		

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFloat
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetFloat")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(float))) Stack->PushNULL();
		else Stack->PushFloat(*(float*)((BYTE*)m_Buffer+Start));		

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetDouble
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetDouble")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(double))) Stack->PushNULL();
		else Stack->PushFloat(*(double*)((BYTE*)m_Buffer+Start));

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetString
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetString")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		int Length = Stack->Pop()->GetInt();

		// find end of string
		if(Length==0 && Start >= 0 && Start < m_Size)
		{
			for(int i=Start; i<m_Size; i++)
			{
				if(((char*)m_Buffer)[i]=='\0')
				{
					Length = i - Start;
					break;
				}
			}
		}

		if(!CheckBounds(Script, Start, Length)) Stack->PushNULL();
		else
		{
			char* Str = new char[Length+1];
			strncpy(Str, (const char*)m_Buffer + Start, Length);
			Str[Length] = '\0';
			Stack->PushString(Str);
			delete [] Str;
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPointer
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetPointer")==0){
		Stack->CorrectParams(1);
		int Start = Stack->Pop()->GetInt();
		if(!CheckBounds(Script, Start, sizeof(void*))) Stack->PushNULL();
		else
		{
			void* Pointer = *(void**)((BYTE*)m_Buffer+Start);
			CSXMemBuffer* Buf = new CSXMemBuffer(Game, Pointer);
			Stack->PushNative(Buf, false);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetBool
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetBool")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		bool Val = Stack->Pop()->GetBool();

		if(!CheckBounds(Script, Start, sizeof(bool))) Stack->PushBool(false);
		else
		{
			*(bool*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetByte
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetByte")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		BYTE Val = (BYTE)Stack->Pop()->GetInt();

		if(!CheckBounds(Script, Start, sizeof(BYTE))) Stack->PushBool(false);
		else
		{
			*(BYTE*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetShort
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetShort")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		short Val = (short)Stack->Pop()->GetInt();

		if(!CheckBounds(Script, Start, sizeof(short))) Stack->PushBool(false);
		else
		{
			*(short*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetInt / SetLong
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetInt")==0 || strcmp(Name, "SetLong")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		int Val = Stack->Pop()->GetInt();

		if(!CheckBounds(Script, Start, sizeof(int))) Stack->PushBool(false);
		else
		{
			*(int*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFloat
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetFloat")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		float Val = (float)Stack->Pop()->GetFloat();

		if(!CheckBounds(Script, Start, sizeof(float))) Stack->PushBool(false);
		else
		{
			*(float*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetDouble
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetDouble")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		double Val = Stack->Pop()->GetFloat();

		if(!CheckBounds(Script, Start, sizeof(double))) Stack->PushBool(false);
		else
		{
			*(double*)((BYTE*)m_Buffer+Start) = Val;
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetString
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetString")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		char* Val = Stack->Pop()->GetString();

		if(!CheckBounds(Script, Start, strlen(Val)+1)) Stack->PushBool(false);
		else
		{
			memcpy((BYTE*)m_Buffer+Start, Val, strlen(Val)+1);
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPointer
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetPointer")==0){
		Stack->CorrectParams(2);
		int Start = Stack->Pop()->GetInt();
		CScValue* Val = Stack->Pop();

		if(!CheckBounds(Script, Start, sizeof(void*))) Stack->PushBool(false);
		else
		{
			int Pointer = (int)Val->GetMemBuffer();
			memcpy((BYTE*)m_Buffer+Start, &Pointer, sizeof(void*));
			Stack->PushBool(true);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// DEBUG_Dump
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "DEBUG_Dump")==0){
		Stack->CorrectParams(0);
		if(m_Buffer && m_Size)
		{
			FILE* f = fopen("c:\\!!buffer.bin", "wb");
			fwrite(m_Buffer, m_Size, 1, f);
			fclose(f);
		}
		Stack->PushNULL();
		return S_OK;
	}

	else return E_FAIL;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CUIObject::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// SetFont
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "SetFont")==0){
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();

		if(m_Font) Game->m_FontStorage->RemoveFont(m_Font);
		if(Val->IsNULL())
		{
			m_Font = NULL;
			Stack->PushBool(true);
		}
		else
		{
			m_Font = Game->m_FontStorage->AddFont(Val->GetString());
			Stack->PushBool(m_Font!=NULL);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetImage
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "SetImage")==0){
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();

		SAFE_DELETE(m_Image);		
		if(Val->IsNULL()){
			Stack->PushBool(true);
			return S_OK;
		}
		
		m_Image = new CBSprite(Game);
		if(!m_Image || FAILED(m_Image->LoadFile(Val->GetString()))){
			SAFE_DELETE(m_Image);
			Stack->PushBool(false);			
		}
		else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetImage
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetImage")==0){
		Stack->CorrectParams(0);
		if(!m_Image || !m_Image->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_Image->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetImageObject
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GetImageObject")==0){
		Stack->CorrectParams(0);
		if(!m_Image) Stack->PushNULL();
		else Stack->PushNative(m_Image, true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Focus
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "Focus")==0){
		Stack->CorrectParams(0);
		Focus();
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveAfter / MoveBefore
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "MoveAfter")==0 || strcmp(Name, "MoveBefore")==0){
		Stack->CorrectParams(1);

		if(m_Parent && m_Parent->m_Type == UI_WINDOW){
			CUIWindow* win = (CUIWindow*)m_Parent;

			int i;
			bool found = false;			
			CScValue* val = Stack->Pop();
			// find directly
			if(val->IsNative()){
				CUIObject* widget = (CUIObject*)val->GetNative();
				for(i=0; i<win->m_Widgets.GetSize(); i++){
					if(win->m_Widgets[i]==widget){
						found = true;
						break;
					}
				}
			}
			// find by name
			else{
				char* name = val->GetString();
				for(i=0; i<win->m_Widgets.GetSize(); i++){
					if(CBPlatform::stricmp(win->m_Widgets[i]->m_Name, name)==0){
						found = true;
						break;
					}
				}
			}

			if(found){
				bool done=false;
				for(int j=0; j<win->m_Widgets.GetSize(); j++){
					if(win->m_Widgets[j]==this){
						if(strcmp(Name, "MoveAfter")==0) i++;
						if(j>=i) j++;

						win->m_Widgets.InsertAt(i, this);
						win->m_Widgets.RemoveAt(j);						

						done = true;
						Stack->PushBool(true);
						break;
					}
				}
				if(!done) Stack->PushBool(false);
			}
			else Stack->PushBool(false);

		}
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveToBottom
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "MoveToBottom")==0){
		Stack->CorrectParams(0);

		if(m_Parent && m_Parent->m_Type == UI_WINDOW){
			CUIWindow* win = (CUIWindow*)m_Parent;
			for(int i=0; i<win->m_Widgets.GetSize(); i++){
				if(win->m_Widgets[i]==this){
					win->m_Widgets.RemoveAt(i);
					win->m_Widgets.InsertAt(0, this);
					break;
				}
			}
			Stack->PushBool(true);
		}
		else Stack->PushBool(false);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MoveToTop
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "MoveToTop")==0){
		Stack->CorrectParams(0);

		if(m_Parent && m_Parent->m_Type == UI_WINDOW){
			CUIWindow* win = (CUIWindow*)m_Parent;
			for(int i=0; i<win->m_Widgets.GetSize(); i++){
				if(win->m_Widgets[i]==this){
					win->m_Widgets.RemoveAt(i);
					win->m_Widgets.Add(this);
					break;
				}
			}
			Stack->PushBool(true);
		}
		else Stack->PushBool(false);

		return S_OK;
	}

	else return CBObject::ScCallMethod(Script, Stack, ThisStack, Name);
}
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
HRESULT CBScriptHolder::ParseProperty(BYTE * Buffer, bool Complete)
{
	TOKEN_TABLE_START(commands)
		TOKEN_TABLE (PROPERTY)
		TOKEN_TABLE (NAME)
		TOKEN_TABLE (VALUE)
	TOKEN_TABLE_END

	BYTE* params;
	int cmd;
	CBParser parser(Game);

	if(Complete)
	{
		if(parser.GetCommand ((char**)&Buffer, commands, (char**)&params)!=TOKEN_PROPERTY)
		{
			Game->LOG(0, "'PROPERTY' keyword expected.");
			return E_FAIL;
		}
		Buffer = params;
	}

	char* PropName=NULL;
	char* PropValue=NULL;

	while ((cmd = parser.GetCommand ((char**)&Buffer, commands, (char**)&params)) > 0)
	{
		switch (cmd)
		{
			case TOKEN_NAME:
				SAFE_DELETE_ARRAY(PropName);
				PropName = new char[strlen((char*)params)+1];
				if(PropName) strcpy(PropName, (char*)params);
				else cmd = PARSERR_GENERIC;
			break;

			case TOKEN_VALUE:
				SAFE_DELETE_ARRAY(PropValue);
				PropValue = new char[strlen((char*)params)+1];
				if(PropValue) strcpy(PropValue, (char*)params);
				else cmd = PARSERR_GENERIC;
			break;
		}

	}
	if (cmd == PARSERR_TOKENNOTFOUND)
	{
		SAFE_DELETE_ARRAY(PropName);
		SAFE_DELETE_ARRAY(PropValue);
		Game->LOG(0, "Syntax error in PROPERTY definition");
		return E_FAIL;
	}
	if (cmd == PARSERR_GENERIC || PropName==NULL || PropValue==NULL)
	{
		SAFE_DELETE_ARRAY(PropName);
		SAFE_DELETE_ARRAY(PropValue);
		Game->LOG(0, "Error loading PROPERTY definition");
		return E_FAIL;
	}


	CScValue* val = new CScValue(Game);
	val->SetString(PropValue);
	ScSetProperty(PropName, val);

	delete val;
	SAFE_DELETE_ARRAY(PropName);
	SAFE_DELETE_ARRAY(PropValue);

	return S_OK;
}
Exemple #17
0
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CUIButton::ScCallMethod(CScScript *Script, CScStack *Stack, CScStack *ThisStack, char *Name) {
	//////////////////////////////////////////////////////////////////////////
	// SetDisabledFont
	//////////////////////////////////////////////////////////////////////////
	if (strcmp(Name, "SetDisabledFont") == 0) {
		Stack->CorrectParams(1);
		CScValue *Val = Stack->Pop();

		if (m_FontDisable) Game->m_FontStorage->RemoveFont(m_FontDisable);
		if (Val->IsNULL()) {
			m_FontDisable = NULL;
			Stack->PushBool(true);
		} else {
			m_FontDisable = Game->m_FontStorage->AddFont(Val->GetString());
			Stack->PushBool(m_FontDisable != NULL);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetHoverFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetHoverFont") == 0) {
		Stack->CorrectParams(1);
		CScValue *Val = Stack->Pop();

		if (m_FontHover) Game->m_FontStorage->RemoveFont(m_FontHover);
		if (Val->IsNULL()) {
			m_FontHover = NULL;
			Stack->PushBool(true);
		} else {
			m_FontHover = Game->m_FontStorage->AddFont(Val->GetString());
			Stack->PushBool(m_FontHover != NULL);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPressedFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetPressedFont") == 0) {
		Stack->CorrectParams(1);
		CScValue *Val = Stack->Pop();

		if (m_FontPress) Game->m_FontStorage->RemoveFont(m_FontPress);
		if (Val->IsNULL()) {
			m_FontPress = NULL;
			Stack->PushBool(true);
		} else {
			m_FontPress = Game->m_FontStorage->AddFont(Val->GetString());
			Stack->PushBool(m_FontPress != NULL);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFocusedFont
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetFocusedFont") == 0) {
		Stack->CorrectParams(1);
		CScValue *Val = Stack->Pop();

		if (m_FontFocus) Game->m_FontStorage->RemoveFont(m_FontFocus);
		if (Val->IsNULL()) {
			m_FontFocus = NULL;
			Stack->PushBool(true);
		} else {
			m_FontFocus = Game->m_FontStorage->AddFont(Val->GetString());
			Stack->PushBool(m_FontFocus != NULL);
		}
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetDisabledImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetDisabledImage") == 0) {
		Stack->CorrectParams(1);

		delete m_ImageDisable;
		m_ImageDisable = new CBSprite(Game);
		char *Filename = Stack->Pop()->GetString();
		if (!m_ImageDisable || FAILED(m_ImageDisable->LoadFile(Filename))) {
			delete m_ImageDisable;
			m_ImageDisable = NULL;
			Stack->PushBool(false);
		} else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetDisabledImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetDisabledImage") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageDisable || !m_ImageDisable->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_ImageDisable->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetDisabledImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetDisabledImageObject") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageDisable) Stack->PushNULL();
		else Stack->PushNative(m_ImageDisable, true);

		return S_OK;
	}


	//////////////////////////////////////////////////////////////////////////
	// SetHoverImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetHoverImage") == 0) {
		Stack->CorrectParams(1);

		delete m_ImageHover;
		m_ImageHover = new CBSprite(Game);
		char *Filename = Stack->Pop()->GetString();
		if (!m_ImageHover || FAILED(m_ImageHover->LoadFile(Filename))) {
			delete m_ImageHover;
			m_ImageHover = NULL;
			Stack->PushBool(false);
		} else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetHoverImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetHoverImage") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageHover || !m_ImageHover->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_ImageHover->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetHoverImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetHoverImageObject") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageHover) Stack->PushNULL();
		else Stack->PushNative(m_ImageHover, true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetPressedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetPressedImage") == 0) {
		Stack->CorrectParams(1);

		delete m_ImagePress;
		m_ImagePress = new CBSprite(Game);
		char *Filename = Stack->Pop()->GetString();
		if (!m_ImagePress || FAILED(m_ImagePress->LoadFile(Filename))) {
			delete m_ImagePress;
			m_ImagePress = NULL;
			Stack->PushBool(false);
		} else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPressedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetPressedImage") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImagePress || !m_ImagePress->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_ImagePress->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetPressedImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetPressedImageObject") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImagePress) Stack->PushNULL();
		else Stack->PushNative(m_ImagePress, true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// SetFocusedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "SetFocusedImage") == 0) {
		Stack->CorrectParams(1);

		delete m_ImageFocus;
		m_ImageFocus = new CBSprite(Game);
		char *Filename = Stack->Pop()->GetString();
		if (!m_ImageFocus || FAILED(m_ImageFocus->LoadFile(Filename))) {
			delete m_ImageFocus;
			m_ImageFocus = NULL;
			Stack->PushBool(false);
		} else Stack->PushBool(true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFocusedImage
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetFocusedImage") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageFocus || !m_ImageFocus->m_Filename) Stack->PushNULL();
		else Stack->PushString(m_ImageFocus->m_Filename);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GetFocusedImageObject
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "GetFocusedImageObject") == 0) {
		Stack->CorrectParams(0);
		if (!m_ImageFocus) Stack->PushNULL();
		else Stack->PushNative(m_ImageFocus, true);

		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// Press
	//////////////////////////////////////////////////////////////////////////
	else if (strcmp(Name, "Press") == 0) {
		Stack->CorrectParams(0);

		if (m_Visible && !m_Disable) {
			m_OneTimePress = true;
			m_OneTimePressTime = CBPlatform::GetTime();
		}
		Stack->PushNULL();

		return S_OK;
	}


	else return CUIObject::ScCallMethod(Script, Stack, ThisStack, Name);
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
HRESULT CAdActor::ScCallMethod(CScScript* Script, CScStack *Stack, CScStack *ThisStack, char *Name)
{
	//////////////////////////////////////////////////////////////////////////
	// GoTo / GoToAsync
	//////////////////////////////////////////////////////////////////////////
	if(strcmp(Name, "GoTo")==0 || strcmp(Name, "GoToAsync")==0)
	{
		Stack->CorrectParams(2);
		int X = Stack->Pop()->GetInt();
		int Y = Stack->Pop()->GetInt();
		GoTo(X, Y);
		if(strcmp(Name, "GoToAsync")!=0) Script->WaitForExclusive(this);
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// GoToObject / GoToObjectAsync
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "GoToObject")==0 || strcmp(Name, "GoToObjectAsync")==0)
	{
		Stack->CorrectParams(1);
		CScValue* Val = Stack->Pop();
		if(!Val->IsNative())
		{
			Script->RuntimeError("actor.%s method accepts an entity refrence only", Name);
			Stack->PushNULL();
			return S_OK;
		}
		CAdObject* Obj = (CAdObject*)Val->GetNative();
		if(!Obj || Obj->m_Type != OBJECT_ENTITY)
		{
			Script->RuntimeError("actor.%s method accepts an entity refrence only", Name);
			Stack->PushNULL();
			return S_OK;
		}
		CAdEntity* Ent = (CAdEntity*)Obj;
		if(Ent->m_WalkToX==0 && Ent->m_WalkToY==0) GoTo(Ent->m_PosX, Ent->m_PosY);
		else GoTo(Ent->m_WalkToX, Ent->m_WalkToY, Ent->m_WalkToDir);
		if(strcmp(Name, "GoToObjectAsync")!=0) Script->WaitForExclusive(this);
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// TurnTo / TurnToAsync
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "TurnTo")==0 || strcmp(Name, "TurnToAsync")==0)
	{
		Stack->CorrectParams(1);
		int dir;
		CScValue* val = Stack->Pop();
		
		// turn to object?
		if(val->IsNative() && Game->ValidObject((CBObject*)val->GetNative()))
		{
			CBObject* obj = (CBObject*)val->GetNative();
			int angle = (int)(atan2((double)(obj->m_PosY - m_PosY), (double)(obj->m_PosX - m_PosX)) * (180/3.14));
			dir = (int)AngleToDirection(angle);
		}
		// otherwise turn to direction
		else dir = val->GetInt();

		if(dir >= 0 && dir < NUM_DIRECTIONS)
		{
			TurnTo((TDirection)dir);
			if(strcmp(Name, "TurnToAsync")!=0) Script->WaitForExclusive(this);
		}
		Stack->PushNULL();
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// IsWalking
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "IsWalking")==0)
	{
		Stack->CorrectParams(0);
		Stack->PushBool(m_State==STATE_FOLLOWING_PATH);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// MergeAnims
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "MergeAnims")==0)
	{
		Stack->CorrectParams(1);
		Stack->PushBool(SUCCEEDED(MergeAnims(Stack->Pop()->GetString())));
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// UnloadAnim
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "UnloadAnim")==0)
	{
		Stack->CorrectParams(1);
		char* AnimName = Stack->Pop()->GetString();

		bool Found = false;
		for(int i=0; i<m_Anims.GetSize(); i++)
		{
			if(stricmp(m_Anims[i]->m_Name, AnimName)==0)
			{
				// invalidate sprites in use
				if(m_Anims[i]->ContainsSprite(m_TempSprite2)) m_TempSprite2 = NULL;
				if(m_Anims[i]->ContainsSprite(m_CurrentSprite)) m_CurrentSprite = NULL;
				if(m_Anims[i]->ContainsSprite(m_AnimSprite2)) m_AnimSprite2 = NULL;

				SAFE_DELETE(m_Anims[i]);
				m_Anims.RemoveAt(i);
				i--;
				Found = true;
			}
		}
		Stack->PushBool(Found);
		return S_OK;
	}

	//////////////////////////////////////////////////////////////////////////
	// HasAnim
	//////////////////////////////////////////////////////////////////////////
	else if(strcmp(Name, "HasAnim")==0)
	{
		Stack->CorrectParams(1);
		char* AnimName = Stack->Pop()->GetString();
		Stack->PushBool(GetAnimByName(AnimName) != NULL);
		return S_OK;
	}

	else return CAdTalkHolder::ScCallMethod(Script, Stack, ThisStack, Name);
}