Files
2026-06-01 12:46:52 +02:00

1953 lines
50 KiB
C++

#include "stdafx.h"
#include "SGameScript.h"
#include "SBotManager.h"
#include "SGame.h"
#include "SGameObject.h"
#include <toolkit/khash.h>
#include "SGroundMaterialResDB.h"
// { [sonador]
#include "SGameWeatherAttr.h"
#include <toolkit/XStringUtil.h>
// }
//#include "KUIControl.h"
//#include "SGameMessageUI.h"
#ifdef CLOUD_LUA_RELOAD
#include <kfile/KFileManager.h>
#include "LuaVM.h"
#endif
#ifdef CLOUD_LUA
#include "SGameCloud.h"
#endif
#include <lua/lua.hpp>
extern SBotManager * g_pSBotMng;
//////////////////////////////////////////////////////////////////////////
//Object
struct KBotMsgSpell : public KArg
{
KBotMsgSpell()
{
}
};
int SCRIPT_Spell ( struct lua_State *L )
{
int n = lua_gettop(L); // number of arguments
_CID( SPELL );
KBotMsgSpell msg;
g_pSBotMng->Perform( id_SPELL, msg );
return NULL;
}
int SCRIPT_Skill ( struct lua_State *L )
{
int n = lua_gettop(L); // number of arguments
return NULL;
}
int SCRIPT_Attack( struct lua_State *L )
{
int n = lua_gettop(L); // number of arguments
return NULL;
}
int SCRIPT_Move ( struct lua_State *L )
{
int n = lua_gettop(L); // number of arguments
return NULL;
}
SGame * GetActGame()
{
SBot * pBot = g_pSBotMng->GetCurBot();
if( !pBot ) return NULL;
SGame * pGame = pBot->GetActiveGame();
if( !pGame ) return NULL;
return pGame;
}
//Play Sound
int SCRIPT_PlaySound( struct lua_State *L )
{
static KHash< char, hashPr_string_nocase > s_InvalidSoundHash;
int nArgCnt = lua_gettop(L);
if( nArgCnt < 5 ) return 0;
const char * pFileName = lua_tostring( L, 1 ); //Sound 화일 이름 : .wav 이름 - string
int nPlayID = lua_tonumber( L, 2 ); //PlayID : 0/normal, 1/Loop
int nVolume = lua_tonumber( L, 3 ); //Volume : 0 설정 안함
int nUse3D = lua_tonumber( L, 4 ); //Use 3D : On/Off - number
bool bSoundOption[3];
bSoundOption[0] = false;
bSoundOption[1] = false;
bSoundOption[2] = false;
if( s_InvalidSoundHash.has( pFileName ) ) return 0;
bool bUse3D = nUse3D ? true : false;
AR_HANDLE target = lua_tonumber( L, 5 ); //Target ID : 맞을넘 ID
SGame * pGame = GetActGame();
// _oprint( "SCRIPT_PlaySound : %s\n", pFileName );
if( pGame )
{
SGameObject * pObject = pGame->GetGameObject(target);
if( pObject )
{
if( pGame->StartSound( NULL, pFileName, *pObject->GetPosition(), bUse3D, nVolume, false, bSoundOption ) < 0 )
{
s_InvalidSoundHash.add( pFileName, 1 );
_oprint( "play sound ERROR : %s\n", pFileName );
return 0;
}
else
{
// if( !strstr( pFileName, "walk" ) && !strstr( pFileName, "run" ) ) _oprint( "play Sound : %s\n", pFileName );
}
//피격 테스트
if( pGame->GetCheatMode() == SGame::CHEAT_MODE01 || pGame->GetCheatMode() == SGame::CHEAT_MODE02 )
{
if( strstr(pFileName, "beattack") )
pGame->StartSound( NULL, "soul_shot.wav", *pObject->GetPosition(), bUse3D, nVolume, false, bSoundOption );
}
}
}
return 0;
}
//Play FX
int SCRIPT_PlayFX( struct lua_State *L )
{
//int nArgCnt = lua_gettop(L);
//if( nArgCnt < 7 ) return 0;
//const char * pFileName = lua_tostring( L, 1 ); //FX 화일 이름 : .nx3 이름 - string
//int nPlay = lua_tonumber( L, 2 ); //Play 방법 : 기본, 루프 - number
//int nPlaySpeed = lua_tonumber( L, 3 ); //Play 속도 : 1(기본) - number
//int nDir = lua_tonumber( L, 4 ); //방향 : On/Off - number
//int nPartID = lua_tonumber( L, 5 ); //위치2 : 세부 위치 - number 바닥, 오른발, 왼발, 왼손, 오른손, 가슴, 허리, 머리
//AR_HANDLE owner = lua_tonumber( L, 6 ); //Caster ID : 쏜 넘 ID
//AR_HANDLE caster = lua_tonumber( L, 7 ); //Caster ID : 쏜 넘 ID
//AR_HANDLE target = lua_tonumber( L, 8 ); //Target ID : 맞을 넘 ID
//float fPlayRate = lua_tonumber( L, 9 ); //fPlayRate 의 배속 비율 기본 1배
//if( fPlayRate <= 0.f )
// fPlayRate = 1.f;
//fPlayRate *= 4.8f;
//int nFlag = lua_tonumber( L, 10 ); //따라 다니기 : 0, 1
//SGame * pGame = GetActGame();
//if( pFileName == NULL )
//{
// assert( pFileName && "스크립트 이상 - 화일 이름 없음" );
// return 0;
//}
//if( pGame )
//{
// //if( strstr(pFileName,"default") )
// // nFlag = 1;
// pGame->AddEffect( pFileName, nFlag, owner, caster, target, nPartID, SGameObject::SEQTYPE_NORMAL, fPlayRate );
//}
return 0;
}
int SCRIPT_GetGroundMaterial( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 ); //Handle
//현재 땅 텍스쳐 얻기
int nResult = 0;
int nTileID = 0;
SGame * pGame = GetActGame();
if( pGame )
{
SGameObject * pPlayer = pGame->GetGameObject( handle );
if( pPlayer )
{
bool bInWater = pPlayer->GetGroundMaterial( nTileID );
nResult = GetGroundMaterialResDB().GetGroundMaterialID( nTileID );
if( bInWater ) nResult += 100; //물 + 재질
}
}
lua_pushnumber( L, nResult );
return 1;
}
int SCRIPT_GetItemClass( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 ); //Handle
int nResult = 0;
SGame * pGame = GetActGame();
if( pGame )
{
SGameObject * pPlayer = pGame->GetGameObject( handle );
if( pPlayer )
{
nResult = pPlayer->GetItemClass();
}
}
lua_pushnumber( L, nResult );
return 1;
}
int SCRIPT_GetMaterial ( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 ); //Handle
int nResult = 0;
SGame * pGame = GetActGame();
if( pGame )
{
SGameObject * pPlayer = pGame->GetGameObject( handle );
if( pPlayer )
{
nResult = pPlayer->GetMaterial();
}
}
lua_pushnumber( L, nResult );
return 1;
}
int SCRIPT_GetMovingType( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 ); //Handle
int nResult = 0;
SGame * pGame = GetActGame();
if( pGame )
{
SGameObject * pPlayer = pGame->GetGameObject( handle );
if( pPlayer )
{
nResult = pPlayer->GetMovingType();
}
}
lua_pushnumber( L, nResult );
return 1;
}
int SCRIPT_FX( struct lua_State *L )
{
// PlayFX(FX_ID, target, playPosition, playTime)
// Play the sound effect simultaneously
int nArgCnt = lua_gettop(L);
if( nArgCnt < 6 ) return 0;
FX_DATA fx_data;
fx_data.owner = lua_tonumber( L, 1 ); // Playback target (owner of the effect)
fx_data.attack = lua_tonumber( L, 2 );
fx_data.target = lua_tonumber( L, 3 );
fx_data.nFX_ID = lua_tonumber( L, 4 );
fx_data.nEffPos = lua_tonumber( L, 5 ); // Types of playback positions -> 0: Head, 1: Center, 2: Damage point, 3: Ground, 5: Left hand, 6: Right hand, 7: Both hands
fx_data.nPlayID = lua_tonumber( L, 6 ); // Playback time → 0: Instant, -1: Infinite, greater than 0: Specified duration (in seconds)
// _oprint( "PlayFX : [FX_ID:%d] [owner:%u] [attack:%u] [target:%u] [EffPos:%d] [PlayID:%d]\n", fx_data.nFX_ID, fx_data.owner, fx_data.attack, fx_data.target, fx_data.nEffPos, fx_data.nPlayID );
SGame * pGame = GetActGame();
if( pGame )
{
pGame->AddEffect( &fx_data );
}
return 1;
}
int SCRIPT_ATTACK_FX( struct lua_State *L )
{
int nArgCnt = lua_gettop(L);
if( nArgCnt < 7 ) return 0;
FX_DATA fx_data;
fx_data.attack = lua_tonumber( L, 1 );
fx_data.owner = lua_tonumber( L, 2 );
fx_data.target = lua_tonumber( L, 2 );
fx_data.nFX_ID = lua_tonumber( L, 3 );
fx_data.nEffPos = lua_tonumber( L, 4 );
fx_data.nPlayID = lua_tonumber( L, 5 );
fx_data.keyhandleid = lua_tonumber( L, 6 );
fx_data.keytime = lua_tonumber( L, 7 );
SGame * pGame = GetActGame();
if( pGame )
{
pGame->AddAttackEffect( &fx_data );
}
return 1;
}
// Fraun performance tweak
void Noscript_PlayFX(AR_HANDLE& owner_handle, AR_HANDLE& attack_handle, AR_HANDLE& target_handle, int& nMaterial, int& nWeaponClass, bool& bIsCritical, bool& bIsBlock, int& nKeyHandleID, int& nKeyTime)
{
int nResultFX = 0;
switch (nWeaponClass)
{
case 101: case 102: case 103:
{
switch (nMaterial)
{
case 2:
{
nResultFX = 17005;
break;
}
case 3:
{
nResultFX = 17001;
break;
}
case 4:
{
nResultFX = 17017;
break;
}
case 5:
{
nResultFX = 17009;
break;
}
case 6:
{
nResultFX = 17021;
break;
}
default:
{
nResultFX = 17013;
break;
}
}
break;
}
case 111:
{
nResultFX = 17049;
break;
}
default:
{
switch (nMaterial)
{
case 2:
{
nResultFX = 17029;
break;
}
case 3:
{
nResultFX = 17025;
break;
}
case 4:
{
nResultFX = 17041;
break;
}
case 5:
{
nResultFX = 17033;
break;
}
case 6:
{
nResultFX = 17045;
break;
}
default:
{
nResultFX = 17037;
break;
}
}
break;
}
}
bIsCritical ? nResultFX += 3 : nResultFX += XRandom(0, 2);
FX_DATA fx_data;
fx_data.owner = owner_handle;
fx_data.attack = attack_handle;
fx_data.target = target_handle;
fx_data.nFX_ID = nResultFX;
fx_data.nEffPos = 2;
fx_data.nPlayID = 0;
fx_data.keyhandleid = nKeyHandleID;
fx_data.keytime = nKeyTime;
SGame* pGame = GetActGame();
if (pGame)
{
pGame->AddAttackEffect(&fx_data);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//////
int SCRIPT_GetHP( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 );
SGame* pGame = GetActGame();
int nHP = 0;
if( pGame ) nHP = pGame->GetSelectedState( handle, GET_HP );
lua_pushnumber( L, nHP );
return 1;
}
int SCRIPT_GetMP( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 );
SGame* pGame = GetActGame();
int nMP = 0;
if( pGame ) nMP = pGame->GetSelectedState( handle, GET_MP );
lua_pushnumber( L, nMP );
return 1;
}
int SCRIPT_GetMax_HP( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 );
SGame* pGame = GetActGame();
int nMaxHP = 0;
if( pGame ) nMaxHP = pGame->GetSelectedState( handle, GET_MAXHP );
lua_pushnumber( L, nMaxHP );
return 1;
}
int SCRIPT_GetMax_MP( struct lua_State *L )
{
AR_HANDLE handle = lua_tonumber( L, 1 );
SGame* pGame = GetActGame();
int nMaxMP = 0;
if( pGame ) nMaxMP = pGame->GetSelectedState( handle, GET_MAXMP );
lua_pushnumber( L, nMaxMP );
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//////크리처 동작 관련
int SCRIPT_C_Standby( struct lua_State *L )
{
STRUCT_CREATURE_CMD_SCRIPT StandBy;
StandBy.nCmdScipt = STRUCT_CREATURE_CMD_SCRIPT::CMD_STANDBY;
StandBy.cHandle = lua_tonumber( L, 1 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SendCreatureCmdScript( StandBy );
return 1;
}
int SCRIPT_C_Move( struct lua_State *L )
{
STRUCT_CREATURE_CMD_SCRIPT Move;
Move.nCmdScipt = STRUCT_CREATURE_CMD_SCRIPT::CMD_MOVE;
Move.cHandle = lua_tonumber( L, 1 );
Move.nCreaturePosition = lua_tonumber( L, 2 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SendCreatureCmdScript( Move );
return 1;
}
int SCRIPT_C_Idle( struct lua_State *L )
{
STRUCT_CREATURE_CMD_SCRIPT Idle;
Idle.nCmdScipt = STRUCT_CREATURE_CMD_SCRIPT::CMD_IDLE;
Idle.cHandle = lua_tonumber( L, 1 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SendCreatureCmdScript( Idle );
return 1;
}
int SCRIPT_C_Attack( struct lua_State *L )
{
STRUCT_CREATURE_CMD_SCRIPT Attack;
Attack.nCmdScipt = STRUCT_CREATURE_CMD_SCRIPT::CMD_ATTACK;
Attack.cHandle = lua_tonumber( L, 2 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SendCreatureCmdScript( Attack );
return 1;
}
int SCRIPT_C_Skill( struct lua_State *L )
{
STRUCT_CREATURE_CMD_SCRIPT Skill;
Skill.nCmdScipt = STRUCT_CREATURE_CMD_SCRIPT::CMD_SKILL;
Skill.mHandle = lua_tonumber( L, 1 );
Skill.cHandle = lua_tonumber( L, 2 );
Skill.nSlotNum = lua_tonumber( L, 3 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SendCreatureCmdScript( Skill );
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//////지역 관련
int SCRIPT_LC_In( struct lua_State *L )
{
int nLocalID = lua_tonumber( L, 1 );
SGame * pGame = GetActGame();
if( pGame ) pGame->SetLocalInfo( nLocalID );
return 1;
}
int SCRIPT_LC_Out( struct lua_State *L )
{
SGame * pGame = GetActGame();
if( pGame ) pGame->SetWorldInfo();
return 1;
}
int SCRIPT_LC_Local( struct lua_State *L )
{
return 1;
}
int SCRIPT_LC_World( struct lua_State *L )
{
return 1;
}
// { [sonador] 날씨 관련 스크립트
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//날씨 관련
namespace env_fx
{
struct TLuaOpen
{
TLuaOpen( lua_State* _L ) : L( _L )
{
L = luaL_newstate();
luaopen_base ( L );
luaopen_math ( L );
luaopen_string ( L );
luaopen_table ( L );
if( !L )
{
assert( 0 && "lua_open() FAILED!!" );
}
}
~TLuaOpen()
{
lua_close( L );
}
lua_State* L;
};
#define tlua_open( _L, id ) env_fx::TLuaOpen TLua_open##id( _L ); lua_State* tlua_##id = TLua_open##id.L
struct TLuaOpenTable
{
TLuaOpenTable( lua_State* _L, const char* table )
: L( _L )
{
lua_pushstring( L, table );
lua_gettable( L, -2 );
}
~TLuaOpenTable()
{
lua_pop( L, 1 );
}
lua_State* L;
};
#define tlua_opentable( _L, table ) env_fx::TLuaOpenTable TLua_opentable( _L, table )
struct TLuaHasField
{
bool operator () ( lua_State* L, const char* key ) const
{
bool result;
lua_pushstring( L, key );
lua_gettable( L, -2 );
if( lua_isnil( L, -1 ) ) result = false;
else result = true;
lua_pop( L, 1 );
return result;
}
};
#define tlua_hasfield( _L, key ) env_fx::TLuaHasField()( _L, key )
struct TLuaGetField
{
template< typename _Ty >
void operator () ( lua_State* L, const char* key, _Ty& result ) const
{
lua_pushstring( L, key );
lua_gettable( L, -2 );
result = static_cast< _Ty >( lua_tonumber( L, -1 ) );
lua_pop( L, 1 );
}
template<>
void operator () ( lua_State* L, const char* key, bool& result ) const
{
lua_pushstring( L, key );
lua_gettable( L, -2 );
result = !!lua_toboolean( L, -1 );
lua_pop( L, 1 );
}
template<>
void operator () ( lua_State* L, const char* key, std::string& result ) const
{
lua_pushstring( L, key );
lua_gettable( L, -2 );
result = lua_tostring( L, -1 );
lua_pop( L, 1 );
}
};
#define tlua_getfield( L, key, result ) env_fx::TLuaGetField()( L, key, result )
struct TLuaGetField_n
{
template< typename _Ty >
void operator () ( lua_State* L, int index, _Ty& result ) const
{
lua_pushnumber( L, index );
lua_gettable( L, -2 );
result = static_cast< _Ty >( lua_tonumber( L, -1 ) );
lua_pop( L, 1 );
}
template<>
void operator () ( lua_State* L, int index, bool& result ) const
{
lua_pushnumber( L, index );
lua_gettable( L, -2 );
result = !!lua_toboolean( L, -1 );
lua_pop( L, 1 );
}
template<>
void operator () ( lua_State* L, int index, std::string& result ) const
{
lua_pushnumber( L, index );
lua_gettable( L, -2 );
result = lua_tostring( L, -1 );
lua_pop( L, 1 );
}
};
#define tlua_getfield_n( L, index, result ) env_fx::TLuaGetField_n()( L, index, result )
struct TLuaGetFieldArray
{
template< typename _ct >
void operator () ( lua_State* _L, _ct& container )
{
int array_size = luaL_getn( _L, -1 );
for( int n = 1; n <= array_size; ++n )
{
_ct::value_type result;
tlua_getfield_n( _L, n, result );
container.push_back( result );
}
}
};
#define tlua_getfield_array( _L, _container ) env_fx::TLuaGetFieldArray()( _L, _container )
}
int SCRIPT_WEATHER_GetTheme( struct lua_State* L )
{
SGame* pGame = GetActGame();
int nWeatherTheme = 0;
if( pGame ) nWeatherTheme = pGame->GetWeatherTheme();
lua_pushnumber( L, nWeatherTheme );
return 1;
}
void SCRIPT_WEATHER_GetAttribute( env_fx::SWeatherAttr& Attr, lua_State* L, const char* table )
{
tlua_opentable( L, table );
// area information
if( tlua_hasfield( L, "area" ) )
{
tlua_opentable( L, "area" );
tlua_getfield( L, "swap" , Attr.area_swap );
tlua_getfield( L, "width" , Attr.area_width );
tlua_getfield( L, "height" , Attr.area_height );
}
// particle information
if( tlua_hasfield( L, "particle" ) )
{
tlua_opentable( L, "particle" );
tlua_getfield( L, "vert_density" , Attr.vert_density );
tlua_getfield( L, "hori_density" , Attr.hori_density );
tlua_getfield( L, "life" , Attr.particle_life );
tlua_getfield( L, "destroy_duration" , Attr.destroy_duration );
{
tlua_opentable( L, "direction" );
{
tlua_opentable( L, "x" );
tlua_getfield( L, "min" , Attr.particle_direction.min.x );
tlua_getfield( L, "max" , Attr.particle_direction.max.x );
}
{
tlua_opentable( L, "y" );
tlua_getfield( L, "min" , Attr.particle_direction.min.y );
tlua_getfield( L, "max" , Attr.particle_direction.max.y );
}
{
tlua_opentable( L, "z" );
tlua_getfield( L, "min" , Attr.particle_direction.min.z );
tlua_getfield( L, "max" , Attr.particle_direction.max.z );
}
}
tlua_getfield( L, "velocity" , Attr.particle_velocity );
tlua_getfield( L, "visibility_min" , Attr.visibility_min );
tlua_getfield( L, "visibility_mid" , Attr.visibility_mid );
tlua_getfield( L, "visibility_max" , Attr.visibility_max );
tlua_getfield( L, "visible_range_mid" , Attr.visible_range_mid );
tlua_getfield( L, "visible_range_end" , Attr.visible_range_end );
tlua_getfield( L, "rotation_unit" , Attr.rotation_unit );
tlua_getfield( L, "rotation_speed" , Attr.rotation_speed );
tlua_getfield( L, "collision_max" , Attr.collision_max );
tlua_getfield( L, "collision_factor" , Attr.collision_factor );
tlua_getfield( L, "capacity" , Attr.capacity );
tlua_getfield( L, "emit_per_millisec" , Attr.emit_per_millisec );
}
// resource information
if( tlua_hasfield( L, "resource" ) )
{
tlua_opentable( L, "resource" );
if( tlua_hasfield( L, "texture" ) )
{
Attr.resource_type = env_fx::SWeatherAttr::TEXTURE;
tlua_getfield( L, "texture" , Attr.resource );
tlua_getfield( L, "width" , Attr.particle_width );
tlua_getfield( L, "height" , Attr.particle_height );
tlua_getfield( L, "count" , Attr.sprite_count );
tlua_getfield( L, "row" , Attr.sprite_row );
tlua_getfield( L, "col" , Attr.sprite_col );
}
else if( tlua_hasfield( L, "nx3" ) )
{
Attr.resource_type = env_fx::SWeatherAttr::NX3;
tlua_getfield( L, "nx3", Attr.resource );
}
else
{
Attr.resource_type = env_fx::SWeatherAttr::NONE;
}
}
}
int SCRIPT_WEATHER_SetTheme( struct lua_State* L )
{
using namespace env_fx;
SWeatherInfo* pInfo = new env_fx::SWeatherInfo();
// now table 'weather_theme.xxxx' is on the top of stack
env_fx::SWeatherAttr** ppCurrAttr = &pInfo->m_pWeatherAttr;
*ppCurrAttr = new env_fx::SWeatherAttr();
// weather state
tlua_getfield( L, "id", pInfo->m_nThemeID );
// weather fx
tlua_getfield( L, "state_fade_duration" , pInfo->m_pWeatherAttr->state_fade_duration );
// sound
tlua_getfield( L, "sound", pInfo->m_strSound );
// sky
{
tlua_opentable( L, "sky" );
tlua_getfield( L, "type" , pInfo->m_nSkyType );
tlua_getfield( L, "thunder" , pInfo->m_bThunder );
tlua_getfield( L, "lightning" , pInfo->m_bLightning );
}
// fx[n]
int nId = 0;
while( true )
{
nId++;
std::string table;
XStringUtil::Format( table, "fx%d", nId );
if( !tlua_hasfield( L, table.c_str() ) ) break;
if( *ppCurrAttr == 0 ) *ppCurrAttr = new env_fx::SWeatherAttr();
SCRIPT_WEATHER_GetAttribute( **ppCurrAttr, L, table.c_str() );
ppCurrAttr = &(*ppCurrAttr)->linked_attr;
}
// send attribute to game world
SGame* pGame = 0;
pGame = GetActGame();
if( pGame ) pGame->SetWeatherTheme( pInfo );
else SAFE_DELETE( pInfo );
return 0;
}
int SCRIPT_WEATHER_SetThunderAttribute( struct lua_State* L )
{
using namespace env_fx;
SThunderAttr attr;
{
tlua_getfield( L, "factor" , attr.fFactor );
tlua_getfield( L, "lightning_factor", attr.fLightningFactor );
tlua_getfield( L, "duration" , attr.dwDuration );
tlua_getfield( L, "flash_count" , attr.nFlashCount );
{
tlua_opentable( L, "color" );
KColor temp;
tlua_getfield( L, "r", temp.r );
tlua_getfield( L, "g", temp.g );
tlua_getfield( L, "b", temp.b );
tlua_getfield( L, "a", temp.a );
attr.sColor = K3DColor( temp );
}
tlua_getfield( L, "sound" , attr.strSound );
tlua_getfield( L, "speed_of_sound" , attr.fSpeedOfSound );
}
SGame* pGame = 0;
pGame = GetActGame();
if( pGame ) pGame->SetThunderAttribute( &attr );
return 0;
}
int SCRIPT_WEATHER_SetLightningAttribute( struct lua_State* L )
{
using namespace env_fx;
SLightningAttr attr;
{
tlua_getfield( L, "visible_distance" , attr.fVisibleDistance );
tlua_getfield( L, "twinling_duration" , attr.dwLife_msec_ );
tlua_getfield( L, "fade_out_duration" , attr.dwFadeOut_msec_ );
tlua_getfield( L, "twinkling_count" , attr.nTwinklingCount );
{
tlua_opentable( L, "color" );
tlua_getfield( L, "r", attr.dwColor.r );
tlua_getfield( L, "g", attr.dwColor.g );
tlua_getfield( L, "b", attr.dwColor.b );
tlua_getfield( L, "a", attr.dwColor.a );
}
tlua_getfield( L, "height" , attr.fHeight );
tlua_getfield( L, "width" , attr.fWidth );
{
tlua_opentable( L, "textures" );
tlua_getfield_array( L, attr.strTextures );
}
}
SGame* pGame = 0;
pGame = GetActGame();
if( pGame ) pGame->SetLightningAttribute( &attr );
return 0;
}
int SCRIPT_ENVIRONMENT_GetAttribute( struct lua_State* L )
{
SGame* game = 0;
game = GetActGame();
if( game )
{
// fog setting
{
tlua_opentable( L, "fog_color" );
KColor fogColor;
tlua_getfield( L, "r", fogColor.r );
tlua_getfield( L, "g", fogColor.g );
tlua_getfield( L, "b", fogColor.b );
tlua_getfield( L, "a", fogColor.a );
game->Game_Fog_Color( fogColor.r, fogColor.g, fogColor.b, fogColor.a );
}
int fog_unit;
tlua_getfield( L, "fog_h_start", fog_unit );
game->Game_Fog_Height_Start( fog_unit );
tlua_getfield( L, "fog_h_end", fog_unit );
game->Game_Fog_Height_End( fog_unit );
tlua_getfield( L, "fog_l_start", fog_unit );
game->Game_Fog_Linear_Start( fog_unit );
tlua_getfield( L, "fog_l_end", fog_unit );
game->Game_Fog_Linear_End( fog_unit );
// sky setting
{
tlua_opentable( L, "sky_color_start" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Sky_Color_Start( color.r, color.g, color.b );
}
{
tlua_opentable( L, "sky_color_mid" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Sky_Color_Mid( color.r, color.g, color.b );
}
{
tlua_opentable( L, "sky_color_end" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Sky_Color_End( color.r, color.g, color.b );
}
// cloud color
{
tlua_opentable( L, "cloud_color" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Cloud_Color( color.r, color.g, color.b, color.a );
}
// light setting
{
tlua_opentable( L, "light_ambient" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Light( 2, K3DColor( color ) );
}
{
tlua_opentable( L, "light_diffuse" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Light( 0, K3DColor( color ) );
}
{
tlua_opentable( L, "light_specular" );
KColor color;
tlua_getfield( L, "r", color.r );
tlua_getfield( L, "g", color.g );
tlua_getfield( L, "b", color.b );
tlua_getfield( L, "a", color.a );
game->Game_Light( 1, K3DColor( color ) );
}
// terrain factor setting
float terrain_specular_factor;
tlua_getfield( L, "terrain_specular_factor", terrain_specular_factor);
game->Game_Terrain_Specular( terrain_specular_factor );
// character factor setting
float character_skin_ambient_factor, character_skin_diffuse_factor;
tlua_getfield( L, "character_skin_ambient_factor", character_skin_ambient_factor );
tlua_getfield( L, "character_skin_diffuse_factor", character_skin_diffuse_factor );
game->Game_CharSkin_Color( character_skin_ambient_factor, character_skin_diffuse_factor );
// volume setting
float volume_dry, volume_wet;
tlua_getfield( L, "volume_dry", volume_dry );
tlua_getfield( L, "volume_wet", volume_wet );
game->Game_DryWet_Volume( volume_dry, volume_wet );
}
return 0;
}
// } [sonador]
namespace
{
//타입이 많아 지면 템플릿으로 만들자
void setfield( struct lua_State* L, const char* index, int value )
{
lua_pushstring( L, index );
lua_pushnumber( L, value );
lua_settable( L, -3 );
}
bool getfield( struct lua_State* L, const char* key, int& value )
{
lua_pushstring( L, key );
lua_gettable( L, -2 );
if( lua_isnumber( L, -1 ) == false )
return false;
value = lua_tonumber( L, -1 );
lua_pop( L, 1 );
return true;
}
void setglobal_number( struct lua_State* L, const char* globalname, int val )
{
lua_pushnumber( L, val );
lua_setglobal( L, globalname );
}
void getglobal_number( struct lua_State* L, const char* globalname, int& val )
{
lua_getglobal( L, globalname );
val = lua_tonumber( L, -1 );
lua_pop( L, 1 );
}
};
int SCRIPT_UIWINDOWS_InitAddonList( struct lua_State* L )
{
/* lua_newtable( L );
setfield( L, "left_click", CLICK_TYPE::LEFT_CLICK );
setfield( L, "right_click", CLICK_TYPE::RIGHT_CLICK );
setfield( L, "center_click", CLICK_TYPE::CENTER_CLICK );
lua_setglobal( L, "open_by_click" );*/
setglobal_number( L, "lbutton_up", KLBUTTON_UP );
setglobal_number( L, "lbutton_down", KLBUTTON_DOWN );
setglobal_number( L, "rbutton_up", KRBUTTON_UP );
setglobal_number( L, "rbutton_down", KRBUTTON_DOWN );
setglobal_number( L, "wheel_up", KWHEEL_UP );
setglobal_number( L, "wheel_down", KWHEEL_DOWN );
setglobal_number( L, "lbutton_dblclk", KLBUTTON_DBLCLK );
setglobal_number( L, "rbutton_dblclk", KRBUTTON_DBLCLK );
/* setglobal_number( L, "mouse", SIMSG_TOGGLE_UIWINDOW::MOUSE_POS );
setglobal_number( L, "center", SIMSG_TOGGLE_UIWINDOW::CENTER_POS );
setglobal_number( L, "left_in", SIMSG_TOGGLE_UIWINDOW::LEFT_IN_POS );
setglobal_number( L, "left_out", SIMSG_TOGGLE_UIWINDOW::LEFT_OUT_POS );
setglobal_number( L, "right_in", SIMSG_TOGGLE_UIWINDOW::RIGHT_IN_POS );
setglobal_number( L, "right_out", SIMSG_TOGGLE_UIWINDOW::RIGHT_OUT_POS );
setglobal_number( L, "top_in", SIMSG_TOGGLE_UIWINDOW::TOP_IN_POS );
setglobal_number( L, "top_out", SIMSG_TOGGLE_UIWINDOW::TOP_OUT_POS );
setglobal_number( L, "bottom_in", SIMSG_TOGGLE_UIWINDOW::BOTTOM_IN_POS );
setglobal_number( L, "bottom_out", SIMSG_TOGGLE_UIWINDOW::BOTTOM_OUT_POS );*/
return 1;
}
int SCRIPT_UIWINDOWS_CreateAddOn( struct lua_State* L )
{
/* lua_getglobal( L, "open_by_click" );
if( lua_istable( L, -1 ) )
{
int left_click, right_click, center_click;
getfield( L, "left_click", left_click );
getfield( L, "right_click", right_click );
getfield( L, "center_click", center_click );
}*/
/* lua_getglobal( L, "left_click" );
int left = lua_tonumber( L, -1 );
lua_pop( L, 1 );
lua_getglobal( L, "right_click" );
int right = lua_tonumber( L, -1 );
lua_pop( L, 1 );
lua_getglobal( L, "center_click" );
int center = lua_tonumber( L, -1 );
lua_pop( L, 1 );*/
int argcnt = lua_gettop(L);
if( argcnt < 5 ) return 0;
SIMSG_UI_WINDOW_ADDON msg;
msg.main_window_name = lua_tostring( L, 1 );
msg.addon_window_name = lua_tostring( L, 2 );
if( lua_type( L, 3 ) == LUA_TSTRING )
msg.c_position_x = lua_tostring( L, 3 );
else
msg.n_position_x = lua_tonumber( L, 3 );
if( lua_type( L, 4 ) == LUA_TSTRING )
msg.c_position_y = lua_tostring( L, 4 );
else
msg.n_position_y = lua_tonumber( L, 4 );
msg.open_type = lua_tonumber( L, 5 );
for( int x = 6; x <= argcnt; ++x )
{
//Number면 복사 컨트롤들
if( lua_type( L, x ) == LUA_TNUMBER )
{
int ctrlsize = lua_tonumber( L, x );
if( (x+1) <= argcnt )
{
if( lua_type( L, (x+1) ) == LUA_TSTRING ) //컨트롤 사이즈가 다음은 컨트롤 네임이 와야 한다
{
std::string strControl = lua_tostring( L, (x+1) );
for( int size = 0; size < ctrlsize; ++size )
{
msg.vControlList.push_back( CStringUtil::StringFormat("%s%02d", strControl.c_str(), size ) );
}
}
}
}
else
{
msg.vControlList.push_back( lua_tostring( L, x ) );
}
}
SGame* pGame = GetActGame();
if( pGame ) pGame->SendGameInterfaceMsg( &msg );
return 1;
}
#ifdef DISTANCE_VIEW
int SCRIPT_SKYBOX_SetTheme_sky( struct lua_State* L )
{
using namespace env_fx;
int k=0;
env_fx::SSkyBoxAttr* pAttr = new env_fx::SSkyBoxAttr;
// cloud
tlua_getfield( L, "type_cloud", pAttr->type_cloud );
tlua_getfield( L, "appear_zone_width", pAttr->appear_zone_width );
tlua_getfield( L, "appear_zone_height", pAttr->appear_zone_height );
tlua_getfield( L, "count_cloud", pAttr->count_cloud );
tlua_getfield( L, "appear_layer", pAttr->appear_layer);
tlua_getfield( L, "size_cloud", pAttr->size_cloud);
tlua_getfield( L, "tickness_cloud", pAttr->tickness_cloud);
tlua_getfield( L, "dir_move_cloud", pAttr->dir_move_cloud);
// send attribute to game world
SGame* pGame = 0;
pGame = GetActGame();
if( pGame )
pGame->SetSkyThemeInfo( pAttr );
else
SAFE_DELETE( pAttr );
return 1;
}
int SCRIPT_SKYBOX_SetTheme_distanceView( struct lua_State* L )
{
// send attribute to game world
SGame* pGame = GetActGame();
if( pGame == NULL )
return 0;
int local_id;
tlua_getfield( L, "local_id", local_id);
pGame->ChangeDistanceView( local_id );
return 1;
}
int SCRIPT_SKYBOX_load_localmodelinfo( struct lua_State* L )
{
env_fx::SDistanceViewAttr* pAttr = new env_fx::SDistanceViewAttr;
// distance view model info table
int num = 0;
tlua_getfield( L, "data_num", num);
pAttr->vcLocalModel.resize( num );
for(int x=0; x<num; x++)
{
env_fx::SLocalModelInfo* pLM = new env_fx::SLocalModelInfo;
std::string table;
XStringUtil::Format( table, "data_%03d", x );
if( tlua_hasfield( L, table.c_str() ) )
{
tlua_opentable( L, table.c_str() );
tlua_getfield( L, "local_id", pLM->local_id);
tlua_getfield( L, "model_name", pLM->model_name);
tlua_getfield( L, "cloud_type", pLM->cloud_type);
}
pAttr->vcLocalModel[x] = pLM;
}
// send attribute to game world
SGame* pGame = 0;
pGame = GetActGame();
if( pGame )
pGame->SetDistanceViewInfo( pAttr );
else
SAFE_DELETE( pAttr );
return 1;
}
#endif
#ifdef CLOUD_LUA
/*
int SCRIPT_CLOUD_LoadClouInfo( struct lua_State* L )
{
CCloudKindMgr* pCloudKindMgr = GetCloudKindMgr();
int count = 0;
tlua_getfield( L, "kind_count", count);
pCloudKindMgr->size( count );
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "kind%02d", y );
SCloudKind* pCK = new SCloudKind;
if( tlua_hasfield( L, table.c_str() ) )
{
tlua_opentable( L, table.c_str() );
for(int x=0; x<count; x++)
{
int volume = 0;
std::string field;
XStringUtil::Format( field, "t%02d", x );
tlua_getfield( L, field.c_str(), volume );
pCK->v[ x ] = volume;
}
}
pCloudKindMgr->add( y, pCK );
}
return 1;
}
*/
#define CLOUD_MOVE_SPEED_MAX 100.0f
#define CLOUD_SHOW_RATE_MAX 100
void ERROR_MSGBOX_CLOUD_LUA( const char *fmt, ... )
{
char p[2048];
va_list ap;
va_start(ap, fmt);
_vsnprintf(p, 2048, fmt, ap);
va_end(ap);
MessageBox(NULL, p, "cloud_script.lua 파일 내용 확인바랍니다", MB_OK);
}
int SCRIPT_CLOUD_LoadKind( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "kind_count", count);
GetCloudKindDB().clear();
// GetCloudKindDB().size( count );
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "kind%02d", y );
SCloudKind* pCK = new SCloudKind;
if( tlua_hasfield( L, table.c_str() ) )
{
tlua_opentable( L, table.c_str() );
for(int x=0; x<9; x++) // 루아 파일에 9개로 고정되어있다
{
int volume = 0;
std::string field;
XStringUtil::Format( field, "t%02d", x );
tlua_getfield( L, field.c_str(), volume );
if( volume < 0 || volume >= 200 )
{
GetCloudKindDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_kind: %s : %s : %d\nThe value of this parameter is in the range of (min 0 ~ max 200).", table.c_str(), field.c_str(), volume );
return 0;
}
pCK->v[ x ] = volume;
}
}
GetCloudKindDB().add( y, pCK );
}
return 1;
}
int SCRIPT_CLOUD_LoadThickness( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "thickness_count", count);
GetCloudThicknessDB().clear();
// GetCloudThicknessDB().size( count );
for(int y=0; y<count; y++)
{
int nTickness = 0;
std::string field;
XStringUtil::Format( field, "thickness%02d", y );
tlua_getfield( L, field.c_str(), nTickness );
if( nTickness < 0 || nTickness >= 100 )
{
GetCloudThicknessDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_thickness: %s : %d\nThe value of this parameter is in the range of (min 0 ~ max 200).", field.c_str(), nTickness );
return 0;
}
GetCloudThicknessDB().add( y, nTickness );
}
return 1;
}
int SCRIPT_CLOUD_LoadThicknessGap( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "gap_count", count);
GetCloudThicknessGapDB().clear();
// GetCloudThicknessGapDB().size( count );
for(int y=0; y<count; y++)
{
float fTickness = 0;
std::string field;
XStringUtil::Format( field, "gap%02d", y );
tlua_getfield( L, field.c_str(), fTickness );
if( fTickness < 0.0f || fTickness >= 1000.0f )
{
GetCloudThicknessGapDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_thickness_gap: %s : %f\nThe value of this parameter is in the range of (min 0 ~ max 1000).", field.c_str(), fTickness );
return 0;
}
GetCloudThicknessGapDB().add( y, fTickness );
}
return 1;
}
int SCRIPT_CLOUD_LoadSize( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "size_count", count);
GetCloudSizeDB().clear();
// GetCloudSizeDB().size( count );
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "size%02d", y );
tlua_opentable( L, table.c_str() );
SCloudSize* pSZ = new SCloudSize;
tlua_getfield( L, "s", pSZ->s );
tlua_getfield( L, "e", pSZ->e );
if( pSZ->s < 0 || pSZ->s >= 4000 )
{
GetCloudSizeDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_size : %s : s : %f\nThe value of this parameter is in the range of (min 0 ~ max 4000).", table.c_str(), pSZ->s );
return 0;
}
if( pSZ->e < 0 || pSZ->e >= 4000 )
{
GetCloudSizeDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_size : %s : e : %f\nThe value of this parameter is in the range of (min 0 ~ max 4000).", table.c_str(), pSZ->e );
return 0;
}
if( pSZ->s > pSZ->e )
{
GetCloudSizeDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_size: %s : s (%f) > e (%f)\nThe minimum value (s) is greater than the maximum value (e).\nAre you kidding?!", table.c_str(), pSZ->e );
return 0;
}
GetCloudSizeDB().add( y, pSZ );
}
return 1;
}
int SCRIPT_CLOUD_LoadTextureGroupByType( struct lua_State* L, int nTxrType )
{
if( nTxrType < CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::NORMAL ||
nTxrType > CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::DARK )
return 0;
int count = 0;
tlua_getfield( L, "group_count", count);
GetCloudTxrGroupDB().clear( nTxrType );
// GetCloudTxrGroupDB().size( nTxrType, count );
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "group%02d", y );
tlua_opentable( L, table.c_str() );
CCloudTxrNames* pTxrNames = new CCloudTxrNames;
int nGroupCount=0;
tlua_getfield( L, "txr_count", nGroupCount);
pTxrNames->size( nGroupCount );
for(int x=0; x<nGroupCount; x++)
{
std::string tableTxr;
XStringUtil::Format( tableTxr, "t%02d", x );
std::string* pStr = new std::string;
tlua_getfield( L, tableTxr.c_str(), *pStr );
if( pStr->size() <= 3 )
{
GetCloudTxrGroupDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_texture_group: %s : %s\nThe file name is shorter than 3 characters. Is the file name correct? Is the extension missing?", tableTxr.c_str(), pStr->c_str() );
return 0;
}
pTxrNames->add( x, pStr );
}
GetCloudTxrGroupDB().add( nTxrType, y, pTxrNames );
}
return 1;
}
int SCRIPT_CLOUD_LoadTextureGroup( struct lua_State* L )
{
return SCRIPT_CLOUD_LoadTextureGroupByType( L, CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::NORMAL );
}
int SCRIPT_CLOUD_LoadMiddleTextureGroup( struct lua_State* L )
{
return SCRIPT_CLOUD_LoadTextureGroupByType( L, CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::MIDDLE );
}
int SCRIPT_CLOUD_LoadDarkTextureGroup( struct lua_State* L )
{
return SCRIPT_CLOUD_LoadTextureGroupByType( L, CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::DARK );
}
int SCRIPT_CLOUD_LoadDistribution( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "distribution_count", count);
GetCloudDistributionDB().clear();
// GetCloudDistributionDB().size( count );
for(int y=0; y<count; y++)
{
int nDistribution = 0;
std::string field;
XStringUtil::Format( field, "distribution%02d", y );
tlua_getfield( L, field.c_str(), nDistribution );
if( nDistribution < 0 || nDistribution >= 1000 )
{
GetCloudDistributionDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_distribution: %s : %d\nThe value of this parameter is in the range (min 0 ~ max 200).", field.c_str(), nDistribution );
return 0;
}
GetCloudDistributionDB().add( y, nDistribution );
}
return 1;
}
int SCRIPT_CLOUD_LoadHeightRandomGap( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "gap_count", count);
GetCloudHeightRadomGapDB().clear();
// GetCloudHeightRadomGapDB().size( count );
for(int y=0; y<count; y++)
{
int nGap = 0;
std::string field;
XStringUtil::Format( field, "gap%02d", y );
tlua_getfield( L, field.c_str(), nGap );
if( nGap < 0 || nGap >= 500 )
{
GetCloudHeightRadomGapDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_height_random_gap: %s : %d\nThe value of this parameter is in the range (min 0 ~ max 500).", field.c_str(), nGap );
return 0;
}
GetCloudHeightRadomGapDB().add( y, nGap );
}
return 1;
}
int SCRIPT_CLOUD_LoadLayerGap( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "gap_count", count);
GetCloudLayerGapDB().clear();
// GetCloudLayerGapDB().size( count );
for(int y=0; y<count; y++)
{
int nLayerGap = 0;
std::string field;
XStringUtil::Format( field, "gap%02d", y );
tlua_getfield( L, field.c_str(), nLayerGap );
if( nLayerGap < 0 || nLayerGap >= 65000 )
{
GetCloudLayerGapDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_layer_gap: %s : %d\nThe value of this parameter is in the range (min 0 ~ max 65000).", field.c_str(), nLayerGap );
return 0;
}
GetCloudLayerGapDB().add( y, nLayerGap );
}
return 1;
}
int SCRIPT_CLOUD_LoadMoveDir( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "dir_count", count);
GetCloudMoveDirDB().clear();
// GetCloudMoveDirDB().size( count );
for(int y=0; y<count; y++)
{
int nMoveDir = 0;
std::string field;
XStringUtil::Format( field, "dir%02d", y );
tlua_getfield( L, field.c_str(), nMoveDir );
if( nMoveDir < 0 || nMoveDir > 3 )
{
GetCloudMoveDirDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_move_dir: %s : %d\nThe value of this parameter is in the range (min 0 ~ max 3).", field.c_str(), nMoveDir );
return 0;
}
GetCloudMoveDirDB().add( y, nMoveDir );
}
return 1;
}
int SCRIPT_CLOUD_LoadPath( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "path_count", count);
GetCloudPathDB().clear();
// GetCloudPathDB().size( count );
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "path%02d", y );
tlua_opentable( L, table.c_str() );
SCloudPath* pPath = new SCloudPath;
tlua_getfield( L,"start", pPath->start );
tlua_getfield( L,"maximum", pPath->max );
tlua_getfield( L,"finish", pPath->finish );
if( pPath->start < -4000 || pPath->start >= 5000 )
{
GetCloudPathDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_path: start: %d\nThe value of this parameter is in the range (min -4000 ~ max 5000).", pPath->start );
return 0;
}
if( pPath->max < -4000 || pPath->max >= 7000 )
{
GetCloudPathDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_path: maximum: %d\nThe value of this parameter is in the range (min -4000 ~ max 7000).", pPath->max );
return 0;
}
if( pPath->finish < -4000 || pPath->finish >= 5000 )
{
GetCloudPathDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_path : finish : %d\n이 파라미터의 값은 ( min -4000 ~ max 5000 ) 범위입니다", pPath->finish );
return 0;
}
GetCloudPathDB().add( y, pPath );
}
return 1;
}
int SCRIPT_CLOUD_LoadType( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "type_count", count);
GetCloudTypeInfoDB().clear();
// GetCloudTypeInfoDB().size( count );
int max_MoveSpeed = CLOUD_MOVE_SPEED_MAX;
int max_size = GetCloudSizeDB().get_size();
int max_thickness = GetCloudThicknessDB().get_size();
int max_thickness_gap = GetCloudThicknessGapDB().get_size();
int max_txr_dark = GetCloudTxrGroupDB().get_size(CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::DARK);
int max_txr_normal = GetCloudTxrGroupDB().get_size(CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::NORMAL);
int max_txr_middle = GetCloudTxrGroupDB().get_size(CCloudTxrGroupDB::TXR_BRIGHTNESS_TYPE::MIDDLE);
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "type%02d", y );
tlua_opentable( L, table.c_str() );
SCloudTypeInfo* pTIF = new SCloudTypeInfo;
tlua_getfield( L,"c_size", pTIF->type_size );
tlua_getfield( L,"c_thickness", pTIF->type_thickness );
tlua_getfield( L,"c_thickness_gap", pTIF->type_thickness_gap );
tlua_getfield( L,"c_move_speed", pTIF->fMoveSpeed );
tlua_getfield( L,"c_txr_group", pTIF->type_txr_normal );
tlua_getfield( L,"c_txr_group_middle", pTIF->type_txr_middle );
tlua_getfield( L,"c_txr_group_dark", pTIF->type_txr_dark );
if( pTIF->type_size < 0 || pTIF->type_size >= max_size )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_size : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_size, max_size );
return 0;
}
if( pTIF->type_thickness < 0 || pTIF->type_thickness >= max_thickness )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_thickness : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_thickness, max_thickness );
return 0;
}
if( pTIF->type_thickness_gap < 0 || pTIF->type_thickness_gap >= max_thickness_gap )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_thickness_gap : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_thickness_gap, max_thickness_gap );
return 0;
}
if( pTIF->fMoveSpeed < 0 || pTIF->fMoveSpeed >= max_MoveSpeed )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_move_speed : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->fMoveSpeed, max_MoveSpeed );
return 0;
}
if( pTIF->type_txr_normal < 0 || pTIF->type_txr_normal >= max_txr_normal )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_txr_group : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_txr_normal, max_txr_normal );
return 0;
}
if( pTIF->type_txr_middle < 0 || pTIF->type_txr_middle >= max_txr_middle )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_txr_group_middle : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_txr_middle, max_txr_middle );
return 0;
}
if( pTIF->type_txr_dark < 0 || pTIF->type_txr_dark >= max_txr_dark )
{
GetCloudTypeInfoDB().clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_type : c_txr_group_dark : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pTIF->type_txr_dark, max_txr_dark );
return 0;
}
GetCloudTypeInfoDB().add( y, pTIF );
}
return 1;
}
int SCRIPT_CLOUD_LoadAppearLayer( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "layer_count", count);
GetCloudLayerDB()->clear();
// GetCloudLayerDB()->size( count );
int max_show_rate = CLOUD_SHOW_RATE_MAX;
int max_cloud_type = GetCloudTypeInfoDB().get_size();
int max_distribution = GetCloudDistributionDB().get_size();
int max_HeightRadomGap = GetCloudHeightRadomGapDB().get_size();
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "layer%02d", y );
tlua_opentable( L, table.c_str() );
SCloudLayer* pLayer = new SCloudLayer;
tlua_getfield( L,"distribution", pLayer->type_distribution );
if( pLayer->type_distribution < 0 || pLayer->type_distribution >= max_distribution )
{
GetCloudLayerDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_appear_layer : distribution : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayer->type_distribution, max_distribution );
return 0;
}
tlua_getfield( L,"cloud_height_random_gap", pLayer->type_height_random_gap );
if( pLayer->type_height_random_gap < 0 || pLayer->type_height_random_gap >= max_HeightRadomGap )
{
GetCloudLayerDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_appear_layer : cloud_height_random_gap : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayer->type_height_random_gap, max_HeightRadomGap );
return 0;
}
int cloud_kindcount = 0;
tlua_getfield( L, "cloud_type_count", cloud_kindcount);
pLayer->size( cloud_kindcount );
if( tlua_hasfield( L, "cloud_color" ) )
{
tlua_opentable( L, "cloud_color" );
tlua_getfield( L, "a", pLayer->color[0] ); // a
tlua_getfield( L, "r", pLayer->color[1] ); // r
tlua_getfield( L, "g", pLayer->color[2] ); // g
tlua_getfield( L, "b", pLayer->color[3] ); // b
}
for(int x=0; x<cloud_kindcount; x++)
{
SCloudShowInfo* pShowInfo = new SCloudShowInfo;
std::string table;
XStringUtil::Format( table, "cloud_type%02d", x );
tlua_opentable( L, table.c_str() );
tlua_getfield( L,"cloud_kind", pShowInfo->type_cloud );
tlua_getfield( L,"show_rate", pShowInfo->type_show_rate );
if( pShowInfo->type_cloud < 0 || pShowInfo->type_cloud > max_cloud_type )
{
GetCloudLayerDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_appear_layer : cloud_kind : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pShowInfo->type_cloud, max_cloud_type );
return 0;
}
if( pShowInfo->type_show_rate < 0 || pShowInfo->type_show_rate > max_show_rate )
{
GetCloudLayerDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_appear_layer : show_rate : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pShowInfo->type_show_rate, max_show_rate );
return 0;
}
pLayer->add( x, pShowInfo );
}
GetCloudLayerDB()->add( y, pLayer );
}
return 1;
}
int SCRIPT_CLOUD_LoadLayerSet( struct lua_State* L )
{
int count = 0;
tlua_getfield( L, "set_count", count);
GetCloudLayerSetDB()->clear();
// GetCloudLayerSetDB()->size( count );
int max_path = GetCloudPathDB().get_size();
int max_move_dir = GetCloudMoveDirDB().get_size();
int max_layer = GetCloudLayerDB()->get_size();
int max_layer_gap = GetCloudLayerGapDB().get_size();
for(int y=0; y<count; y++)
{
std::string table;
XStringUtil::Format( table, "set%02d", y );
tlua_opentable( L, table.c_str() );
SCloudLayerSet* pSet = new SCloudLayerSet;
int layercount = 0;
tlua_getfield( L, "layer_count", layercount);
pSet->size( layercount );
for(int x=0; x<layercount; x++)
{
SCloudLayerInfo* pLayerInfo = new SCloudLayerInfo;
std::string table;
XStringUtil::Format( table, "layer%02d", x );
tlua_opentable( L, table.c_str() );
tlua_getfield( L,"path_type", pLayerInfo->type_path );
tlua_getfield( L,"move_dir", pLayerInfo->type_move_dir );
tlua_getfield( L,"layer_type", pLayerInfo->type_layer );
tlua_getfield( L,"layer_gap", pLayerInfo->type_layer_gap );
if( pLayerInfo->type_path < 0 || pLayerInfo->type_path >= max_path )
{
GetCloudLayerSetDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_layer_set : path_type : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayerInfo->type_path, max_path-1 );
return 0;
}
if( pLayerInfo->type_move_dir < 0 || pLayerInfo->type_move_dir >= max_move_dir )
{
GetCloudLayerSetDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_layer_set : move_dir : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayerInfo->type_move_dir, max_move_dir-1 );
return 0;
}
if( pLayerInfo->type_layer < 0 || pLayerInfo->type_layer >= max_layer )
{
GetCloudLayerSetDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_layer_set : layer_type : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayerInfo->type_layer, max_layer-1 );
return 0;
}
if( pLayerInfo->type_layer_gap < 0 || pLayerInfo->type_layer_gap >= max_layer_gap )
{
GetCloudLayerSetDB()->clear();
ERROR_MSGBOX_CLOUD_LUA( "cloud_layer_set : layer_type : %d\n이 파라미터의 값은 ( min 0 ~ max %d ) 범위입니다", pLayerInfo->type_layer_gap, max_layer_gap-1 );
return 0;
}
pSet->add( x, pLayerInfo );
}
GetCloudLayerSetDB()->add( y, pSet );
}
return 1;
}
#endif
#ifdef CLOUD_LUA_RELOAD
int SCRIPT_CLOUD_Reload()
{
std::string strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "cloud_script.lua" );
if( strScript.length() > 0 )
{
LUA()->RunFile( strScript.c_str() );
KFileManager::Instance().DeleteTemporaryFile( "cloud_script.lua" );
}
LUA()->RunString( "loadCloudInfo()" );
return 1;
}
#endif