ILInt64 VBDate(ILInt64 month, ILInt64 day, ILInt64 year, int yearDigits) { ILInt64 result; /* Validate the parameters */ if(year >= 0 && year < 100 && yearDigits <= 2) { if(year < 30) { year += 2000; } else { year += 1900; } } if(year < 1 || year > 9999) { CCError(_("invalid year value")); year = 1; } if(month < 1 || month > 12) { CCError(_("invalid month value")); month = 1; } if(day < 1 || day > DaysInMonth(year, month)) { CCError(_("invalid day value")); day = 1; } /* Build the final tick value */ result = YearToDays(year); result += daysBeforeMonth[(int)(month - 1)]; if(month > 2 && IsLeapYear(year)) { ++result; } return (result + (day - 1)) * TicksPerDay; }
struct Population* PopulationLoad(lua_State* _State, int _Index) { int i; const char* _Key = NULL; const char* _Name = NULL; struct Constraint** _Ages = NULL; struct LinkedList _List = {0, NULL, NULL}; struct Population* _Pop = NULL; struct FoodBase** _Eats = NULL; struct LnkLst_Node* _Itr = NULL; int _Young = 0; int _Old = 0; int _Death = 0; int _Nutrition = 0; int _Meat = 0; int _Milk = 0; int _IsShearable = 0; int _FMRatio = 0; int _SpaceReq = 0; const struct GoodBase* _SkinGood = NULL; const struct GoodBase* _HairGood = NULL; double _SkinPounds = 0.0; double _HairPounds = 0.0; double _MaleRatio = 0; double _ReproduceMin = 0.0f; double _ReproduceMax = 0.0f; int _Return = -2; int _Top = lua_gettop(_State); lua_getmetatable(_State, _Index); lua_pushnil(_State); while(lua_next(_State, -2) != 0) { if(lua_isstring(_State, -2)) _Key = lua_tostring(_State, -2); else continue; if (!strcmp("Nutrition", _Key)) _Return = LuaGetInteger(_State, -1, &_Nutrition); else if(!strcmp("Name", _Key)) _Return = LuaGetString(_State, -1, &_Name); else if(!strcmp("MaleRatio", _Key)) _Return = LuaGetNumber(_State, -1, &_MaleRatio); else if(!strcmp("Meat", _Key)) _Return = LuaGetInteger(_State, -1, &_Meat); else if(!strcmp("Milk", _Key)) _Return = LuaGetInteger(_State, -1, &_Milk); else if(!strcmp("MatureAge", _Key)) { _Return = LuaIntPair(_State, -1, &_Young, &_Old); _Young = YearToDays(_Young); _Old = YearToDays(_Old); } else if(!strcmp("DeathAge", _Key)) { _Return = LuaGetInteger(_State, -1, &_Death); _Death = YearToDays(_Death); } else if (!strcmp("SpaceReq", _Key)) { _Return = LuaGetInteger(_State, -1, &_SpaceReq); } else if(!strcmp("FMRatio", _Key)) { _Return = LuaGetInteger(_State, -1, &_FMRatio); } else if(!strcmp("Reproduce", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) _Return = 0; lua_rawgeti(_State, -1, 1); if((_Return = LuaGetNumber(_State, -1, &_ReproduceMin)) <= 0) goto loop_end; lua_rawgeti(_State, -2, 2); if((_Return = LuaGetNumber(_State, -1, &_ReproduceMax)) <= 0) goto loop_end; lua_pop(_State, 2); } else if(!strcmp("Eats", _Key)) { _Return = 1; lua_pushnil(_State); while(lua_next(_State, -2) != 0) { void* _Data = NULL; if(lua_isstring(_State, -1) == 0) goto EatsEnd; if((_Data = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_WARNING, "Food %s could not be found.", lua_tostring(_State, -1)); goto EatsEnd; } LnkLstPushBack(&_List, _Data); EatsEnd: lua_pop(_State, 1); } } else if(!strcmp("Skin", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) { if(lua_isnil(_State, -1) == 0) Log(ELOG_INFO, "Population skin variable is not a table."); goto loop_end; } lua_pushstring(_State, "Type"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TSTRING) { Log(ELOG_INFO, "Population skin.Type variable is not a table."); goto loop_end; } if((_SkinGood = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_INFO, "Population skin.Type: %s is not a good.", lua_tostring(_State, -1)); lua_pop(_State, 2); continue; } lua_pop(_State, 1); lua_pushstring(_State, "Pounds"); lua_rawget(_State, -2); if(lua_type(_State, LUA_TNUMBER) == 0) { Log(ELOG_INFO, "Population skin.Pounds variable is not a number."); lua_pop(_State, 2); continue;; } _SkinPounds = lua_tonumber(_State, -1); lua_pop(_State, 1); } else if(!strcmp("Hair", _Key)) { if(lua_type(_State, -1) != LUA_TTABLE) { if(lua_isnil(_State, -1) == 0) Log(ELOG_INFO, "Population hair variable is not a table."); goto loop_end; } lua_pushstring(_State, "Type"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TSTRING) { Log(ELOG_INFO, "Population hair.Type variable is not a table."); goto loop_end; } if((_HairGood = HashSearch(&g_Goods, lua_tostring(_State, -1))) == NULL) { Log(ELOG_INFO, "Population hair.Type: %s is not a good.", lua_tostring(_State, -1)); goto loop_end; } lua_pop(_State, 1); lua_pushstring(_State, "Pounds"); lua_rawget(_State, -2); if(lua_type(_State, LUA_TNUMBER) == 0) { Log(ELOG_INFO, "Population hair.Pounds variable is not a number."); lua_pop(_State, 2); continue; } _HairPounds = lua_tonumber(_State, -1); lua_pop(_State, 1); lua_pushstring(_State, "IsShearable"); lua_rawget(_State, -2); if(lua_type(_State, -1) != LUA_TBOOLEAN) { Log(ELOG_INFO, "Population hair.IsShearable variable is not a number."); lua_pop(_State, 2); continue; } _IsShearable = lua_toboolean(_State, -1); lua_pop(_State, 1); } else { Log(ELOG_WARNING, "%s is not a field of a Population.", _Key); goto fail; } if(!(_Return > 0)) { Log(ELOG_WARNING, "%s contains invalid data for a Population.", _Key); goto fail; } loop_end: lua_pop(_State, 1); } if(_Young > _Old || _Old > _Death || _Death < 0) { Log(ELOG_WARNING, "%s age limits are invalid.", _Name); goto fail; } _Ages = CreateConstrntBnds(4, 0, _Young, _Old, _Death); _Pop = CreatePopulation(_Name, _Nutrition, _Meat, _Milk, _Ages, _MaleRatio, _FMRatio, _ReproduceMin, _ReproduceMax, _SpaceReq); _Eats = calloc(_List.Size, sizeof(struct FoodBase*)); _Itr = _List.Front; i = 0; while(_Itr != NULL) { _Eats[i] =_Itr->Data; InsertionSort(_Eats, i + 1, GoodBaseCmp, sizeof(*_Eats)); _Itr = _Itr->Next; ++i; } _Pop->Skin.Skin = _SkinGood; _Pop->Skin.Pounds = _SkinPounds; _Pop->Hair.Hair = _HairGood; _Pop->Hair.Pounds = _HairPounds; _Pop->Hair.Shearable = _IsShearable; _Pop->Outputs = malloc(sizeof(struct Good*)); _Pop->Outputs[0] = NULL; _Pop->Eats = _Eats; _Pop->EatsSize = _List.Size; if(_Pop->EatsSize == 0) Log(ELOG_WARNING, "Population %s has zero food types to consume.", _Name); return _Pop; fail: lua_settop(_State, _Top); return NULL; }