Merge branch 'master' into more-encompassing-number-skips

This commit is contained in:
Arfon Smith
2015-07-29 13:54:51 +01:00
parent 885b5aab41
commit 90a293727d
434 changed files with 79876 additions and 56121 deletions

View File

@@ -0,0 +1,246 @@
// Checkpoint Manager
// (c) João Pedro Lopes, All right's reserved
//
// Feel free to change any line above, as long as you post the 'fix' / 'patch' at the forum
// and send a copy to jplopes@live.com.pt
/* natives
native CreateCheckpoint(ownerid, chpid, Float:posX, Float:posY, Float:posZ, Float:size); // Creates a checkpoint
native SetCheckpointInterior(chpid, interiorid); // Changes the checkpoint interior
native SetCheckpointVirtualWorld(chpid, VirtualWorldID); // Changes the Checkpoint vWorld
native ToggleCheckpointActive(chpid, bool:active); // Deactivates / Activates the checkpoint
native ChangeCheckpointOwner(chpid, owner); // Change the checkpoint owner
native RemoveCheckpoint(chpid); // Removes the specified checkpoint
native StartCheckpointSeeking(); // Starts seeking for each individual
native StopCheckpointSeeking(); // Stops the system
native VerifyCheckpoint(playerid); // Place this at OnPlayerEnterCheckpoint
*/
// Function Forwards
forward public OnCheckpointEnter(playerid, checkpointid);
#if defined _CHECKPOINT_MANAGER_INCLUDED
#endinput
#endif
#define _CHECKPOINT_MANAGER_INCLUDED
#pragma library CheckpointManager
#include <a_samp>
#define MAX_CHECKPOINTS 200
#define CHECKPOINT_SEEKER_DELAY 300
#define GLOBAL_OWNER_ID -1
// CHECKPOINT ENUMERATION
enum _checkpointEnum{
_chp_populated, // Is this slot of the memory populated?
_chp_id, // The ID of the checkpoint
_chp_owner, // The ID of the player who this checkpoint is visible too
Float:_chp_posX, // The X position of this checkpoint
Float:_chp_posY, // The Y position of this checkpoint
Float:_chp_posZ, // The Z position of this checkpoint
Float:_chp_size, // The checkpoint size
Float:_chp_viewDistance, // The checkpoint view distance
bool:_chp_active, // Is this checkpoint active?
_chp_interior_id, // The interior id of this checkpoint
_chp_world_id // The world id of this checkpoint
};
// DATA ARRAYS
new _checkpoints[MAX_CHECKPOINTS][_checkpointEnum];
new _p_VisibleCheckpoint[MAX_PLAYERS];
new _chp_manager_timer_id;
// DATA VARIABLES
new _totalCheckpoints;
// --------------------------------------------------------------------------------------------------------
// Creates a new checkpoint with some initial data
stock CreateCheckpoint(__ownerid, __chpid, Float:__posX, Float:__posY, Float:__posZ, Float:__size){
// Max checkpoint reached?
if(_totalCheckpoints == MAX_CHECKPOINTS) return 0;
// First checkpoint? Setting everything to unpopulated
if(!_totalCheckpoints){
for(new i; i < MAX_PLAYERS; i++) _p_VisibleCheckpoint[i] = -1;
for(new i; i < MAX_CHECKPOINTS; i++){
_checkpoints[i][_chp_populated] = false;
}
// Sending the Initialization Info
printf("[Checkpoint Manager : Version 0.1.1b] System Initialized...", __chpid);
}
// Getting the first open slot
new _slot;
for(new i = 0; i < MAX_CHECKPOINTS; i++){
if(!_checkpoints[i][_chp_populated]){
_slot = i;
break;
}
}
// Adding the new checkpoint
_checkpoints[_slot][_chp_populated] = true;
_checkpoints[_slot][_chp_id] = __chpid;
_checkpoints[_slot][_chp_owner] = __ownerid;
_checkpoints[_slot][_chp_posX] = __posX;
_checkpoints[_slot][_chp_posY] = __posY;
_checkpoints[_slot][_chp_posZ] = __posZ;
_checkpoints[_slot][_chp_size] = __size;
_checkpoints[_slot][_chp_viewDistance] = 50.0;
_checkpoints[_slot][_chp_active] = true;
_checkpoints[_slot][_chp_interior_id] = 0;
_checkpoints[_slot][_chp_world_id] = 0;
printf("[Checkpoint Manager] Checkpoint created (%d) at slot %d", __chpid, _slot);
printf("Checkpoint Position: { %f, %f, %f }", _checkpoints[_slot][_chp_posX], _checkpoints[_slot][_chp_posY], _checkpoints[_slot][_chp_posZ]);
_totalCheckpoints++;
return 1;
}
//---------------------------------------------------------------------------------------------
stock SetCheckpointInterior(__chpid, __interiorid){
new _slot = __ChpSlotByID(__chpid);
if(_slot > -1){
// Valid slot?
_checkpoints[_slot][_chp_interior_id] = __interiorid;
return 1;
}
return 0;
}
//---------------------------------------------------------------------------------------------
stock SetCheckpointVirtualWorld(__chpid, __virtual_world_id){
new _slot = __ChpSlotByID(__chpid);
if(_slot > -1){
_checkpoints[_slot][_chp_world_id] = __virtual_world_id;
return 1;
}
return 0;
}
stock ToggleCheckpointActive(__chpid, bool:__active){
new _slot = __ChpSlotByID(__chpid);
if(_slot > -1){
_checkpoints[_slot][_chp_active] = __active;
return 1;
}
return 0;
}
stock ChangeCheckpointOwner(__chpid, __owner){
new _slot = __ChpSlotByID(__chpid);
if(_slot > -1){
_checkpoints[_slot][_chp_owner] = __owner;
return 1;
}
return 0;
}
stock RemoveCheckpoint(__chpid){
new _slot = __ChpSlotByID(__chpid);
if(_slot > -1){
// Deleting the checkpoint
_checkpoints[_slot][_chp_populated] = false;
_checkpoints[_slot][_chp_id] = -1;
_checkpoints[_slot][_chp_owner] = 255;
_checkpoints[_slot][_chp_posX] = -1;
_checkpoints[_slot][_chp_posY] = -1;
_checkpoints[_slot][_chp_posZ] = -1;
_checkpoints[_slot][_chp_size] = -1;
_checkpoints[_slot][_chp_viewDistance] = -1;
_checkpoints[_slot][_chp_active] = false;
_checkpoints[_slot][_chp_interior_id] = -1;
_checkpoints[_slot][_chp_world_id] = -1;
_totalCheckpoints--;
printf("\n[Checkpoint Manager] Checkpoint removed (ID: %d)", __chpid);
return 1;
}
return 0;
}
//---------------------------------------------------------------------------------------------
// Gets the checkpoint slot by id
stock __ChpSlotByID(__chpid){
for(new i; i < MAX_CHECKPOINTS; i++){
if(_checkpoints[i][_chp_id] == __chpid) return i;
}
return -1;
}
forward CheckpointSeeker();
stock StartCheckpointSeeking(){
_chp_manager_timer_id = SetTimer("CheckpointSeeker", CHECKPOINT_SEEKER_DELAY, 1);
return 1;
}
stock StopCheckpointSeeking(){
KillTimer(_chp_manager_timer_id);
return 1;
}
public CheckpointSeeker(){
new Float:__posX, Float:__posY, Float:__posZ;
new __interior;
new __virtualWorld;
for(new i; i < MAX_PLAYERS; i++)
{
if(!IsPlayerConnected(i)) continue;
GetPlayerPos(i, Float:__posX, Float:__posY, Float:__posZ);
// Is the player near a checkpoint?
if(_p_VisibleCheckpoint[i] > -1)
{
// If the player is no longer near that point
if(__posX < (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posX] - _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
|| __posX > (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posX] + _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
|| __posY < (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posY] - _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])
|| __posY > (_checkpoints[_p_VisibleCheckpoint[i]][_chp_posY] + _checkpoints[_p_VisibleCheckpoint[i]][_chp_viewDistance])){
DisablePlayerCheckpoint(i);
_p_VisibleCheckpoint[i] = -1;
}
}
else
{
// Getting the player Interior and virtual world
__interior = GetPlayerInterior(i);
__virtualWorld = GetPlayerVirtualWorld(i);
// Looking for a new checkpoint
for(new j = 0; j < MAX_CHECKPOINTS; j++){
if(!_checkpoints[j][_chp_populated]) continue;
if((_checkpoints[j][_chp_owner] != i) && (_checkpoints[j][_chp_owner] != -1)) continue;
if(_checkpoints[j][_chp_interior_id] != __interior) continue;
if(_checkpoints[j][_chp_world_id] != __virtualWorld) continue;
if(__posX > (_checkpoints[j][_chp_posX] - _checkpoints[j][_chp_viewDistance])
&& __posX < (_checkpoints[j][_chp_posX] + _checkpoints[j][_chp_viewDistance])
&& __posY > (_checkpoints[j][_chp_posY] - _checkpoints[j][_chp_viewDistance])
&& __posY < (_checkpoints[j][_chp_posY] + _checkpoints[j][_chp_viewDistance])){
SetPlayerCheckpoint(i, _checkpoints[j][_chp_posX], _checkpoints[j][_chp_posY], _checkpoints[j][_chp_posZ], _checkpoints[j][_chp_size]);
_p_VisibleCheckpoint[i] = j;
break;
}
}
}
}
return 1;
}
stock VerifyCheckpoint(__playerid){
if(_p_VisibleCheckpoint[__playerid] >= 0){
OnCheckpointEnter(__playerid, _checkpoints[_p_VisibleCheckpoint[__playerid]][_chp_id]);
return 1;
}
return 0;
}

View File

@@ -0,0 +1,91 @@
/* Fixed point arithmetic
*
* (c) Copyright 1998-2011, ITB CompuPhase
* This file is provided as is (no warranties).
*/
#pragma library Fixed
const fround_method: {
fround_round = 0,
fround_floor,
fround_ceil,
fround_tozero,
fround_unbiased
}
native Fixed:fixed(value);
native Fixed:strfixed(const string[]);
native Fixed:fmul(Fixed:oper1, Fixed:oper2);
native Fixed:fdiv(Fixed:dividend, Fixed:divisor);
native Fixed:ffract(Fixed:value);
native fround(Fixed:value, fround_method:method=fround_round);
native Fixed:fpower(Fixed:value, exponent);
native Fixed:fsqroot(Fixed:value);
native Fixed:fabs(Fixed:value);
#pragma rational Fixed(3)
/* user defined operators */
native Fixed:operator*(Fixed:oper1, Fixed:oper2) = fmul;
native Fixed:operator/(Fixed:oper1, Fixed:oper2) = fdiv;
native Fixed:operator=(oper) = fixed;
stock Fixed:operator++(Fixed:oper)
return oper + fixed(1);
stock Fixed:operator--(Fixed:oper)
return oper - fixed(1);
stock Fixed:operator*(Fixed:oper1, oper2)
return Fixed: (_:oper1 * oper2); /* "*" is commutative */
stock Fixed:operator/(Fixed:oper1, oper2)
return oper1 / fixed(oper2);
stock Fixed:operator/(oper1, Fixed:oper2)
return fdiv(fixed(oper1), oper2);
stock Fixed:operator+(Fixed:oper1, oper2)
return oper1 + fixed(oper2); /* "+" is commutative */
stock Fixed:operator-(Fixed:oper1, oper2)
return oper1 - fixed(oper2);
stock Fixed:operator-(oper1, Fixed:oper2)
return fixed(oper1) - oper2;
stock bool:operator>(Fixed:oper1, oper2)
return oper1 > fixed(oper2);
stock bool:operator>(oper1, Fixed:oper2)
return fixed(oper1) > oper2;
stock bool:operator>=(Fixed:oper1, oper2)
return oper1 >= fixed(oper2);
stock bool:operator>=(oper1, Fixed:oper2)
return fixed(oper1) >= oper2;
stock bool:operator<(Fixed:oper1, oper2)
return oper1 < fixed(oper2);
stock bool:operator<(oper1, Fixed:oper2)
return fixed(oper1) < oper2;
stock bool:operator<=(Fixed:oper1, oper2)
return oper1 <= fixed(oper2);
stock bool:operator<=(oper1, Fixed:oper2)
return fixed(oper1) <= oper2;
stock bool:operator==(Fixed:oper1, oper2) /* "==" is commutative */
return oper1 == fixed(oper2);
stock bool:operator!=(Fixed:oper1, oper2) /* "!=" is commutative */
return oper1 != fixed(oper2);
/* forbidden operations */
forward operator%(Fixed:oper1, Fixed:oper2);
forward operator%(Fixed:oper1, oper2);
forward operator%(oper1, Fixed:oper2);

272
samples/SourcePawn/foo.sma Normal file
View File

@@ -0,0 +1,272 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// TimeLeft Plugin
//
#include <amxmodx>
const TASK_TIMEREMAIN_SHORT = 8648458 // 0.8s repeat task
const TASK_TIMEREMAIN_LARGE = 34543 // 1.0s repeat task
// time display flags
const TD_BOTTOM_WHITE_TEXT = 1 // a - display white text on bottom
const TD_USE_VOICE = 2 // b - use voice
const TD_NO_REMAINING_VOICE = 4 // c - don't add "remaining" (only in voice)
const TD_NO_HOURS_MINS_SECS_VOICE = 8 // d - don't add "hours/minutes/seconds" (only in voice)
const TD_SHOW_SPEAK_VALUES_BELOW = 16 // e - show/speak if current time is less than this set in parameter
new g_TimeSet[32][2]
new g_LastTime
new g_CountDown
new g_Switch
// pcvars
new g_amx_time_voice, g_amx_timeleft
new g_mp_timelimit
public plugin_init()
{
register_plugin("TimeLeft", AMXX_VERSION_STR, "AMXX Dev Team")
register_dictionary("timeleft.txt")
g_amx_time_voice = register_cvar("amx_time_voice", "1")
register_srvcmd("amx_time_display", "setDisplaying")
g_amx_timeleft = register_cvar("amx_timeleft", "00:00", FCVAR_SERVER|FCVAR_EXTDLL|FCVAR_UNLOGGED|FCVAR_SPONLY)
register_clcmd("say timeleft", "sayTimeLeft", 0, "- displays timeleft")
register_clcmd("say thetime", "sayTheTime", 0, "- displays current time")
set_task(0.8, "timeRemain", TASK_TIMEREMAIN_SHORT, "", 0, "b")
g_mp_timelimit = get_cvar_pointer("mp_timelimit")
}
public sayTheTime(id)
{
if (get_pcvar_num(g_amx_time_voice))
{
new mhours[6], mmins[6], whours[32], wmins[32], wpm[6]
get_time("%H", mhours, charsmax(mhours))
get_time("%M", mmins, charsmax(mmins))
new mins = str_to_num(mmins)
new hrs = str_to_num(mhours)
if (mins)
num_to_word(mins, wmins, charsmax(wmins))
else
wmins[0] = EOS
if (hrs < 12)
wpm = "am "
else
{
if (hrs > 12) hrs -= 12
wpm = "pm "
}
if (hrs)
num_to_word(hrs, whours, charsmax(whours))
else
whours = "twelve "
client_cmd(id, "spk ^"fvox/time_is_now %s_period %s%s^"", whours, wmins, wpm)
}
new ctime[64]
get_time("%m/%d/%Y - %H:%M:%S", ctime, charsmax(ctime))
client_print(0, print_chat, "%L: %s", LANG_PLAYER, "THE_TIME", ctime)
return PLUGIN_CONTINUE
}
public sayTimeLeft(id)
{
if (get_pcvar_float(g_mp_timelimit))
{
new a = get_timeleft()
if (get_pcvar_num(g_amx_time_voice))
{
new svoice[128]
setTimeVoice(svoice, charsmax(svoice), 0, a)
client_cmd(id, "%s", svoice)
}
client_print(0, print_chat, "%L: %d:%02d", LANG_PLAYER, "TIME_LEFT", (a / 60), (a % 60))
}
else
client_print(0, print_chat, "%L", LANG_PLAYER, "NO_T_LIMIT")
return PLUGIN_CONTINUE
}
setTimeText(text[], len, tmlf, id)
{
new secs = tmlf % 60
new mins = tmlf / 60
if (secs == 0)
formatex(text, len, "%d %L", mins, id, (mins > 1) ? "MINUTES" : "MINUTE")
else if (mins == 0)
formatex(text, len, "%d %L", secs, id, (secs > 1) ? "SECONDS" : "SECOND")
else
formatex(text, len, "%d %L %d %L", mins, id, (mins > 1) ? "MINUTES" : "MINUTE", secs, id, (secs > 1) ? "SECONDS" : "SECOND")
}
setTimeVoice(text[], len, flags, tmlf)
{
new temp[7][32]
new secs = tmlf % 60
new mins = tmlf / 60
// for (new a = 0;a < 7;++a) // we just created it, already null
// temp[a][0] = 0
if (secs > 0)
{
num_to_word(secs, temp[4], charsmax(temp[]))
if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE )
temp[5] = "seconds " /* there is no "second" in default hl */
}
if (mins > 59)
{
new hours = mins / 60
num_to_word(hours, temp[0], charsmax(temp[]))
if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE )
temp[1] = "hours "
mins = mins % 60
}
if (mins > 0)
{
num_to_word(mins, temp[2], charsmax(temp[]))
if ( ~flags & TD_NO_HOURS_MINS_SECS_VOICE )
temp[3] = "minutes "
}
if ( ~flags & TD_NO_REMAINING_VOICE )
temp[6] = "remaining "
return formatex(text, len, "spk ^"vox/%s%s%s%s%s%s%s^"", temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6])
}
findDispFormat(_time)
{
// it is important to check i<sizeof BEFORE g_TimeSet[i][0] to prevent out of bound error
for (new i = 0; i < sizeof(g_TimeSet) && g_TimeSet[i][0]; ++i)
{
if (g_TimeSet[i][1] & TD_SHOW_SPEAK_VALUES_BELOW)
{
if (g_TimeSet[i][0] > _time)
{
if (!g_Switch)
{
g_CountDown = g_Switch = _time
remove_task(TASK_TIMEREMAIN_SHORT)
set_task(1.0, "timeRemain", TASK_TIMEREMAIN_LARGE, "", 0, "b")
}
return i
}
}
else if (g_TimeSet[i][0] == _time)
{
return i
}
}
return -1
}
public setDisplaying()
{
new arg[32], flags[32], num[32]
new argc = read_argc() - 1
new i = 0
while (i < argc && i < sizeof(g_TimeSet))
{
read_argv(i + 1, arg, charsmax(arg))
parse(arg, flags, charsmax(flags), num, charsmax(num))
g_TimeSet[i][0] = str_to_num(num)
g_TimeSet[i][1] = read_flags(flags)
i++
}
if( i < sizeof(g_TimeSet) )
g_TimeSet[i][0] = 0 // has to be zeroed in case command is sent twice
return PLUGIN_HANDLED
}
public timeRemain(param[])
{
new gmtm = get_timeleft()
new tmlf = g_Switch ? --g_CountDown : gmtm
new stimel[12]
formatex(stimel, charsmax(stimel), "%02d:%02d", gmtm / 60, gmtm % 60)
set_pcvar_string(g_amx_timeleft, stimel)
if (g_Switch && gmtm > g_Switch)
{
remove_task(TASK_TIMEREMAIN_LARGE)
g_Switch = 0
set_task(0.8, "timeRemain", TASK_TIMEREMAIN_SHORT, "", 0, "b")
return
}
if (tmlf > 0 && g_LastTime != tmlf)
{
g_LastTime = tmlf
new tm_set = findDispFormat(tmlf)
if (tm_set != -1)
{
new flags = g_TimeSet[tm_set][1]
new arg[128]
if (flags & TD_BOTTOM_WHITE_TEXT)
{
new players[MAX_PLAYERS], pnum, plr
get_players(players, pnum, "c")
if (flags & TD_SHOW_SPEAK_VALUES_BELOW) // yes this is correct flag, just because message should be shorter if it is shown every seconds
set_hudmessage(255, 255, 255, -1.0, 0.85, 0, 0.0, 1.1, 0.1, 0.5, -1)
else
set_hudmessage(255, 255, 255, -1.0, 0.85, 0, 0.0, 3.0, 0.0, 0.5, -1)
for (new i = 0; i < pnum; i++)
{
plr = players[i]
setTimeText(arg, charsmax(arg), tmlf, plr)
show_hudmessage(plr, "%s", arg)
}
}
if (flags & TD_USE_VOICE)
{
setTimeVoice(arg, charsmax(arg), flags, tmlf)
client_cmd(0, "%s", arg)
}
}
}
}

View File

@@ -0,0 +1,289 @@
/* mFile 1.1 by Minokon
*
* (c) Copyright by Minokon 2010
* (c) y_files Copyright by Y_Less 2010
*
*/
#if defined _mfile_included
#endinput
#endif
#define _mfile_included
//Defines
#define MAX_LINE_SIZE 80 //Max lenght of one line in file
#define MAX_KEY_SIZE 50 //Max lenght of key in line (to =)
#define MAX_VALUE_SIZE 50 //Max lenght of value in line (past =)
#define TMP_FILE "tmpfile.txt"
//Natives
/*
native mCreateFile(const file[]);
native mRemoveFile(const file[]);
native mClearFile(const file[]);
native bool:mFileExist(const file[]);
native mRenameFile(const file[], const newname[]);
native mFindFile(const name[], dest[], &index, sizename=sizeof dest);
native mCreateDir(const name[]);
native mRenameDir(const dir[], const newname[]);
native mFindDir(const name[], dest[], &index, sizename=sizeof dest);
native mHowLines(const file[]);
native mRemoveNewLine(string[]); //removes "\n" from string
native mGetString(const file[], const key[], bool:ignorecase=false);
native mGetInt(const file[], const key[], bool:ignorecase=false);
native mGetFloat(const file[], const key[], &Float:value);
native mSetString(const file[], const key[], const new_value[]);
native mSetInt(const file[], const key[], new_value);
native mSetFloat(const file[], const key[], Float:new_value);
native mIsSet(const file[], const key[], bool:ignorecase=false);
native mUnSet(const file[], const key[]);
native mIsFileEmpty(const file[]);
native y_files
*/
//y_files by Y_Less Functions
native ffind(const pattern[], filename[], len, &idx);
native frename(const oldname[], const newname[]);
native dfind(const pattern[], filename[], len, &idx);
native dcreate(const name[]);
native drename(const oldname[], const newname[]);
//Forwards
forward OnFileCreated(file[]);
forward OnFileRemoved(file[]);
forward OnFileCleared(file[]);
forward OnFileRenamed(oldname[], newname[]);
forward OnDirCreated(dir[]);
forward OnDirRenamed(oldname[], newname[]);
stock mCreateFile(const file[])
{
if(fexist(file)) fremove(file);
new File:mfile = fopen(file, io_write);
fclose(mfile);
CallLocalFunction("OnFileCreated", "s", file);
return 1;
}
stock mRemoveFile(const file[])
{
CallLocalFunction("OnFileRemoved", "s", file);
return fremove(file);
}
stock mClearFile(const file[])
{
if(!fremove(file)) return 0;
new File:mfile = fopen(file, io_write);
fclose(mfile);
CallLocalFunction("OnFileCleared", "s", file);
return 1;
}
stock bool:mFileExist(const file[])
if(fexist(file)) return true; //dla ciekawych: fexist nie zwraca booleanu
else return false;
stock mRenameFile(const file[], const newname[])
{
CallLocalFunction("OnFileRenamed", "ss", file, newname);
return frename(file, newname);
}
stock mFindFile(const name[], dest[], &index, sizename=sizeof dest)
return ffind(name, dest, sizename, index);
stock mCreateDir(const name[])
{
CallLocalFunction("OnDirCreated", "s", name);
return dcreate(name);
}
stock mRenameDir(const dir[], const newname[])
{
CallLocalFunction("OnDirRenamed", "ss", dir, newname);
return drename(dir, newname);
}
stock mFindDir(const name[], dest[], &index, sizename=sizeof dest)
return dfind(name, dest, sizename, index);
stock mHowLines(const file[])
{
new lines, str[MAX_LINE_SIZE];
new File:mfile = fopen(file, io_read);
while(fread(mfile, str)) lines++;
fclose(mfile);
return lines;
}
stock mRemoveNewLine(string[])
{
new pos = strfind(string, "\n");
if(pos != -1)
{
strdel(string, pos, pos+2);
return 1;
}
return 0;
}
stock mGetString(const file[], const key[], bool:ignorecase=false)
{
//Create file if not exists
if(!fexist(file))
{
new File:created = fopen(file, io_write);
fclose(created);
}
new //Variables
File:mfile = fopen(file, io_read), //Open file
str[MAX_LINE_SIZE],
str2[MAX_KEY_SIZE],
str3[MAX_VALUE_SIZE],
pos;
//Find key in file
while(fread(mfile, str))
{
pos = strfind(str, "=", ignorecase);
strmid(str2, str, 0, pos);
if(!strcmp(str2, key, ignorecase, strlen(key)+1))
{
strmid(str3, str, pos+1, strlen(str));
mRemoveNewLine(str3);
break;
}
}
fclose(mfile);
return str3;
}
stock mGetInt(const file[], const key[], bool:ignorecase=false)
return strval(mGetString(file, key, ignorecase));
stock mGetFloat(const file[], const key[], &Float:value, bool:ignorecase=false)
value = floatstr(mGetString(file, key, ignorecase));
stock mSetString(const file[], const key[], const new_value[])
{
//Create file if not exists
if(!fexist(file))
{
new File:created = fopen(file, io_write);
fclose(created);
}
new //Variables
str[MAX_LINE_SIZE],
str2[MAX_KEY_SIZE],
str3[MAX_LINE_SIZE],
bool:lFinded = false;
//Open file
new File:mfile = fopen(file, io_read);
//Create cache file
new File:tmpfile = fopen(TMP_FILE, io_write);
fclose(tmpfile);
//Open cache file
tmpfile = fopen(TMP_FILE, io_append);
format(str3, sizeof str3, "%s=%s\n", key, new_value);
while(fread(mfile, str))
{
strmid(str2, str, 0, strfind(str, "="));
if(!strcmp(str2, key))
{
fwrite(tmpfile, str3);
lFinded = true;
}
else
fwrite(tmpfile, str);
}
if(!lFinded) //if line not found
fwrite(tmpfile, str3);
//Close and remove old file
fclose(mfile);
fremove(file);
//Close cache file and rename it
fclose(tmpfile);
frename(TMP_FILE, file);
return 1;
}
stock mSetInt(const file[], const key[], new_value)
{
new str[MAX_VALUE_SIZE];
valstr(str, new_value);
mSetString(file, key, str);
return 1;
}
stock mSetFloat(const file[], const key[], Float:new_value)
{
new str[MAX_VALUE_SIZE];
format(str, sizeof str, "%f", new_value);
return mSetString(file, key, str);
}
stock bool:mIsSet(const file[], const key[], bool:ignorecase=false)
{
//If fexists return false
if(!fexist(file)) return false;
new //Variables
File:mfile = fopen(file, io_read), //Open file
str[MAX_LINE_SIZE],
str2[MAX_KEY_SIZE],
bool:finded = false;
//Find key in file
while(fread(mfile, str))
{
strmid(str2, str, 0, strfind(str, "="));
if(!strcmp(str2, key, ignorecase, strlen(key)+1))
{
finded = true;
break;
}
}
fclose(mfile);
return finded;
}
stock mUnSet(const file[], const key[])
{
if(!fexist(file)) return 0;
new //Variables
str[MAX_LINE_SIZE],
str2[MAX_KEY_SIZE];
//Open file
new File:mfile = fopen(file, io_read);
//Create cache file
new File:tmpfile = fopen(TMP_FILE, io_write);
fclose(tmpfile);
//Open cache file
tmpfile = fopen(TMP_FILE, io_append);
while(fread(mfile, str))
{
strmid(str2, str, 0, strfind(str, "="));
if(strcmp(str2, key) != 0)
fwrite(tmpfile, str);
}
//Close and remove old file
fclose(mfile);
fremove(file);
//Close cache file and rename it
fclose(tmpfile);
frename(TMP_FILE, file);
return 1;
}
stock bool:mIsFileEmpty(const file[])
{
if(!fexist(file)) return true;
new File:mfile = fopen(file, io_read);
if(flength(mfile) <= 1)
{
fclose(mfile);
return true;
}
else
{
fclose(mfile);
return false;
}
}

View File

@@ -0,0 +1,633 @@
/**--------------------------------------------------------------------------**\
====================================
y_testing - Run unit tests easilly
====================================
Description:
Runs any functions named as tests when the Testing_Run function is called.
Legal:
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the YSI testing include.
The Initial Developer of the Original Code is Alex "Y_Less" Cole.
Portions created by the Initial Developer are Copyright (C) 2011
the Initial Developer. All Rights Reserved.
Contributors:
ZeeX, koolk, JoeBullet/Google63, g_aSlice/Slice
Thanks:
JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
ZeeX - Very productive conversations.
koolk - IsPlayerinAreaEx code.
TheAlpha - Danish translation.
breadfish - German translation.
Fireburn - Dutch translation.
yom - French translation.
50p - Polish translation.
Zamaroht - Spanish translation.
Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
for me to strive to better.
Pixels^ - Running XScripters where the idea was born.
Matite - Pestering me to release it and using it.
Very special thanks to:
Thiadmer - PAWN, whose limits continue to amaze me!
Kye/Kalcor - SA:MP.
SA:MP Team past, present and future - SA:MP.
Version:
1.0
Changelog:
16/02/12:
Added better error reporting (less verbose passes).
Removed "Tests:".
Added player requiring tests.
25/10/10:
Integrated in to YSI.
06/08/10:
First version
</remarks>
\**--------------------------------------------------------------------------**/
/*#if defined _inc_a_samp || defined _samp_included || defined _inc_y_version
#error y_testing must be the VERY FIRST include in your mode if being used.
#endif
// Now we redefined "native" to do something clever!
// "IsPlayerAttachedObjectSlotUsed" is an issue for us...
// "y_renative" allows native functions to be declared without constantly trying
// to redefine it.
#include "internal\y_renative"
#define native%0(%1); _YSI_NO_TAG_NATIVE:_YSI_RE_NATIVE<%0@|||%1|||%0>_YSI_RE_STOCK<%0|||%1|||_:%0@>
//stock%0(%1){printf(_:_YSI_NO_SQUARE:"native "#%0" called");return _:%0@(%1);}
#define _YSI_RE_STOCK<%0|||%1|||%2> stock%0(%1){print(_:_YSI_NO_SQUARE:"native "#%0" called");return %2(%1);}
#define _YSI_NO_SQUARE:%0);%1(%2[%3]%4);} _YSI_NO_SQUARE:%0);%1(%2%4);}
//#define _YSI_NO_TAG_NATIVE:_YSI_RE_NATIVE<%0:%1|||%2|||%3:%4>%5{%6;%7:%8:%9} _YSI_RE_NATIVE<%1|||%2|||%4>%5{%6;return%8:%9}
#define _YSI_NO_TAG_NATIVE:_YSI_RE_NATIVE<%0:%1|||%2|||%3:%4>_YSI_RE_STOCK<%5:%6|||%7|||_:%8:%9> _YSI_RE_NATIVE<%1|||%2|||%4>_YSI_RE_STOCK<%5:%6|||%7|||%8:%9>*/
#include <a_samp>
#if defined YSI_TESTS
#if defined INCLUDE_TESTS
#error Incompatible testing options (YSI_TESTS + INCLUDE_TESTS)
#endif
#if !defined RUN_TESTS
#define RUN_TESTS
#endif
#endif
#if defined INCLUDE_TESTS
#define RUN_TESTS
#define Debug_PrintT va_printf
#elseif defined RUN_TESTS
#define _AUTO_RUN_TESTS
#define Debug_PrintT va_printf
#else
#if _DEBUG > 0 || defined _YSI_SPECIAL_DEBUG
#define RUN_TESTS
#define _AUTO_RUN_TESTS
//#if defined _YSI_SPECIAL_DEBUG
// #define TP printf
// //#define TC(%0); %0
#define Debug_PrintT va_printf
//#else
// //#define TP P:0
// //#define TC C:0
//#endif
#else
#define Debug_PrintT(%0);
// #define Tests:%1() stock bool:Tests_@%1()
// #define Test:%1() stock bool:Test_@%1()
// #define TestInit:%1() stock Init_@%1()
// #define TestClose:%1() stock Shut_@%1()
#endif
#endif
#define Y_TESTING_DIALOG_ID (0x7974) // "yt"
#define TEST_TRUE(%0) Testing_Test(!!%0)
#define TEST_FALSE(%0) Testing_Test(!%0)
#define TEST_NULL(%0) Testing_Test(0 == %0)
#define TEST_NOT_NULL(%0) Testing_Test(0 != %0)
#define TEST_N(%0,%1) Testing_Test(%1 == %0)
#define TEST_TRUE_EX(%0,%2) Testing_Test(bool:(%0), (%2))
#define TEST_FALSE_EX(%0,%2) Testing_Test(!(%0), (%2))
#define TEST_NULL_EX(%0,%2) Testing_Test((%0) == 0, (%2))
#define TEST_N_EX(%0,%1,%2) Testing_Test((%0) == (%1), (%2))
#define TEST_MSG "\2\2\2\2\2"
#define TEST_FAILED "FAIL:"
#define TEST_PASSED "PASS!"
//#define TEST_FAILED "*** Test Failed:"
//#define TEST_PASSED "*** Test Passed:"
#define _Y_TESTEQ(%0) "\"%0\"")
#define _Y_TESTDQ:_Y_TESTEQ(%0"%1"%2) _Y_TESTDQ:_Y_TESTEQ(%0\x22;%1\x22;%2)
//#define _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0)%1) _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0\x29;%1)
#define _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0)%1) _Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0\x29;%1)
#define _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0(%1) _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0\x28;%1)
#define ASSERT(%0) Testing_Test(%0,TEST_MSG" %s", _Y_TESTOB:_Y_TESTCB:_Y_TESTDQ:_Y_TESTEQ(%0)
#define ASSERT_TRUE(%0) ASSERT(!!%0) //Testing_Test(!!%0,__name)
#define ASSERT_FALSE(%0) ASSERT(!%0) //Testing_Test(!%0,__name)
#define ASSERT_NULL(%0) ASSERT(0 == %0) //Testing_Test(0==%0,__name)
#define ASSERT_N:%1(%0) ASSERT(%1 == %0) //Testing_Test(%1==%0,__name)
#define ASK(%0) Testing_Ask(playerid,%0)
static stock
YSI_g_sFailMessage[512],
YSI_g_sPlayer = cellmax,
bool:YSI_g_sAsked,
YSI_g_sTests,
YSI_g_sFails;
#if defined RUN_TESTS
#define Test:%1() forward bool:Tezt_@%1(); public bool:Tezt_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
//#define Tests:%1() forward bool:Test_@%1(); public bool:Test_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
#define TestInit:%1() forward Init_@%1(); public Init_@%1() for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define TestClose:%1() forward Shut_@%1(); public Shut_@%1() for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define PTest:%1(%2) forward bool:Tezp_@%1(%2); public bool:Tezp_@%1(%2) for(new string:__name[]=#%1,bool:__once=(printf("*** Player Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
//#define Tests:%1() forward bool:Test_@%1(); public bool:Test_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
#define PTestInit:%1(%2) forward Inip_@%1(%2); public Inip_@%1(%2) for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define PTestClose:%1(%2) forward Shup_@%1(%2); public Shup_@%1(%2) for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#else
#define Test:%1() stock bool:Test_@%1()
#define TestInit:%1() stock Init_@%1()
#define TestClose:%1() stock Shut_@%1()
#define PTest:%1(%2) stock bool:Test_@%1(%2)
#define PTestInit:%1(%2) stock Init_@%1(%2)
#define PTestClose:%1(%2) stock Shut_@%1(%2)
#endif
// These all need to come AFTER the types are defined in case the have tests.
#include "internal\y_version"
#include "y_amx"
#include "internal\y_shortfunc"
#include "y_debug"
#include "internal\y_natives"
#include "y_va"
/**--------------------------------------------------------------------------**\
<summary>Testing_Ask</summary>
<param name="playerid">Player to ask a question to.</param>
<param name="str[]">What to ask.</param>
<param name="va_args<>">Additional data.</param>
<returns>
-
</returns>
<remarks>
Calls a dialog to ask the player if the given test actually passed.
</remarks>
\**--------------------------------------------------------------------------**/
stock Testing_Ask(playerid, str[] = "", va_args<>)
{
va_format(YSI_g_sFailMessage, sizeof (YSI_g_sFailMessage), str, va_start<2>);
ShowPlayerDialog(playerid, Y_TESTING_DIALOG_ID, DIALOG_STYLE_MSGBOX, "Did the test pass?", YSI_g_sFailMessage, "Yes", "No");
YSI_g_sAsked = true;
}
stock Testing_Test(bool:x, str[] = "", va_args<>)
{
P:3("Testing_Test called: %i, \"%s\"", x, str);
++YSI_g_sTests;
if (!x)
{
++YSI_g_sFails;
if (numargs() == 2)
{
P:T(TEST_FAILED " %s", va_start<1>);
//printf("*** Test failed: %s", str);
}
else
{
if (str[0] == '\2')
{
strunpack(str, !TEST_FAILED, 6);
str[5] = ' ';
}
P:T(str, va_start<2>);
}
}
#if defined TEST_SHOW_PASSES
else /*if (numargs() == 2)
{
P:T(TEST_PASSED " %s", va_start<1>);
}
else
{
P:T(str, va_start<2>);
if (str[0] == '\2')
{
strunpack(str, !TEST_PASSED, 17);
str[16] = ' ';
}
printf(str);
P:T(str, va_start<2>);*/
{
P:T(TEST_PASSED, va_start<2>);
}
#endif
}
/**--------------------------------------------------------------------------**\
<summary>Testing_Run</summary>
<param name="&tests">Number of tests run.</param>
<param name="&fails">Number of tests which failed.</param>
<param name="buffer[33]">The name of the first test which failed.</param>
<returns>
Wether all tests were sucessful or not.
</returns>
<remarks>
-
native Testing_Run(&tests, &fails, buffer[33] = "");
</remarks>
\**--------------------------------------------------------------------------**/
stock bool:Testing_Run(&tests, &fails, lastfail[33] = "", bool:p = false)
{
P:3("bool:Testing_Run called: %i, %i, \"%s\", %i", tests, fails, lastfail, p);
#pragma unused p, lastfail
#if defined RUN_TESTS
P:2("Testing_Run() called");
new
idx,
buffer[32];
while ((idx = AMX_GetPublicName(idx, buffer, "Tezt_@")))
{
strunpack(buffer, buffer);
//++YSI_g_sTests;
// Call the setup function if there is one.
buffer[0] = 'I';
buffer[1] = 'n';
buffer[2] = 'i';
buffer[3] = 't';
CallLocalFunction(buffer, "");
// Call the test.
buffer[0] = 'T';
buffer[1] = 'e';
buffer[2] = 'z';
buffer[3] = 't';
fails = YSI_g_sFails;
P:5("Testing_Run(): Calling %s", buffer[6]);
CallLocalFunction(buffer, "");
#if !defined TEST_SHOW_PASSES
if (YSI_g_sFails == fails)
{
printf(TEST_PASSED);
printf(" ");
}
#endif
/*if (YSI_g_sFails != fails)
{
if (YSI_g_sFails)
{
++YSI_g_sFails;
}
else
{
fails = 0;
// Copy the string over.
while ((lastfail[fails] = buffer[fails + 6])) ++fails;
YSI_g_sFails = 1;
}
//C:1(if (p) printf("*** Test failed: %s", buffer[fails + 6]););
}*/
// Call the shutdown function if there is one.
buffer[0] = 'S';
buffer[1] = 'h';
buffer[2] = 'u';
buffer[3] = 't';
CallLocalFunction(buffer, "");
}
tests = YSI_g_sTests;
fails = YSI_g_sFails;
return fails == 0;
#else
#pragma unused tests, fails, lastfail
return true;
#endif
}
/**--------------------------------------------------------------------------**\
<summary>Testing_Player</summary>
<param name="playerid">Player to test on.</param>
<param name="&idx">Next test to run.</param>
<param name="&tests">Number of tests run.</param>
<param name="&fails">Number of tests which failed.</param>
<param name="buffer[33]">The name of the first test which failed.</param>
<returns>
Wether all tests were sucessful or not.
</returns>
<remarks>
-
native Testing_Run(&tests, &fails, buffer[33] = "");
</remarks>
\**--------------------------------------------------------------------------**/
stock bool:Testing_Player(playerid, &idx, &tests, &fails, lastfail[33] = "", bool:p = false)
{
P:3("bool:Testing_Player called: %i, %i, %i, %i, \"%s\", %i", playerid, idx, tests, fails, lastfail, p);
#pragma unused p
#if defined RUN_TESTS
P:2("Testing_Player() called");
new
//idx,
buffer[32];
//while ((idx = AMX_GetPublicName(idx, buffer, "Tezt_@")))
if ((idx = AMX_GetPublicName(idx, buffer, "Tezp_@")))
{
strunpack(buffer, buffer);
//++YSI_g_sTests;
// Call the setup function if there is one.
buffer[0] = 'I';
buffer[1] = 'n';
buffer[2] = 'i';
buffer[3] = 'p';
CallLocalFunction(buffer, "");
// Call the test.
buffer[0] = 'T';
buffer[1] = 'e';
buffer[2] = 'z';
buffer[3] = 'p';
fails = YSI_g_sFails;
P:5("Testing_Player(): Calling %s", buffer[6]);
CallLocalFunction(buffer, "");
#if !defined TEST_SHOW_PASSES
if (YSI_g_sFails == fails)
{
printf(TEST_PASSED);
printf(" ");
}
#endif
/*if (YSI_g_sFails != fails)
{
if (YSI_g_sFails)
{
++YSI_g_sFails;
}
else
{
fails = 0;
// Copy the string over.
while ((lastfail[fails] = buffer[fails + 6])) ++fails;
YSI_g_sFails = 1;
}
//C:1(if (p) printf("*** Test failed: %s", buffer[fails + 6]););
}*/
// Call the shutdown function if there is one.
//buffer[0] = 'S';
//buffer[1] = 'h';
//buffer[2] = 'u';
//buffer[3] = 'p';
//CallLocalFunction(buffer, "");
}
tests = YSI_g_sTests;
fails = YSI_g_sFails;
return fails == 0;
#else
#pragma unused tests, fails, lastfail
return true;
#endif
}
#if defined RUN_TESTS
/*#define Test:%1() forward bool:Tezt_@%1(); public bool:Tezt_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
//#define Tests:%1() forward bool:Test_@%1(); public bool:Test_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
#define TestInit:%1() forward Init_@%1(); public Init_@%1() for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define TestClose:%1() forward Shut_@%1(); public Shut_@%1() for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define PTest:%1(%2) forward bool:Tezp_@%1(%2); public bool:Tezp_@%1(%2) for(new string:__name[]=#%1,bool:__once=(printf("*** Player Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
//#define Tests:%1() forward bool:Test_@%1(); public bool:Test_@%1() for(new string:__name[]=#%1,bool:__once=(printf("*** Test %s start", __name) || TRUE);__once;__once=(printf(" ") && FALSE))
#define PTestInit:%1(%2) forward Inip_@%1(%2); public Inip_@%1(%2) for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))
#define PTestClose:%1(%2) forward Shup_@%1(%2); public Shup_@%1(%2) for(new string:__name[]=#%1,bool:__once=TRUE;__once;__once=(printf(" ", __name) && FALSE))*/
#if defined _AUTO_RUN_TESTS
#if !defined FILTERSCRIPT
// Hook main in gamemodes.
main()
{
// Disable error messages (as we're likely to generate them).
state ysi_debug : off;
CallLocalFunction("Testing_main", "");
new
tests,
fails;
printf(" ");
printf(" ||===================|| ");
printf(" || STARTING TESTS... || ");
printf(" ||===================|| ");
printf(" ");
Testing_Run(tests, fails, _, true);
printf("*** Tests: %d, Fails: %d", tests, fails);
if (!fails)
{
printf(" ");
printf(" ||===================|| ");
printf(" || ALL TESTS PASSED! || ");
printf(" ||===================|| ");
printf(" ");
}
state ysi_debug : on;
}
#define main forward Testing_main(); public Testing_main
Testing_Next(playerid)
{
new
buffer[32];
for ( ; ; )
{
new
fails = YSI_g_sFails;
// Get the last test (nicely fails for cellmax).
if ((YSI_g_sPlayer = AMX_GetPublicName(YSI_g_sPlayer, buffer, "Tezp_@")))
{
strunpack(buffer, buffer);
// Call the shutdown function if there is one.
buffer[0] = 'S';
buffer[1] = 'h';
buffer[2] = 'u';
buffer[3] = 'p';
CallLocalFunction(buffer, "i", playerid);
}
// Get the new test, but don't store the index.
if (AMX_GetPublicName(YSI_g_sPlayer, buffer, "Tezp_@"))
{
YSI_g_sAsked = false;
//++YSI_g_sTests;
strunpack(buffer, buffer);
// Call the setup function if there is one.
buffer[0] = 'I';
buffer[1] = 'n';
buffer[2] = 'i';
buffer[3] = 'p';
CallLocalFunction(buffer, "i", playerid);
// Call the test.
buffer[0] = 'T';
buffer[1] = 'e';
buffer[2] = 'z';
buffer[3] = 'p';
P:5("Testing_Next(): Calling %s", buffer[6]);
CallLocalFunction(buffer, "i", playerid);
}
else
{
YSI_g_sAsked = true;
// No more tests.
printf("*** Tests: %d, Fails: %d", YSI_g_sTests, YSI_g_sFails);
if (!YSI_g_sFails)
{
printf(" ");
printf(" ||==========================|| ");
printf(" || ALL PLAYER TESTS PASSED! || ");
printf(" ||==========================|| ");
printf(" ");
}
}
// If the test needs a player but doesn't ask them anything
// then we can't wait for "OnDialogResponse" to run the next
// one.
if (YSI_g_sAsked)
{
break;
}
else if (fails == YSI_g_sFails)
{
printf(TEST_PASSED);
}
}
//while (!YSI_g_sAsked);
}
public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if (dialogid == Y_TESTING_DIALOG_ID)
{
++YSI_g_sTests;
if (response)
{
// Pass.
printf(TEST_PASSED);
}
else
{
// Fail.
printf(TEST_FAILED " %s", YSI_g_sFailMessage);
++YSI_g_sFails;
}
Testing_Next(playerid);
return 1;
}
#if defined Testing_OnDialogResponse
return Testing_OnDialogResponse(playerid, dialogid, response, listitem, inputtext);
#else
return 1;
#endif
}
#if defined _ALS_OnDialogResponse
#undef OnDialogResponse
#else
#define _ALS_OnDialogResponse
#endif
#define OnDialogResponse Testing_OnDialogResponse
#if defined Testing_OnDialogResponse
forward Testing_OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]);
#endif
public OnPlayerSpawn(playerid)
{
if (YSI_g_sPlayer == cellmax && !IsPlayerNPC(playerid))
{
printf(" ");
printf(" ||==========================|| ");
printf(" || STARTING PLAYER TESTS... || ");
printf(" ||==========================|| ");
printf(" ");
YSI_g_sTests = 0;
YSI_g_sFails = 0;
Testing_Next(playerid);
}
#if defined Testing_OnPlayerSpawn
return Testing_OnPlayerSpawn(playerid);
#else
return 1;
#endif
}
#if defined _ALS_OnPlayerSpawn
#undef OnPlayerSpawn
#else
#define _ALS_OnPlayerSpawn
#endif
#define OnPlayerSpawn Testing_OnPlayerSpawn
#if defined Testing_OnPlayerSpawn
forward Testing_OnPlayerSpawn(playerid);
#endif
#endif
#else
Testing_RunAll()
{
// Disable error messages (as we're likely to generate them).
state ysi_debug : off;
new
tests,
fails;
printf(" ");
printf(" ||===================|| ");
printf(" || STARTING TESTS... || ");
printf(" ||===================|| ");
printf(" ");
Testing_Run(tests, fails, _, true);
printf("*** Tests: %d, Fails: %d", tests, fails);
if (!fails)
{
printf(" ");
printf(" ||===================|| ");
printf(" || ALL TESTS PASSED! || ");
printf(" ||===================|| ");
printf(" ");
}
state ysi_debug : on;
}
#endif
#else
//#define Tests:%1() stock bool:Tests_@%1()
/*#define Test:%1() stock bool:Test_@%1()
#define TestInit:%1() stock Init_@%1()
#define TestClose:%1() stock Shut_@%1()
#define PTest:%1(%2) stock bool:Test_@%1(%2)
#define PTestInit:%1(%2) stock Init_@%1(%2)
#define PTestClose:%1(%2) stock Shut_@%1(%2)*/
#endif