Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- findplayer("Graal5635647").addweapon(this.name);
- // Online Level NPC Editor
- // By fp4 (fowlplay4/Jerret)
- // Note:
- // (npcserver) requires rw access to the levels
- // in order to update NPC changes.
- //
- // I.e: rw levels/*.nw
- //
- // Clientside Configuration is down below.
- function onCreated() {
- // Serverside Folder Configuration
- this.levelfolders = {
- "levels/%s",
- "levels/shared/%s"
- };
- //levels/users/theirID/levels/levelname.nw
- for (temp.pl: allplayers) {
- temp.playerfolder = "levels/users/" @ temp.pl.account @ "/levels/";
- if (!(temp.playerfolder in this.levelfolders)) {
- this.levelfolders.add(temp.playerfolder @ "%s");
- }
- }
- echo(this.levelfolders);
- this.removenonexistantimages = false;
- }
- function onActionServerSide() {
- if (params[0] == "loadlevel") {
- // Find Level
- temp.file = getfile(params[1]);
- // Check if Level Found
- if (temp.file == NULL) {
- player.triggerclient("weapon", this.name, "msg", format("Could not find the file %s for this level! Check Configuration.", params[1]));
- return;
- }
- // Check if Player Has Access to Level
- if (!player.hasright("r", temp.file)) {
- player.triggerclient("weapon", this.name, "msg", "You don't have access to this level!");
- return;
- }
- // Get Level Modification Time
- temp.modtime = getfilemodtime(temp.file);
- // Check if Level Locked
- for (temp.pl: players) {
- temp.lock = temp.pl.client.olne_lock;
- if (temp.lock[0] == temp.file && temp.lock[1] == temp.modtime) {
- player.triggerclient("weapon", this.name, "msg", format("%s is currently editing this level's NPCs!", (temp.pl.communityname ? temp.pl.communityname : temp.pl.account)));
- return;
- }
- }
- // Set Level Lock Flag
- client.olne_lock = {temp.file, temp.modtime};
- // Check if Readonly Access
- temp.readonly = !player.hasright("w", temp.file);
- // Load File
- temp.lines.loadlines(temp.file);
- // Parse NPC Sections of File
- for (temp.line: temp.lines) {
- if (temp.reading) {
- if (temp.line == "NPCEND") {
- temp.leveldata.add({
- temp.npc_img,
- temp.npc_x,
- temp.npc_y,
- temp.npc_script
- });
- temp.reading = false;
- } else {
- temp.npc_script.add(temp.line);
- }
- } else {
- if (temp.line.starts("NPC ")) {
- temp.tokens = temp.line.tokenize();
- if (temp.tokens.size() == 4) {
- temp.npc_img = temp.tokens[1];
- temp.npc_x = temp.tokens[2];
- temp.npc_y = temp.tokens[3];
- temp.npc_script = {};
- temp.reading = true;
- }
- }
- }
- }
- // Send Data to Client
- player.triggerclient("weapon", this.name, "leveldata", temp.leveldata, temp.readonly);
- }
- else if (params[0] == "savelevel") {
- // Find Level
- temp.file = getfile(params[1]);
- // Check for Write Access to File
- if (!player.hasright("w", temp.file)) {
- player.triggerclient("weapon", this.name, "msg", "You can't make changes to this level!");
- return;
- }
- // Load Level
- temp.lines.loadlines(temp.file);
- temp.newlines = {};
- // Parse Level Ignore NPC Sections
- for (temp.line: temp.lines) {
- if (temp.skipping) {
- if (temp.line == "NPCEND") {
- temp.skipping = false;
- }
- } else {
- if (temp.line.starts("NPC ")) {
- temp.skipping = true;
- } else {
- temp.newlines.add(temp.line);
- }
- }
- }
- // Parse NPC Data
- temp.npcdata = params[2];
- for (temp.data: temp.npcdata) {
- temp.npc_img = temp.data[0];
- temp.npc_x = temp.data[1];
- temp.npc_y = temp.data[2];
- temp.npc_script = temp.data[3];
- if ((this.removenonexistantimages && !fileexists(temp.npc_img)) || temp.npc_img.trim() == "") {
- temp.npc_img = "-";
- }
- // Add NPC Sections to Level
- temp.newlines.add(format("NPC %s %s %s", temp.npc_img, temp.npc_x, temp.npc_y));
- if (temp.npc_script != NULL) {
- temp.newlines.addarray(temp.npc_script);
- }
- temp.newlines.add("NPCEND");
- }
- // Save Level
- temp.newlines.savelines(temp.file, 0);
- // Log
- savelog2("olne_log.txt", format("%s updated %s using OLNE!", player.account, temp.file));
- // Unlock Level
- client.olne_lock = "";
- // Send Message
- player.triggerclient("weapon", this.name, "msg", "NPCs Saved!");
- }
- else if (params[0] == "resetlock") {
- client.olne_lock = "";
- }
- }
- /*
- This is where i left off. Check where the filepath is stored and then if it is stored somewhere
- in levels/users/ then format by applying the player's ID as well.
- */
- function getfile(filename) {
- for (temp.folder: this.levelfolders) {
- temp.path = format(temp.folder, filename);
- if (fileexists(temp.path)) {
- return temp.path;
- }
- }
- return NULL;
- }
- //#CLIENTSIDE
- // Clientside Configuration
- const PLACEHOLDER = "mum_npc_placeholder.png";
- const SHOWIMGPART = true; // Detects First ShowImgPart Usage (Even if commented out)
- const SHOWCHARS = true; // Displays Gani Character for NPCs
- const RIGHTMENUTIME = 0.3;
- const GRAALMINIMUM = 6;
- function onPlayerEnters() {
- // Wait for NPCs to Load
- waitfor(this, "RandomEvent", 0.05);
- // Hide Images
- hideimgs(200,20008);
- // Reset Variables
- this.updatedscripts = false;
- this.active = false;
- // Unhide NPCs
- visibleNPCs(true);
- // Reset Lock
- if (client.olne_lock != "") {
- triggerserver("gui", this.name, "resetlock");
- }
- }
- function GraalControl.onKeyUp(key) {
- // Check if F9 Pressed
- if (key == VK_F9) {
- if (!this.active) {
- // Load Level
- displayMSG("Loading NPCs...");
- triggerserver("gui", this.name, "loadlevel", player.level.name, player.account);
- } else {
- // Check if Update Required
- if (this.updatedscripts) {
- displayMSG("Saving NPCs...");
- triggerserver("gui", this.name, "savelevel", player.level.name, getNPCData());
- this.updatedscripts = false;
- } else {
- triggerserver("gui", this.name, "resetlock");
- }
- // Unhide NPCs and Hide Images
- visibleNPCs(true);
- hideimgs(200,10000);
- this.active = false;
- }
- }
- // Check if Delete Pressed
- else if (key == VK_DELETE) {
- // Check if has selection
- if (this.active && this.selected > 0) {
- // Delete selected NPC
- deleteSelection();
- }
- }
- }
- // Displays Message
- // Fades Message After 3 Seconds
- function displayMSG(msg) {
- with (findimg(20000)) {
- x = screenwidth / 2;
- y = screenheight - 45;
- text = msg;
- style = "bc";
- textshadow = true;
- shadowcolor = "0 0 0";
- zoom = 1;
- alpha = 1;
- layer = 4;
- }
- this.scheduleevent(3, "HideMSG", "");
- }
- // Fades out Message
- function onHideMSG() {
- while (findimg(20000).alpha > 0) {
- findimg(20000).alpha -= 0.1;
- waitfor(this, "RandomEvent", 0.05);
- }
- hideimg(20000);
- }
- function onActionClientSide() {
- // Check for Level Data
- if (params[0] == "leveldata") {
- // Hide NPCs
- visibleNPCs(false);
- // Reset Images
- hideimgs(200,10000);
- // Initialize Variables
- temp.leveldata = params[1];
- temp.i = 0;
- this.levelnpcs = {};
- // Determine Top-Left Corner of Level
- if (player.gmap != NULL) {
- temp.tx = player.x - (player.x % 64);
- temp.ty = player.y - (player.y % 64);
- } else {
- temp.tx = temp.ty = 0;
- }
- // Parse NPC Data
- echo(temp.leveldata.size());
- for (temp.data: temp.leveldata) {
- // Determine ID and Other Variables
- temp.npc_id = 200 + temp.i;
- temp.npc_img = temp.data[0];
- temp.npc_x = temp.data[1];
- temp.npc_y = temp.data[2];
- temp.npc_script = temp.data[3];
- // Draw NPC
- updateNPCImage(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script);
- // Add to Level NPCs Array
- this.levelnpcs.add(temp.npc_id);
- // Increment Counter
- temp.i++;
- echo(temp.npc_script.length());
- echo(temp.i);
- }
- echo("hidemsg");
- // Stop Hide Message Timer
- this.cancelevents("HideMSG");
- // Check if Read-only Access
- if (params[2]) {
- // Warn Read-only
- displayMSG("You don't have rights to change this level!");
- } else {
- // Hide Loading Message
- this.trigger("HideMSG", "");
- }
- // Toggle Active Flag
- this.active = true;
- setTimer(0.05);
- }
- // Check if Displaying Message
- else if (params[0] == "msg") {
- // Disable Fading
- this.cancelevents("HideMSG");
- // Display Message
- displayMSG(params[1]);
- }
- }
- function updateNPCImage(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script) {
- // Determine Top-Left Corner of Level
- if (player.gmap != NULL) {
- temp.tx = player.x - (player.x % 64);
- temp.ty = player.y - (player.y % 64);
- } else {
- temp.tx = temp.ty = 0;
- }
- with(findimg(temp.npc_id)) {
- x = temp.tx + temp.npc_x;
- y = temp.ty + temp.npc_y;
- // Check if showimgpart NPCs Enabled
- if (temp.npc_script.lower().pos("setimgpart ") >= 0 || temp.npc_script.lower().pos("setimgpart(") >= 0 || temp.npc_script.lower().pos("setgifpart ") >= 0) {
- // Check if contains showimgpart
- if (SHOWIMGPART) {
- // Isolate and Determine Parameters
- temp.str = temp.npc_script.substring(temp.npc_script.pos("setimgpart"));
- temp.str = temp.str.substring(0, temp.str.pos(";"));
- temp.str = temp.str.substring("setimgpart ".length());
- temp.tokens = temp.str.tokenize(",");
- if (temp.tokens.size() == 6) temp.tokens.delete(0);
- if (temp.tokens.size() == 5) {
- image = temp.tokens[0].trim();
- // Remove Quotes and Braces
- while (image.starts("(")) image = image.substring(1);
- while (image.starts('"')) image = image.substring(1);
- while (image.ends('"')) image = image.substring(0,image.length()-1);
- // Check if Image Exists
- if (!fileexists(image)) {
- // Draw NPCs Image
- image = (!fileexists(npc_img) ? PLACEHOLDER : npc_img);
- // Determine Width and Height
- this.width = getimgwidth(image) / 16;
- this.height = getimgheight(image) / 16;
- } else {
- partx = math_eval(temp.tokens[1].trim());
- party = math_eval(temp.tokens[2].trim());
- partw = math_eval(temp.tokens[3].trim());
- parth = temp.tokens[4].trim();
- // Remove End Brace
- while (parth.ends(")")) parth = parth.substring(0, parth.length()-1);
- // Calculate Part Height
- parth = math_eval(parth);
- // Minimum Width and Height
- if (partw < 0) partw = 16;
- if (parth < 0) parth = 16;
- this.width = partw / 16;
- this.height = parth / 16;
- }
- } else {
- // Invalid Default to Placeholder
- image = PLACEHOLDER;
- this.width = this.height = 3;
- }
- } else {
- // Draw Placeholder
- image = PLACEHOLDER;
- this.width = this.height = 3;
- }
- }
- // Check if NPC is Character
- else if (temp.npc_script.pos("showcharacter") >= 0) {
- if (SHOWCHARS) {
- // Set Animation
- ani = getCharAni(npc_script);
- playerlook = false;
- // Head
- temp.head = getActorValue("head", npc_script);
- if (temp.head) actor.head = temp.head;
- // Body
- temp.body = getActorValue("body", npc_script);
- if (temp.body) actor.bodyimg = temp.body;
- // Shield
- temp.shield = getActorValue("shield", npc_script);
- if (temp.shield) actor.shield = temp.shield;
- // Colors
- for (temp.i = 0; temp.i < 5; temp.i++) {
- temp.color = getActorValue("colors", npc_script, temp.i);
- if (temp.color) actor.colors[temp.i] = temp.color;
- }
- // Attributes
- for (temp.i = 0; temp.i < 30; temp.i++) {
- temp.attr = getActorValue("attr", npc_script, temp.i);
- if (temp.attr) actor.attr[temp.i] = temp.attr;
- }
- // Direction
- actor.dir = getVarValue("dir", temp.npc_script);
- } else {
- image = PLACEHOLDER;
- }
- this.width = this.height = 3;
- }
- // NPC Isn't Special
- else {
- // Draw NPCs Image
- image = (!fileexists(npc_img) ? PLACEHOLDER : npc_img);
- // Determine Width and Height
- this.width = getimgwidth(image) / 16;
- this.height = getimgheight(image) / 16;
- }
- }
- // Set Script and Image
- setNPCScript(temp.npc_id, temp.npc_script);
- setNPCImage(temp.npc_id, temp.npc_img);
- }
- function setNPCScript(npc_id, npc_script) {
- thiso.("npcscript_" @ npc_id) = npc_script;
- }
- function getNPCScript(npc_id) {
- return thiso.("npcscript_" @ npc_id);
- }
- function setNPCImage(npc_id, npc_image) {
- thiso.("npcimage_" @ npc_id) = npc_image;
- }
- function getNPCImage(npc_id) {
- return thiso.("npcimage_" @ npc_id) ? this.("npcimage_" @ npc_id) : "";
- }
- function getActorValue(part, npc_script, extra) {
- switch (part) {
- case "head":
- temp.i = getCharPropValue("#3", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("head", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("headimg", npc_script);
- return fileexists(temp.i) ? temp.i : "head0.png";
- break;
- case "body":
- temp.i = getCharPropValue("#8", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("body", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("bodyimg", npc_script);
- return fileexists(temp.i) ? temp.i : "body.png";
- break;
- case "shield":
- temp.i = getCharPropValue("#2", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("shield", npc_script);
- if (temp.i == NULL) temp.i = getVarValue("shieldimg", npc_script);
- return fileexists(temp.i) ? temp.i : "no-shield.png";
- break;
- case "colors":
- temp.i = getCharPropValue("#C" @ extra, npc_script);
- if (temp.i == NULL) temp.i = getVarValue("colors[" @ extra @ "]", npc_script);
- return temp.i; // RED DRAGONS
- break;
- case "attr":
- temp.i = getCharPropValue("#P" @ extra, npc_script);
- if (temp.i == NULL) temp.i = getVarValue("attr[" @ extra @ "]", npc_script);
- return temp.i;
- break;
- }
- }
- function getCharPropValue(prop, npc_script) {
- temp.p = "setcharprop " @ prop @ ",";
- temp.a = npc_script.pos(temp.p);
- if (temp.a >= 0) {
- temp.s = npc_script.substring(temp.a + temp.p.length());
- temp.s = temp.s.substring(0, temp.s.pos(";"));
- if (temp.s == "0") temp.s = "white";
- return temp.s;
- } else {
- return NULL;
- }
- }
- function getVarValue(vari, npc_script) {
- // Find Variable
- temp.aa = npc_script.positions(vari);
- for (temp.a: temp.aa) {
- // Check for Assignment
- temp.s = npc_script.substring(temp.a);
- temp.e = temp.s.pos("=");
- temp.c = temp.s.pos(";");
- // Make Sure Semi-Colon is After Assignment
- if (temp.e < temp.c) {
- // Ignore ""
- if (temp.s.pos("\"\"") >= 0) return "";
- // Determine Value
- temp.s = temp.s.substring(temp.e+1);
- temp.sc = temp.s.pos(";");
- temp.s = temp.s.substring(0, (temp.sc == -1 ? temp.s.length() : temp.sc));
- temp.s = temp.s.trim();
- if (temp.s.size() == 2) {
- temp.s.delete(0);
- temp.s = temp.s[0];
- }
- // Remove Double-Quotes
- while (temp.s.starts('"')) temp.s = temp.s.substring(0);
- while (temp.s.ends('"')) temp.s = temp.s.substring(0,temp.s.length()-1);
- // (0) White Color Fix
- if (vari.starts("colors") && (temp.s == "0")) {
- temp.s = "white";
- }
- // Return Value
- return temp.s;
- }
- }
- return NULL;
- }
- function getCharAni(npc_script) {
- temp.p = npc_script.lower().pos("setcharani ");
- temp.q = npc_script.lower().pos("setcharani(");
- if (temp.p >= 0 || temp.q >= 0) {
- if (temp.q == -1) temp.q = temp.p;
- temp.s = npc_script.substring(temp.q);
- temp.s = temp.s.substring(0, temp.s.pos(",")-1);
- temp.s = temp.s.substring("setcharani ".length());
- if (temp.s.size() == 2) {
- temp.s.delete(0);
- temp.s = temp.s[0];
- }
- // Remove Double Quotes
- while (temp.s.starts('"')) temp.s = temp.s.substring(1);
- while (temp.s.ends('"')) temp.s = temp.s.substring(0, temp.s.length()-1);
- // Return Value
- return (fileexists(temp.s @ ".gani") ? temp.s : "idle");
- }
- return "idle";
- }
- function getNPCData() {
- // Initialize Data Array
- temp.npcdata = {};
- // Loop through NPCs
- for (temp.npc_id: this.levelnpcs) {
- // Check if has script
- temp.npc_script = getNPCScript(temp.npc_id);
- temp.no_script = (temp.npc_script.size() == 1 && temp.npc_script[0].trim() == "");
- temp.npc_img = getNPCImage(temp.npc_id);
- with (findimg(temp.npc_id)) {
- // Add NPC Data to Array
- temp.npcdata.add({
- temp.npc_img,
- (x % 64),
- (y % 64),
- (temp.no_script ? NULL : temp.npc_script)
- });
- }
- }
- // Return NPC Data
- return temp.npcdata;
- }
- function onTimeout() {
- // Check if Active
- if (this.active) {
- // Right Drag Menu
- if (this.rightdragging) {
- // Check if Right Mouse Down
- if (!rightmousebutton) {
- // Close Menu
- this.rmorigin_x = "";
- this.rmorigin_y = "";
- this.rightdragging = "";
- onHideContextMenu();
- } else {
- // Check If Time to Display Menu Yet
- if (timevar2 > this.rightdragging_init) {
- // Fade in Menu
- if (this.rightalpha < 1) {
- this.rightalpha += 0.25;
- }
- with (findimg(20003)) {
- x = thiso.rmorigin_x;
- y = thiso.rmorigin_y - 0.25;
- text = "Mouse over the NPC to create it!";
- style = "bc";
- textshadow = true;
- shadowcolor = "0 0 0";
- zoom = 0.5;
- alpha = thiso.rightalpha;
- }
- with (findimg(20004)) {
- x = thiso.rmorigin_x - 1.5;
- y = thiso.rmorigin_y - 5;
- image = PLACEHOLDER;
- alpha = thiso.rightalpha;
- }
- with (findimg(20005)) {
- x = thiso.rmorigin_x - 1.5;
- y = thiso.rmorigin_y + 2;
- ani = "idle";
- playerlook = false;
- actor.head = "head0.png";
- actor.colors[0] = "orange";
- actor.colors[1] = "white";
- actor.colors[2] = "blue";
- actor.colors[3] = "red";
- actor.colors[4] = "black";
- actor.shield = "no-shield.png";
- actor.dir = 2;
- actor.alpha = thiso.rightalpha;
- }
- temp.ydiff = mousey - this.rmorigin_y;
- temp.creating = false;
- if (temp.ydiff in |-5,-1.75|) {
- // Create Placeholder
- temp.creating = "placeholder";
- }
- else if (temp.ydiff in |2,5|) {
- // Create NPC
- temp.creating = "npc";
- }
- if (temp.creating) {
- // Hide Images
- onHideContextMenu();
- this.rmorigin_x = "";
- this.rmorigin_y = "";
- this.rightdragging = "";
- // Determine Next NPC ID
- temp.npc_id = this.levelnpcs[this.levelnpcs.size()-1] + 1;
- // Set NPC Variables
- temp.npc_x = mousex % 64;
- temp.npc_y = mousey % 64;
- temp.npc_img = "";
- temp.npc_script = {
- "// Created by " @ player.account
- };
- // Generate Script
- if (temp.creating == "npc") {
- temp.npc_script.addarray({
- "function onCreated() {",
- " showcharacter();",
- " this.head = \"head0.png\";",
- " this.colors[0] = \"orange\";",
- " this.colors[1] = \"white\";",
- " this.colors[2] = \"blue\";",
- " this.colors[3] = \"red\";",
- " this.colors[4] = \"black\";",
- " this.shield = \"no-shield.png\";",
- " this.dir = 2;",
- " setcharani(\"idle\",NULL);",
- "}"
- });
- }
- // Changes Made
- changesMade();
- // Draw NPCs
- updateNPCImage(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script);
- // Add to List
- this.levelnpcs.add(temp.npc_id);
- // Begin Dragging
- this.dragoffsetx = 1;
- this.dragoffsety = 1;
- this.dragging = temp.npc_id;
- }
- } else {
- this.rmorigin_x = mousex;
- this.rmorigin_y = mousey;
- }
- }
- }
- // Check if Dragging
- else if (this.dragging) {
- // Check if Mouse Button Down
- if (leftmousebutton || rightmousebutton) {
- // Draw GMAP Boundaries
- if (player.gmap != NULL) {
- drawBoundaries();
- }
- // Determine Level Boundaries
- if (player.gmap != NULL) {
- temp.tx = player.x - (player.x % 64);
- temp.ty = player.y - (player.y % 64);
- } else {
- temp.tx = temp.ty = 0;
- }
- // Move NPC
- with (findimg(this.dragging)) {
- x = int(mousex - thiso.dragoffsetx);
- y = int(mousey - thiso.dragoffsety);
- // Force Boundaries
- if (x < temp.tx) x = temp.tx;
- else if (x > (temp.tx + 63)) x = temp.tx + 63;
- if (y < temp.ty) y = temp.ty;
- else if (y > (temp.ty + 63)) y = temp.ty + 63;
- // Set Alpha
- if (actor.head) {
- actor.alpha = (timevar2 > thiso.waitalpha ? 0.5 : 1);
- } else {
- alpha = (timevar2 > thiso.waitalpha ? 0.8 : 1);
- }
- }
- // Update Selected NPC
- this.selected = this.dragging;
- } else {
- // Determine Level Boundaries
- if (player.gmap != NULL) {
- temp.tx = player.x - (player.x % 64);
- temp.ty = player.y - (player.y % 64);
- } else {
- temp.tx = temp.ty = 0;
- }
- with (findimg(this.dragging)) {
- if (!(x in |temp.tx,temp.tx + 64| && temp.ty in |temp.ty,temp.ty + 64|)) {
- temp.outsidebounds = true;
- }
- // Check if Position Changed
- temp.updating = ((x SPC y) != this.original);
- // Set Alpha Back to Normal
- if (actor.head) {
- actor.alpha = 1;
- } else {
- alpha = 1;
- }
- this.original = "";
- }
- if (temp.updating) {
- // Changes Made Tell Editor
- changesMade();
- }
- if (temp.outsidebounds) {
- this.cancelevents("HideMSG");
- displayMSG("Please place the NPC in the boundaries of the level!");
- }
- // Hide Boundaries
- hideBoundaries();
- // Unset Dragging Flag
- this.dragging = false;
- }
- }
- // Check for Selected NPC
- if (this.selected > 0) {
- // Draw Box Around Selection
- drawSelection();
- }
- setTimer(0.05);
- }
- }
- function drawBoundaries() {
- with (findimg(20006)) {
- x = player.x - (player.x % 64);
- y = player.y - (player.y % 64);
- this.width = 64;
- this.height = 64;
- alpha = 0.5;
- polygon = poly_hollowbox(x,y,this.width,this.height);
- }
- }
- function hideBoundaries() {
- hideimg(20006);
- }
- function onHideContextMenu() {
- findimg(20003).alpha -= 0.2;
- findimg(20004).alpha -= 0.2;
- findimg(20005).actor.alpha -= 0.2;
- if (findimg(20003).alpha > 0) {
- this.scheduleevent(0.05, "HideContextMenu", "");
- } else {
- hideimgs(20003,20005);
- }
- }
- // Draws Box Around Selection
- function drawSelection() {
- // Glitched in V5
- if (graalversion < 6) {
- with (findimg(this.selected)) {
- alpha = 0.8;
- actor.alpha = 0.5;
- }
- return;
- }
- temp.selection = findimg(this.selected);
- with (findimg(20001)) {
- x = temp.selection.x;
- y = temp.selection.y;
- width = temp.selection.width;
- height = temp.selection.height;
- temp.s = 2/8;
- red = blue = green = 0.9;
- polygon = poly_hollowbox(x-temp.s,y-temp.s,width+(temp.s*1.5),height+(temp.s*1.5));
- }
- this.last_selected = this.selection;
- }
- // poly_funcs::hollow_box()
- public function poly_hollowbox(qx,qy,qw,qh) {
- qd=1/8;
- return {qx,qy, qx+qw,qy, qx+qw,qy+qh, qx,qy+qh, qx,qy,
- qx+qd,qy+qd, qx+qd,qy+qh+qd, qx+qw+qd,qy+qh+qd, qx+qw+qd,qy+qd, qx+qd,qy+qd};
- }
- // Deletes Selected NPC
- function deleteSelection() {
- // Remove NPC from Level NPCs Array
- this.levelnpcs.remove(this.selected);
- // Hide NPC
- hideimg(this.selected);
- // Notify Editor of Change
- changesMade();
- // Remove Selection Box
- removeSelection();
- }
- function removeSelection() {
- // V5 Selection just does Alpha
- if (graalversion < 6) {
- with (findimg(this.selected)) {
- alpha = 1;
- actor.alpha = 1;
- }
- }
- // Unset Selected NPC Value
- this.selected = "";
- // Hide Box Image
- hideimg(20001);
- }
- function GraalControl.onMouseDown(a, tx, ty, clickcount) {
- if (!this.active) return;
- temp.double = false;
- if (clickcount == 2) {
- temp.dist = vectordist({mousex, mousey, 0}, this.last_click);
- if (temp.dist < 0.5) {
- temp.double = true;
- }
- }
- if (temp.double) {
- onMousePressed("double");
- } else {
- onMousePressed("left");
- }
- this.last_click = {mousex, mousey, 0};
- }
- function GraalControl.onRightMouseDown() {
- if (!this.active) return;
- onMousePressed("right");
- }
- function onMousePressed(click) {
- if (!this.active) return;
- switch (click) {
- case "left":
- // Drag
- if (!this.dragging) {
- // Find Nearest NPC
- this.dragging = getClosestNPCID();
- if (this.dragging > 0) {
- // Determine Drag Offset and Original Position
- with (findimg(this.dragging)) {
- thiso.dragoffsetx = mousex - x;
- thiso.dragoffsety = mousey - y;
- this.original = x SPC y;
- }
- // Draw Selection
- this.selected = this.dragging;
- drawSelection();
- // Set Time Before Turns Transparent
- this.waitalpha = timevar2 + 0.1;
- } else {
- // No NPC was Found
- this.dragging = false;
- // Remove Selection Box
- removeSelection();
- }
- }
- this.lastclick = (int(mousex) SPC int(mousey));
- break;
- case "right":
- // Duplicate
- temp.dupe = getClosestNPCID();
- if (temp.dupe > 0) {
- // Determine Next NPC ID
- temp.npc_id = this.levelnpcs[this.levelnpcs.size()-1] + 1;
- // Find NPC to Dupe
- temp.duping = findimg(temp.dupe);
- // Create New NPC
- temp.npc_img = getNPCImage(temp.dupe);
- temp.npc_x = temp.duping.x % 64;
- temp.npc_y = temp.duping.y % 64;
- temp.npc_script = getNPCScript(temp.dupe);
- updateNPCImage(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script);
- // Begin Dragging Duplicate NPC
- this.waitalpha = timevar2 + 0.10;
- this.dragoffsetx = mousex - temp.duping.x;
- this.dragoffsety = mousey - temp.duping.y;
- this.dragging = temp.npc_id;
- // Add to Level NPCs Array
- this.levelnpcs.add(temp.npc_id);
- // Notify Editor of Change Made
- changesMade();
- // Display Duplication Message to User
- displayMSG("NPC Duplicated!");
- } else {
- // Remove Selection
- removeSelection();
- // Make sure not Draggin Right Mouse
- if (!this.rightdragging) {
- // Set Origin of Mouse
- this.rmorigin_x = mousex;
- this.rmorigin_y = mousey;
- // Begin Right Drag
- this.rightdragging = true;
- // Declare Time to Create Right-Context Menu
- this.rightdragging_init = timevar2 + RIGHTMENUTIME;
- this.rightalpha = 0;
- }
- }
- break;
- case "double":
- // Record Time of Doubleclick
- if (this.selected > 0) {
- this.doubleclick = timevar2;
- }
- break;
- }
- }
- function GraalControl.onMouseUp() {
- // Check if mouse up within recent double click
- if (timevar2 in |this.doubleclick,this.doubleclick+0.25|) {
- // Open Script of Nearest NPC to Mouse
- temp.closest_id = getClosestNPCID();
- if (temp.closest_id != NULL) {
- temp.npc_script = getNPCScript(temp.closest_id);
- temp.npc_img = getNPCImage(temp.closest_id);
- with (findimg(temp.closest_id)) {
- createEditorWindow(temp.closest_id, temp.npc_img, x, y, temp.npc_script);
- }
- }
- }
- }
- // Finds Nearest NPC in Level NPCs to Mouse X and Y
- function getClosestNPCID() {
- // Loop through NPCs
- for (temp.npc_id: this.levelnpcs) {
- with (findimg(temp.npc_id)) {
- if (mousex in |x,x+this.width| && mousey in |y,y+this.height|) {
- temp.found.add({
- temp.npc_id, x, y
- });
- }
- }
- }
- // Check if any Found
- if (temp.found.size() > 0) {
- if (temp.found.size() == 1) {
- // Set Closest ID to Only One Found
- temp.closest_id = temp.found[0][0];
- } else {
- // Determine Which ID is Closest
- temp.closest_id = temp.found[0][0];
- temp.closest_dist = vectordist({mousex, mousey, 0}, {temp.found[0][1], temp.found[0][2], 0});
- for (temp.i = 1; temp.i < temp.found.size(); temp.i++) {
- temp.dist = vectordist({mousex, mousey}, temp.found[temp.i].subarray(1));
- if (temp.dist < temp.closest_dist) {
- temp.closest_id = temp.found[temp.i][0];
- temp.closest_dist = temp.dist;
- }
- }
- }
- // Return Closest NPC ID
- return temp.closest_id;
- } else {
- // No NPC Found
- return NULL;
- }
- }
- function changesMade() {
- // Check if Not Updated
- if (!this.updatedscripts) {
- // Display 'How to Save' Message to User
- displayMSG("Press F9 to save changes when your ready!");
- // Set Updated Flag for Editor
- this.updatedscripts = true;
- }
- }
- // For scheduling display messages
- function onReminder(msg) {
- displayMSG(msg);
- }
- // Create Editor Window
- function createEditorWindow(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script) {
- new GuiMLTextEditProfile("SyntaxHighlightLegacyProfile") {
- fontType = fileexists("DejaVuSansMono.ttf") ? "DejaVuSansMono" : "Courier";
- fontSize = (thiso.options.scriptfontsize <= 0 ? 14 : thiso.options.scriptfontsize);
- cursorColor = "0 0 0";
- fillColorHL = "255 255 0";
- fontColor = "0 0 0";
- fontColorHL = "192 0 0"; // control words like if, else etc.
- fontColorSEL = "0 16 0"; // identifiers 0,96,0
- fontColorLink = "192 0 192"; // strings
- fontColorLinkHL = "0 0 255"; // numbers
- }
- new GuiWindowCtrl("LevelNPC_" @ temp.npc_id @ "_Window") {
- profile = GuiBlueWindowProfile;
- clientrelative = true;
- this.npc_id = temp.npc_id;
- temp.ww = clientwidth = 600;
- temp.wh = clientheight = 500;
- x = (screenwidth - temp.ww) / 2;
- y = (screenheight - temp.wh) / 2;
- isexternal = true;
- text = format("NPC Script Editor (X: %s Y: %s)", temp.npc_x % 64, temp.npc_y % 64);
- destroyonhide = true;
- thiso.trigger("CenterExternalWindow", this);
- new GuiScrollCtrl("LevelNPC_" @ temp.npc_id @ "_ScriptScroll") {
- profile = GuiBlueScrollProfile;
- scrollprofile = GuiBlueScrollProfile;
- useownprofile = true;
- profile.fillColor = "255 255 255";
- profile.opaque = true;
- profile.border = 1;
- profile.bitmap = "guiblue_scroll_noback.png";
- horizsizing = "width";
- vertsizing = "height";
- clientwidth = temp.ww;
- clientheight = temp.wh - 40;
- new GuiMLTextEditCtrl("LevelNPC_" @ temp.npc_id @ "_Script") {
- profile = SyntaxHighlightLegacyProfile;
- useownprofile = true;
- profile.fillcolorhl = "80 180 255";
- profile.fontcolorlink = "255 0 255";
- profile.fontsize = 15;
- horizsizing = "width";
- syntaxhighlighting = true;
- wordwrap = false;
- clientheight = temp.wh;
- clientwidth = temp.ww - 40;
- width -= 4;
- setlines(temp.npc_script);
- temp.scriptctrl = this;
- autoindenting = true;
- tabspaces = 2;
- }
- }
- new GuiButtonCtrl("LevelNPC_" @ temp.npc_id @ "_ScriptClose") {
- profile = GuiBlueButtonProfile;
- horizsizing = "left";
- vertsizing = "top";
- clientwidth = 64;
- clientheight = 32;
- x = temp.ww - 68;
- y = temp.wh - 40 + 4;
- text = "Close";
- thiso.catchevent(this.name, "onAction", "onCloseScript");
- }
- new GuiButtonCtrl("LevelNPC_" @ temp.npc_id @ "_ScriptApply") {
- profile = GuiBlueButtonProfile;
- horizsizing = "left";
- vertsizing = "top";
- clientwidth = 64;
- clientheight = 32;
- x = temp.ww - 68 - 64 - 4;
- y = temp.wh - 40 + 4;
- text = "Apply";
- thiso.catchevent(this.name, "onAction", "onApplyScript");
- }
- new GuiTextEditCtrl("LevelNPC_" @ temp.npc_id @ "_Image") {
- profile = GuiBlueTextEditProfile;
- clientwidth = 256;
- clientheight = 24;
- x = 4;
- y = temp.wh - 24 - 10;
- text = temp.npc_img;
- thiso.catchevent(this.name, "onAction", "onUpdateImage");
- temp.imgctrl = this;
- }
- this.scriptctrl = temp.scriptctrl;
- this.imgctrl = temp.imgctrl;
- }
- }
- function onCenterExternalWindow(obj) {
- with (obj.externalwindow) {
- x = screenbounds[0] + (screenbounds[2] - width) / 2;
- y = screenbounds[1] + (screenbounds[3] - height) / 2;
- }
- }
- // Update Image in Text Box
- function onUpdateImage(obj) {
- if (!this.active) return;
- temp.npc_img = obj.text.trim();
- with (findimg(obj.parent.npc_id)) {
- image = temp.npc_img;
- image = fileexists(image) ? image : PLACEHOLDER;
- this.width = getimgwidth(image) / 16;
- this.height = getimgheight(image) / 16;
- }
- setNPCImage(temp.npc_id, temp.npc_img);
- changesMade();
- }
- // Closes Script
- function onCloseScript(obj) {
- obj.parent.destroy();
- }
- // Saves NPC Script and Image
- function onApplyScript(obj) {
- if (!this.active) {
- obj.parent.destroy();
- return;
- }
- temp.npc_id = obj.parent.npc_id;
- temp.npc_script = obj.parent.scriptctrl.getlines();
- temp.npc_img = obj.parent.imgctrl.text.trim();
- obj.parent.destroy();
- with (findimg(temp.npc_id)) {
- image = temp.npc_img;
- image = fileexists(image) ? image : PLACEHOLDER;
- temp.npc_x = x % 64;
- temp.npc_y = y % 64;
- }
- setNPCImage(temp.npc_id, temp.npc_img);
- setNPCScript(temp.npc_id, temp.npc_script);
- if (temp.npc_id > 0) {
- changesMade();
- updateNPCImage(temp.npc_id, temp.npc_img, temp.npc_x, temp.npc_y, temp.npc_script);
- }
- }
- // Hides/Shows Level NPCs
- function visibleNPCs(showing) {
- // Determine Top-Left Position
- if (player.gmap != NULL) {
- temp.tx = player.x - (player.x % 64);
- temp.ty = player.y - (player.y % 64);
- } else {
- temp.tx = temp.ty = 0;
- }
- // Loop through NPCs
- for (temp.npc: npcs) {
- // Check if Showing NPCs
- if (showing) {
- // Check if Was Hidden
- if (temp.npc.washidden != "") {
- // Return Original Visible State
- temp.npc.visible = temp.npc.washidden;
- temp.npc.washidden = "";
- }
- } else {
- // Check if in Current Level
- if (temp.npc.x in |temp.tx,temp.tx+64| && temp.npc.y in |temp.ty,temp.ty+64|) {
- // Hide NPC
- temp.npc.washidden = temp.npc.visible && !showing;
- temp.npc.visible = false;
- }
- }
- }
- }
- /*
- Math Eval Functions
- */
- public function math_eval(temp.equ, temp.stack) {
- // Brackets
- temp.stack++;
- temp.opn = temp.equ.positions("(");
- temp.end = temp.equ.positions(")");
- if (opn.size() != end.size()) return "Bracket Mismatch";
- while (temp.opn.size() > 0) {
- // Isolate Inner Brackets
- temp.spos = temp.opn[temp.opn.size()-1];
- temp.epos = temp.equ.substring(temp.spos).pos(")");
- temp.nequ = temp.equ.substring(temp.spos+1, temp.epos - 1);
- temp.result = math_eval(temp.nequ, temp.stack);
- temp.equ = temp.equ.substring(0, temp.spos) @ temp.result @ temp.equ.substring(temp.spos+temp.epos+1);
- temp.opn = temp.equ.positions("(");
- }
- // Remove Spaces
- temp.equ = clearSpaces(temp.equ);
- // Evaluate
- temp.operations = {"^", "/", "*", "+", "-", "<", ">", "<=", ">=", "!=", "==", "&&", "||"};
- for (temp.op: temp.operations) {
- while (temp.equ.pos(temp.op) > 0) {
- temp.fpos = temp.equ.pos(temp.op);
- // Find A
- temp.apos = "";
- for (temp.j = temp.fpos-temp.op.length(); temp.j > 0 && !temp.apos; temp.j--) {
- temp.sop = temp.equ.charat(temp.j);
- temp.dop = temp.sop @ temp.equ.charat(temp.j-1);
- if (temp.dop in temp.operations || temp.sop in temp.operations) {
- temp.apos = temp.j;
- temp.a = temp.equ.substring(temp.apos + 1, temp.fpos - temp.apos - 1);
- }
- }
- if (!temp.apos) {
- temp.a = temp.equ.substring(0, temp.fpos);
- }
- if (hasValue(temp.a)) temp.a = getValue(temp.a);
- // Find B
- temp.bpos = "";
- for (temp.k = temp.fpos+temp.op.length()+1; temp.k < temp.equ.length() && !temp.bpos; temp.k++) {
- temp.sop = temp.equ.charat(temp.k);
- temp.dop = temp.sop @ temp.equ.charat(temp.k+1);
- if (temp.sop in temp.operations || temp.dop in temp.operations) {
- temp.bpos = k;
- temp.b = temp.equ.substring(temp.fpos + temp.op.length(), temp.bpos - temp.fpos - 1);
- }
- }
- if (!temp.bpos) {
- temp.b = temp.equ.substring(temp.fpos+temp.op.length());
- }
- if (hasValue(temp.b)) temp.b = getValue(temp.b);
- // Calculate Result
- temp.result = evaluate(temp.a, temp.op, temp.b);
- // Rebuild Equation
- temp.str = temp.apos ? temp.equ.substring(0, temp.apos + 1) : "";
- temp.end = temp.bpos ? temp.equ.substring(temp.bpos) : "";
- temp.equ = temp.str @ temp.result @ temp.end;
- }
- }
- temp.result = hasValue(temp.equ) ? getValue(temp.equ) : float(temp.equ);
- return temp.result ? temp.equ : temp.result;
- }
- function clearSpaces(temp.l) {
- while (temp.l.pos(" ") >= 0) {
- temp.l = temp.l.substring(0, temp.l.pos(" ")) @ temp.l.substring(temp.l.pos(" ")+1);
- }
- return temp.l;
- }
- function evaluate(a, op, b) {
- switch(op) {
- case "equal":
- case "==":
- case "=":
- return a == b || a == int(float(b));
- case "&&":
- return a && b;
- case "||":
- return a || b;
- case "!=":
- return a != b;
- case ">":
- return a > b;
- case ">=":
- return a >= b;
- case "<":
- return a < b;
- case "<=":
- return a <= b;
- case "&":
- return a & b;
- case "^":
- return a ^ b;
- case "|":
- return a | b;
- case "in": // array only
- return a in b;
- case "*":
- return a * b;
- case "/":
- return a / b;
- case "+":
- return a + b;
- case "-":
- return a -b;
- }
- return 0;
- }
- function hasValue(temp.svar) {
- return getValue(temp.svar);
- }
- function getValue(temp.svar) {
- return this.(@temp.svar);
- }
Add Comment
Please, Sign In to add comment