package core;
import static core.VergeEngine.*;
import static core.Controls.*;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.util.List;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.RescaleOp;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Random;
import audio.VMusic;
import domain.VSound;
import domain.VImage;
import domain.Entity;
import domain.Map;
import static core.Script.screen;
import static core.Script.setlucent;
import static core.Script.showpage;
import static core.Script.timer;
import static core.SinCos.*;
public class Script {
// For Testing purposes (simulations)
public static boolean TEST_SIMULATION = false;
public static int TEST_POS = 0;
public static int[] TEST_OPTIONS;
//public static final int VCFILES = 51;
public static final int VC_READ = 1;
public static final int VC_WRITE = 2;
public static final int VC_WRITE_APPEND = 3; // Overkill (2006-07-05): Append mode added.
public static final int CF_GRAY = 1;
public static final int CF_INV_GRAY = 2;
public static final int CF_INV = 3;
public static final int CF_RED = 4;
public static final int CF_GREEN = 5;
public static final int CF_BLUE = 6;
public static final int CF_CUSTOM = 7;
// VERGE ENGINE VARIABLES: Moved to Script for easy of use
/**
* This is a hardcoded image handle for the screen. It is a pointer to a
* bitmap of the screen's current dimensions (set in verge.cfg or by
* SetResolution() function at runtime). Anything you want to appear in the
* verge window should be blitted here with one of the graphics functions.
* When ShowPage() is called the screen bitmap is transfered to the display.
*/
public static VImage screen;
// For partial screen rendering
static VImage virtualScreen = null;
/** read-only timer variable constantly increasing*/
public static int systemtime;
/** read/write timer variable*/
public static int timer;
// internal use only
static int vctimer = 0; // [Rafael, the Esper]
static int hooktimer = 0;
public static List<Entity> entity = new ArrayList<Entity>();
public static Entity myself = null;
/**
* The number of entities currently on the map. Use this an the upper bound
* any time you need to loop through and check entites for something.
*/
public static int numentities;
public static int player;
public static int playerstep = 1;
public static boolean playerdiagonals = true;
public static boolean smoothdiagonals = true; // [Rafael, the Esper]
public static int xwin, ywin;
public static Map current_map = null;
public static int cameratracking = 1;
public static int cameratracker = 0;
public static int lastplayerdir = 0;
public static boolean entitiespaused = false;
// END OF VERGE ENGINE VARIABLES
public static String renderfunc, timerfunc; // was VergeCallback (struct)
public static DefaultPalette palette = new DefaultPalette();
public static int transcolor = -65281; // Color(255, 0, 255);
public static int currentLucent = 255;
public static int event_tx;
public static int event_ty;
public static int event_zone;
public static int event_entity;
public static int event_param;
public static int event_sprite;
public static int event_entity_hit;
public static int __grue_actor_index;
private static VMusic musicplayer; // [Rafael, the Esper]
public static int invc;
public static String _trigger_onStep = "", _trigger_afterStep = "";
public static String _trigger_beforeEntityScript = "", _trigger_afterEntityScript = "";
public static String _trigger_onEntityCollide = "";
public static String _trigger_afterPlayerMove = "";
public static void error(String str) {
System.err.println(str);
}
static void hooktimer()
{
// To prevent hooktimer from happening before the script engine is loaded.
//if(se == null) return;
while (hooktimer != 0)
{
callfunction(timerfunc);
hooktimer--;
}
}
public static void hooktimer(String cb) {
hooktimer = 0;
timerfunc = cb;
}
public static void hookretrace()
{
if(renderfunc != null) {
callfunction(renderfunc);
}
}
public static void hookretrace(String cb) {
renderfunc = cb;
}
// Rafael: Changed to ExecuteFunctionString
/*public void ExecuteCallback(String function, boolean callingFromLibrary) */
public static void exit(String message) {
System.err.println(message);
System.exit(0);
}
/* Rafael: TODO Implement this.
public static void SetButtonJB(int b, int jb) {
switch (b)
{
case 1: j_b1 = jb; break;
case 2: j_b2 = jb; break;
case 3: j_b3 = jb; break;
case 4: j_b4 = jb; break;
}
}*/
// Overkill (2007-08-25): HookButton is supposed to start at 1, not 0.
// It's meant to be consistent with Unpress().
public static void hookbutton(int b, String s) {
if (b<1 || b>4) return;
bindbutton[b-1] = s;
}
public static void hookkey(int k, String s) {
if (k<0 || k>127) return;
bindarray[k] = s;
}
public static void log(String s) {
System.out.println(s);
}
/*
static void MessageBox(String msg) { showMessageBox(msg); }*/
public static int random(int min, int max) {
if(min > max) {
return random(max, min);
}
Random r = new Random(); // TODO Use unique random instance
return r.nextInt(max+1-min) + min;
}
public static void setAppName(String s) {
getGUI().setTitle(s);
}
public static void unpress(int n) {
switch (n)
{
case 0:
if (b1) UnB1();
if (b2) UnB2();
if (b3) UnB3();
if (b4) UnB4();
break;
case 1: if (b1) UnB1(); break;
case 2: if (b2) UnB2(); break;
case 3: if (b3) UnB3(); break;
case 4: if (b4) UnB4(); break;
case 5: if (up) UnUp(); break;
case 6: if (down) UnDown(); break;
case 7: if (left) UnLeft(); break;
case 8: if (right) UnRight(); break;
case 9:
if (b1) UnB1();
if (b2) UnB2();
if (b3) UnB3();
if (b4) UnB4();
if (up) UnUp();
if (down) UnDown();
if (left) UnLeft();
if (right) UnRight();
break;
}
}
public static void updateControls() {
Controls.UpdateControls();
}
public static int asc(String s) {
if(s.length() == 0)
return 0;
else
return (int)s.charAt(0);
}
public static String chr(int c) {
return Character.toString((char) c);
}
public static String gettoken(String s, String d, int i) { // Reimplemented by [Rafael, the Esper]
String[] retorno = s.split(d);
if(retorno.length <= i)
return "";
return retorno[i];
}
public static String left(String str, int len) {
return str.substring(0, str.length()>len?len:str.length());
}
public static int len(String s) {
return s.length();
}
public static String mid(String str, int pos, int len) {
return str.substring(pos, pos+len);
}
public static String right(String str, int len) {
return len > str.length() ? str : str.substring(str.length() - len);
}
public static String str(int d) {
return Integer.toString(d);
}
public static boolean strcmp(String s1, String s2) {
return s1.equals(s2); // ? 1 : 0;
}
public static String capitalize(String s) { // [Rafael, the Esper]
if (s.length() == 0) return s;
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
public static String strdup(String s, int times) {
String ret = "";
for (int i=0; i<times; i++)
ret = ret.concat(s);
return ret;
}
public static int tokencount(String s, String d) {
String[] retorno = s.split(d);
return retorno.length;
}
public static String trim(String s) {
return s.trim();
}
public static String tolower(String str) {
return str.toLowerCase();
}
public static String toupper(String str) {
return str.toUpperCase();
}
public static int val(String s) {
if(s==null || s.isEmpty() || s.trim().equals("-"))
return 0;
return Integer.valueOf(s.replace('+', ' ').trim());
}
//VI.d. Map Functions
public static void map(String map) {
mapname = map;
die = true;
done = true;
/* Hookretrace carries over between maps!
/ According to http://verge-rpg.com/docs/the-verge-3-manual/general-utility-functions/hookretrace/
hookretrace(""); */
}
//VI.e. Entity Functions
public static void changeCHR(int e, String c) {
if (e<0 || e >= numentities) return;
else entity.get(e).set_chr(c);
}
public static void entitymove(int e, String s) {
if (e<0 || e >= numentities) return;
else entity.get(e).setMoveScript(s);
}
public static void entitysetwanderdelay(int e, int d) {
if (e<0 || e >= numentities) return;
else entity.get(e).setWanderDelay(d);
}
public static void entitysetwanderrect(int e, int x1, int y1, int x2, int y2) {
if (e<0 || e >= numentities) return;
else entity.get(e).setWanderBox(x1, y1, x2, y2);
}
public static void entitysetwanderzone(int e) {
if (e<0 || e >= numentities) return;
else entity.get(e).setWanderZone();
}
public static int entityspawn(int x, int y, String s) {
return AllocateEntity(x*16,y*16,s);
}
public static int countParty(int first) {
if (first<0 || first >= numentities) return 0;
int num = 1;
Entity e = entity.get(first);
while(e.getFollower() != null) {
e = e.getFollower();
num++;
}
return num;
}
public static void entitystalk(int stalker, int stalkee) {
if (stalker<0 || stalker>=numentities)
return;
if (stalkee<0 || stalkee>=numentities)
{
entity.get(stalker).clear_stalk();
return;
}
entity.get(stalker).setx(entity.get(stalkee).getx()); // [Rafael, the Esper]
entity.get(stalker).sety(entity.get(stalkee).gety()); // [Rafael, the Esper]
entity.get(stalker).stalk(entity.get(stalkee));
}
public static void entitystop(int e) {
if (e<0 || e >= numentities) return;
else entity.get(e).setMotionless();
}
public static void hookentityrender(int i, String s) {
if (i<0 || i>=numentities)
System.err.printf("vc_HookEntityRender() - no such entity %d", i);
entity.get(i).hookrender = s;
}
public static void playermove(String s) {
if (myself==null)
return;
myself.setMoveScript(s);
int current_invc = invc;
invc=1;//Rafael
while(myself.movecode != 0 )
{
screen.render();
showpage();
}
invc=current_invc;//Rafael
playerentitymovecleanup();
}
public static void playerentitymovecleanup() {
if (myself==null) return;
myself.movecode = 0;
//[Rafael, the Esper] implementar afterPlayerMove();
}
public static void pauseplayerinput() { // [Rafael, the Esper]
invc = 1;
}
public static void unpauseplayerinput() { // [Rafael, the Esper]
invc = 0;
}
public static void setentitiespaused(boolean b) {
entitiespaused = b;
if (!entitiespaused)
lastentitythink = systemtime;
}
public static Entity setplayer(int e) {
if (e<0 || e>=numentities)
{
player = -1;
myself = null;
System.err.println("invalid Player.");
return null;
}
myself = entity.get(e);
player = e;
myself.setMotionless();
myself.obstructable = true;
return myself;
}
public static int getplayer()
{
return player;
}
/*
//VI.g. Sprite Functions
static int GetSprite() { return GetSprite(); }
static void ResetSprites() { return ResetSprites(); }
//VI.h. Sound/Music Functions
static void FreeSong(int handle) { FreeSong(handle); }
static void FreeSound(int slot) { FreeSample((void*)slot); }
static int GetSongPos(int handle) { return GetSongPos(handle); }
static int GetSongVolume(int handle) { return GetSongVol(handle); }
static int LoadSong(String fn) { return LoadSong(fn); }
static int LoadSound(String fn) { return (int)LoadSample(fn); }*/
public static void playsound(VSound sound) {
playsound(sound, 100);
}
public static void playsound(VSound sound, int volume) {
if(sound==null || VergeEngine.config.isNosound())
return;
if (volume < 0)
volume = 0;
else if (volume > 100)
volume = 100;
sound.start(volume);
}
public static URL getmusic() {
if(VergeEngine.config==null || VergeEngine.config.isNosound() || musicplayer==null)
return null;
return VMusic.getPlay();
}
public static void playmusic(URL fn) {
playmusic(fn, 100);
}
public static void playmusic(URL fn, int volume) {
if(fn==null || VergeEngine.config==null || VergeEngine.config.isNosound())
return;
if(musicplayer!=null) {
// If same music is playing, does nothing
if(musicplayer.getPlay().equals(fn)) {
return;
}
musicplayer.stop();
}
try {
musicplayer = new VMusic(volume);
log("Playing..." + fn);
musicplayer.start(fn);
}
catch(Exception e) {
System.err.println("Error when playing " + fn);
}
}
/*
static void PlaySong(int handle) { PlaySong(handle); }*/
/*public static int playsound(String name, int volume) {
return 0;
//return PlaySample((void*) slot, volume * 255 / 100);
}*/
public static void setMusicVolume(int v) {
if(VergeEngine.config==null || VergeEngine.config.isNosound())
return;
if(musicplayer!=null) {
musicplayer.setVolume(v);
} else {
musicplayer = new VMusic(v);
}
}
/*static void StopSong(int handle) { StopSong(handle); }
static void StopSound(int chan) { StopSound(chan); }
*/
/*static void SetSongPaused(int h, int p) { SetPaused(h,p); }
static void SetSongPos(int h, int p) { SetSongPos(h,p); }
static void SetSongVolume(int h, int v) { SetSongVol(h,v); } */
public static void stopmusic() {
if(musicplayer!=null) {
musicplayer.stop();
}
}
// Graphics
public static void setcustomcolorfilter(Color c1, Color c2) {
/*GetColor(c1, cf_r1, cf_g1, cf_b1);
GetColor(c2, cf_r2, cf_g2, cf_b2);
cf_rr = cf_r2 - cf_r1;
cf_gr = cf_g2 - cf_g1;
cf_br = cf_b2 - cf_b1;*/
// TODO [Rafael, the Esper] Implement this
graycolorfilter(screen.getImage());
error("Non implemented function: setcustomcolorfilter");
}
public static void setlucent(int p) {
if(p < 0 || p > 100)
return;
currentLucent = (100-p) * 255 / 100;
if(getGUI()!=null)
getGUI().setAlpha ((float)(100-p) / 100);
}
static int lastchangetime = 0;
public static void showpage() {
//if(lastchangetime++ > 1) {
lastchangetime = 0;
if(virtualScreen!=null) {
//finalScreen.blit(0, 0, screen);
screen.blit(0, 0, virtualScreen);
}
//else {
//finalScreen.blit(0, 0, screen);
//}
//}
Controls.UpdateControls();
DefaultTimer();//[Rafael, the Esper]
GUI.paintFrame();
/*if(toClipboard) {
toClipboard = false;
screen.copyImageToClipboard();
}*/
}
public static void lightfilter(int scalefactor, VImage vimage) {
RescaleOp op = new RescaleOp((float)scalefactor/100, 0, null);
op.filter(vimage.image, vimage.image);
}
private static BufferedImageOp op = null;
public static void graycolorfilter(BufferedImage img) {
if(op==null)
op = new ColorConvertOp (ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
img = op.filter(img, img);
return;
}
public static void colorfilter(int filter, VImage img) {
if(filter>6) return;
if(filter==1) {
if(op==null)
op = new ColorConvertOp (ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
op.filter(img.getImage(), img.getImage());
return;
}
int rr, gg, bb, z; Color c = null;
int x1,x2,y1,y2;
// [Rafael, the Esper] img.GetClip(x1,y1,x2,y2);
x1 = y1 = 0;
x2 = img.width;
y2 = img.height;
//PT ptr = (PT)img.data;
//PT data = (PT)&ptr[(y1 * img.pitch) + x1];
for (int y=y1; y<y2; y++)
{
//int* data_end = data+x2+1;
for(int x=x1;x<x2;x++) {
int rgb = img.getImage().getRGB(x, y);
//Color col = new Color(img.getImage().getRGB(x, y));
if (rgb == transcolor) continue; // Overkill (2006-07-27): Ignore trans pixels
rr = (rgb >> 16) & 0x000000FF;
gg = (rgb >>8 ) & 0x000000FF;
bb = (rgb) & 0x000000FF;
//GetColor(col, rr, gg, bb);
//if(filter==2) System.out.printf("%d %d %d %d\n", rr, gg, bb, 255-((rr+gg+bb)/3));
switch (filter)
{
case 0:
case 1: z = (rr+gg+bb)/3; c = new Color(z,z,z); break; // GRAY
case 2: z = 255-((rr+gg+bb)/3); c = new Color(z,z,z); break;
case 3: c = new Color(255-rr, 255-gg, 255-bb); break;
case 4: z = (rr+gg+bb)/3; c = new Color(z, 0, 0); break; // RED
case 5: z = (rr+gg+bb)/3; c = new Color(0, z, 0); break; // GREEN
case 6: z = (rr+gg+bb)/3; c = new Color(0, 0, z); break; // BLUE
// [Rafael, the Esper] Custom color filter case 7: z = (rr+gg+bb)/3; c = new Color(cf_r1+((cf_rr*z)>>8), cf_g1+((cf_gr*z)>>8), cf_b1+((cf_br*z)>>8)).getRGB(); break;
}
img.setPixel(x, y, c);
}
}
}
public static Color RGB(int r, int g, int b) {
return new Color(r, g, b);
}
public static Color mixcolor(Color c1, Color c2, int p) {
if (p>255) p=255;
if (p<0) p=0;
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
return new Color((r1*(255-p)/255)+(r2*p/255), (g1*(255-p)/255)+(g2*p/255), (b1*(255-p)/255)+(b2*p/255));
}
public static int getB(int c) {
return palette.getColor(c, currentLucent).getBlue();
}
public static int getG(int c) {
return palette.getColor(c, currentLucent).getGreen();
}
public static int getR(int c) {
return palette.getColor(c, currentLucent).getRed();
}
/*
static int HSV(int h, int s, int v) { return HSVtoColor(h,s,v); }
static int GetH(int col) {
int h, s, v;
GetHSV(col, h, s, v);
return h;
}
static int GetS(int col) {
int h, s, v;
GetHSV(col, h, s, v);
return s;
}
static int GetV(int col) {
int h, s, v;
GetHSV(col, h, s, v);
return v;
}
static void HueReplace(int hue_find, int hue_tolerance, int hue_replace, int image) {
HueReplace(hue_find, hue_tolerance, hue_replace, ImageForHandle(image));
}
static void ColorReplace(int find, int replace, int image)
{
ColorReplace(find, replace, ImageForHandle(image));
}
*/
//VI.j. Math Functions
//helper:
public static int abs(int i) {
return Math.abs(i);
}
public static int sgn(int i) {
return (int) Math.signum(i);
}
public static int mydtoi(double d) { return (int)Math.floor(d + 0.5); }
static int acos(int val) {
double dv = (double) val / 65535;
double ac = Math.acos(dv);
ac = ac * 180 / 3.14159265358979; // convert radians to degrees
return mydtoi(ac);
}
public static int facos(int val) {
double dv = (double) val / 65535;
double ac = Math.acos(dv);
ac *= 65536; // Convert to 16.16 fixed point
return mydtoi(ac);
}
public static int asin(int val) {
double dv = (double) val / 65535;
double as = Math.asin(dv);
as = as * 180 / 3.14159265358979; // convert radians to degrees
return mydtoi(as);
}
public static int fasin(int val) {
double dv = (double) val / 65535;
double as = Math.asin(dv);
as *= 65536; // Convert to 16.16 fixed point
return mydtoi(as);
}
public static int atan(int val) {
double dv = (double) val / 65535;
double at = Math.atan(dv);
at = at * 180 / 3.14159265358979; // convert radians to degrees
return mydtoi(at);
}
public static int fatan(int val) {
double dv = (double) val / 65535;
double at = Math.atan(dv);
at *= 65536; // Convert to 16.16 fixed point
return mydtoi(at);
}
public static int atan2(int y, int x) {
float f = (float) Math.atan2((float)y,(float)x);
return (int)(f/2.0/3.14159265358979*360.0);
}
public static int fatan2(int y, int x) {
double theta = Math.atan2((double) y, (double) x);
return mydtoi(theta * 65536);
}
public static int sin(int n) {
while (n < 0) n += 360;
while (n >= 360) n -= 360;
return sintbl[n];
}
public static int cos(int n) {
while (n < 0) n += 360;
while (n >= 360) n -= 360;
return costbl[n];
}
public static int tan(int n) {
while (n < 0) n += 360;
while (n >= 360) n -= 360;
return tantbl[n];
}
public static int fsin(int val) {
double magnitude = Math.sin((double) val / 65536);
return mydtoi(magnitude * 65536);
}
public static int fcos(int val) {
double magnitude = Math.cos((double) val / 65536);
return mydtoi(magnitude * 65536);
}
public static int ftan(int val) {
double magnitude = Math.tan((double) val / 65536);
return mydtoi(magnitude * 65536);
}
public static int pow(int a, int b) {
return (int) Math.pow((double)a, (double)b);
}
public static int sqrt(int val) {
return (int) (float) Math.sqrt((float) val);
}
// Util Functions
private static boolean isLetterDigitOrSignal(char c) {
if(Character.isLetterOrDigit(c) || c=='+' || c=='-')
return true;
return false;
}
// Split String in trimmed words
public static List<String> splitTextIntoWords(String text) {
int initial = 0;
List<String> words = new ArrayList<String>();
if(text==null)
return words;
for(int i=0; i<text.length(); i++) {
while(i<text.length() && (isLetterDigitOrSignal(text.charAt(i)) || text.charAt(i) == '\'')) {
i++;
}
while(i<text.length() && !isLetterDigitOrSignal(text.charAt(i))) {
i++;
}
words.add(text.substring(initial, i).trim());
initial = i;
}
return words;
}
// Split list of words into rows
public static List<String> splitTextIntoRows(String text, int maxperrow) {
List<String> words = splitTextIntoWords(text);
List<String> rows = new ArrayList<String>();
int i = 0;
String str;
while (i < words.size()) {
str = words.get(i);
while (i < words.size()-1 && str.length()+ 1 + words.get(i+1).length() <= maxperrow) {
str = str.concat(" " + words.get(i+1));
i += 1;
}
rows.add(str);
str = "";i+=1;
}
return rows;
}
public static boolean up, down, left, right;
public static boolean b1, b2, b3, b4;
public static final int SCAN_A = java.awt.event.KeyEvent.VK_A;
public static final int SCAN_B = java.awt.event.KeyEvent.VK_B;
public static final int SCAN_C = java.awt.event.KeyEvent.VK_C;
public static final int SCAN_D = java.awt.event.KeyEvent.VK_D;
public static final int SCAN_E = java.awt.event.KeyEvent.VK_E;
public static final int SCAN_F = java.awt.event.KeyEvent.VK_F;
public static final int SCAN_G = java.awt.event.KeyEvent.VK_G;
public static final int SCAN_H = java.awt.event.KeyEvent.VK_H;
public static final int SCAN_I = java.awt.event.KeyEvent.VK_I;
public static final int SCAN_J = java.awt.event.KeyEvent.VK_J;
public static final int SCAN_K = java.awt.event.KeyEvent.VK_K;
public static final int SCAN_L = java.awt.event.KeyEvent.VK_L;
public static final int SCAN_M = java.awt.event.KeyEvent.VK_M;
public static final int SCAN_N = java.awt.event.KeyEvent.VK_N;
public static final int SCAN_O = java.awt.event.KeyEvent.VK_O;
public static final int SCAN_P = java.awt.event.KeyEvent.VK_P;
public static final int SCAN_Q = java.awt.event.KeyEvent.VK_Q;
public static final int SCAN_R = java.awt.event.KeyEvent.VK_R;
public static final int SCAN_S = java.awt.event.KeyEvent.VK_S;
public static final int SCAN_T = java.awt.event.KeyEvent.VK_T;
public static final int SCAN_U = java.awt.event.KeyEvent.VK_U;
public static final int SCAN_V = java.awt.event.KeyEvent.VK_V;
public static final int SCAN_W = java.awt.event.KeyEvent.VK_W;
public static final int SCAN_X = java.awt.event.KeyEvent.VK_X;
public static final int SCAN_Y = java.awt.event.KeyEvent.VK_Y;
public static final int SCAN_Z = java.awt.event.KeyEvent.VK_Z;
public static final int SCAN_0 = java.awt.event.KeyEvent.VK_0;
public static final int SCAN_1 = java.awt.event.KeyEvent.VK_1;
public static final int SCAN_2 = java.awt.event.KeyEvent.VK_2;
public static final int SCAN_3 = java.awt.event.KeyEvent.VK_3;
public static final int SCAN_4 = java.awt.event.KeyEvent.VK_4;
public static final int SCAN_5 = java.awt.event.KeyEvent.VK_5;
public static final int SCAN_6 = java.awt.event.KeyEvent.VK_6;
public static final int SCAN_7 = java.awt.event.KeyEvent.VK_7;
public static final int SCAN_8 = java.awt.event.KeyEvent.VK_8;
public static final int SCAN_9 = java.awt.event.KeyEvent.VK_9;
public static boolean getkey(int key) {
return Controls.getKey(key);
}
/*
// Overkill (2006-06-30): Gets the contents of the key buffer.
// TODO: Implement for other platforms.
static String GetKeyBuffer()
{
//#ifdef __WIN32__
return keybuffer;
//#else
//err("The function GetKeyBuffer() is not defined for this platform.");
//return String();
//#endif
}
// Overkill (2006-06-30): Clears the contents of the key buffer.
// TODO: Implement for other platforms.
static void FlushKeyBuffer()
{
//#ifdef __WIN32__
FlushKeyBuffer();
//#else
//err("The function FlushKeyBuffer() is not defined for this platform.");
//#endif
}
// Overkill (2006-06-30): Sets the delay in centiseconds before key repeat.
// TODO: Implement for other platforms.
static void SetKeyDelay(int d)
{
if (d < 0)
{
d = 0;
}
//#ifdef __WIN32__
key_input_delay = d;
//#else
// err("The function SetKeyDelay() is not defined for this platform.");
//#endif
}
*/
public static void setVirtualScreen(VImage dest) {
virtualScreen = dest;
}
public static VImage getVirtualScreen() {
return virtualScreen;
}
// Function (method) calling
public static boolean functionexists(String function) {
return executefunction(function, true);
}
/** Check methods in the following order:
*
* 1. Direct Class-method (ex: sully.vc.v1_menu.Menu_System.DrawMenu)
* 2. System Lib (executed class, ex: Sully.class + method)
* 3. Loaded Map Class (ex: Bumsville.class + method)
*
* The called function must be public and without parameters.
* The capitalized version is also checked (ex: "entStart" checks also for "EntStart")
* If the function is not found, nothing happens
*
*/
public static void callfunction(String function) {
executefunction(function, false);
}
private static boolean executefunction(String function, boolean justCheck) {
if(function==null || function.isEmpty())
return false;
Class path = null;
// This means that it is a direct class-method
if (function.lastIndexOf(".") != -1) {
String s = function.substring(function.lastIndexOf(".") + 1);
String t = function.substring(0, function.lastIndexOf("."));
try {
path = systemclass.forName(t);
}
catch(ClassNotFoundException cnfe) {
error("Class " + path + " not found for direct execution (" + function + ")");
return false;
}
invokeMethod(path, s, justCheck);
return true;
}
else { // Try to find the class in the current_map
boolean notFoundInMap = false;
StringBuilder cName = new StringBuilder();
if(current_map != null && current_map.getFilename() != null) {
cName.append(systemclass.getPackage().getName() + ".");
int pos = current_map.getFilename().lastIndexOf('\\');
if(pos==-1)
pos = 0;
StringBuilder b = new StringBuilder(current_map.getFilename().toLowerCase());
b.replace(pos, pos+1, String.valueOf(Character.toUpperCase(b.charAt(pos))));
String s = b.toString().substring(0, b.indexOf(".map")).replace('\\', '.');
cName.append(s);
try {
path = systemclass.forName(cName.toString());
}
catch(ClassNotFoundException cnfe) {
// FIXME Solve this mess, also use toUppercase and Capitalize first letter to avoid error on .MAP
b = new StringBuilder(systemclass.getPackage().getName() + "." + mapname);
s = b.toString().substring(0, b.lastIndexOf(".map")).replace('\\', '.').replace('/', '.');
try {
path = systemclass.forName(s);
} catch (ClassNotFoundException e) {
error("Class " + path + " not found for map execution.");
notFoundInMap = true; //return;
}
}
if(path!=null) {
if (!invokeMethod(path, function, justCheck))
notFoundInMap = true;
else
return true; // Success
}
}
// Try to find the method directly in the System class
if(current_map == null || current_map.getFilename() == null || notFoundInMap) {
path = systemclass;
if (invokeMethod(path, function, justCheck)) {
return true; // Success
}
else {
error("Error invoking " + function + " in path " + path);
}
}
}
return false;
}
private static boolean invokeMethod(Class c, String function, boolean justCheck) {
Method[] allMethods = c.getDeclaredMethods();
for (Method m : allMethods) {
String mname = m.getName();
if(mname.equals(function) || mname.equals(capitalize(function))) {
if(justCheck)
return true;
try {
//log("Found method " + mname + " in path " + c); // just for debug
m.invoke(null);
return true;
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return false;
}
/**
* Method for loading resources from the classpath, like images, fonts, sounds, etc
*/
public static URL load(String url) {
if(TEST_SIMULATION) // [Rafael, the Esper]
return null;
log("(" + systemclass + ")" + ", reading: " + url);
URL resource = systemclass.getResource(url);
// Optional code, a little robustness to avoid case-sensitive issues
if(resource == null) { // try to capitalize
String newUrl;
if(url.lastIndexOf('/') != -1)
newUrl = url.substring(0, url.lastIndexOf('/')+1) +
capitalize(url.substring( url.lastIndexOf('/')+1));
else
newUrl = capitalize(url);
log("WARNING! Resource not found. Trying to read: " + newUrl);
resource = systemclass.getResource(newUrl);
if(resource==null) { // try uppercase
if(url.lastIndexOf('/') != -1)
newUrl = url.substring(0, url.lastIndexOf('/')+1) +
url.substring( url.lastIndexOf('/')+1).toUpperCase();
else
newUrl = url.toUpperCase();
log("WARNING! Resource not found. Trying to read: " + newUrl);
resource = systemclass.getResource(newUrl);
}
if(resource==null) { // try lowercase
if(url.lastIndexOf('/') != -1)
newUrl = url.substring(0, url.lastIndexOf('/')+1) +
url.substring( url.lastIndexOf('/')+1).toLowerCase();
else
newUrl = url.toLowerCase();
log("WARNING! Resource not found. Trying to read: " + newUrl);
resource = systemclass.getResource(newUrl);
}
if(resource==null) {
error("ERROR! Resource not found: " + url);
}
}
syncAfterLoading(); // Rafael, the Esper
return resource;
}
public static void setSystemPath(Class c) {
systemclass = c;
}
}