Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - boodals 2

Pages: 1 ... 3 4 5 6 7 [8] 9 10 11 12 13 ... 66
106
Modification Help / Re: Quite a few questions
« on: June 01, 2015, 04:54:59 PM »
3. What are script objects? How do I use them? How are they useful?
Script objects are extremely useful. They are TorqueScript's version of object oriented programming (google it).

4. How do I get source code from a default function?
You either ask someone who has decrypted the .dso files, or decrypt them yourself.

5. Is it possible to bring up a list of default global variables? How?
Put $ in console, press tab repetitively. Alternatively you could try exporting "$*", however recently that seems to be crashing for whatever reason.

7. What is the correct way to call a parent function in a package?
parent::FUNCTION(%ARG1, %ARG2, ... , %ARGN);
Make sure that you return that if the function you are packaging returns something. If in doubt, do it anyway.

8. How can I store variables for clients? (Player persistence?)
Use file objects to create a file that stores the data. Its a big subject, look them up.

107
Modification Help / Re: [Resource] Simple Task Manager
« on: May 31, 2015, 11:42:15 AM »
I've been considering making an 'Advanced' Task Manager, which would be similar to this, except designed myself. There's several features i'd love to have (such as tasks looping until a condition is met), however I want to keep this version entirely to the documentation given. Would anyone else want that?

108
I've seen something before where someone used console commands to make the fov extremely large and just made the image go across 3 screens, but I'm not sure if it's exactly the same.

Other than GUI stuff, that's all this is.

109
Add-Ons / Re: Synth8
« on: May 29, 2015, 07:20:37 AM »
Holy stuff that's a lot of sound files, waaayy past practicality.

110
Modification Help / Re: [Resource] Simple Task Manager
« on: May 28, 2015, 02:04:51 PM »
Could you also give an example of how this can be used?

The documentation has a bunch of demonstrations, but without context. Ill make some up here too.

Say you were making a simple AI. The bot will wander around until AIPlayer::OnBotSeeTarget is called, it will then aim at the target and repeatedly fire its weapon, until its dead.

Code: [Select]
function AIPlayer::CreateTaskManager(%bot) { //Call this when the bot is created
%bot.taskMgr = newTaskManager(%bot);
%bot.taskMgr.selfExecuteTasks(false); //Makes the manager execute the tasks automatically
%bot.taskMgr.addTask("wander(10);", -1, 0, 1000); //Every 1000ms, wander around (actually just calls %bot.wander(10); )
}

function AIPlayer::OnBotSeeTarget(%bot, %target) {
%bot.taskMgr.addTaskFront("fireWeapon();", 10, 1, 200); //Every 200ms, fire weapon, up to 10 times. After that, it will go back to wandering.
%bot.taskMgr.addTaskFront("aimAt(%target);"); //As soon as the bot sees a target, aim at them (assume this is instant) (this will be put before fireWeapon) (this will only be done once)
}

function AIPlayer::OnBotTargetDead(%bot, %target) {
%bot.taskMgr.clearTasks();
%bot.taskMgr.addTask("wander(10);", -1, 0, 1000); //Wander again
}



Yeah that isn't the best example. Its really quite powerful though. Read the top half of the documentation.


How about infinite chunked terrain generation? You want to generate chunks nearest to the player, but want to schedule it out so that it doesnt lag the server. Just make a manager, %mgr.setDefaultTaskDelay(500); %mgr.selfExecuteTasks(true); and then add chunks to be generated, and every 500ms it will generate the next one on the list.

111
Modification Help / [Resource] Simple Task Manager
« on: May 28, 2015, 01:45:26 PM »
A simple task manager that was built into the original TGE FPS kit. I recreated it because I figured it would be really useful to have around. I recreated it from the documentation, and tested it using the given examples (and also a bunch of other tests).

As documented here on pages 367 to 377.

In short, lets you queue up functions to be called in a specified order, with optional delays.

Code: [Select]
////Simple Task Manager
//As documented http://www-rohan.sdsu.edu/~stewart/GPGT/Appendix%20A%20-%20Quick%20References.pdf
// on pages 367 to 377

function newTaskManager(%target) {
%mgr = new ScriptGroup() {
class = SimpleTaskMgr;

target = isObject(%target) ? %target.getID() : 0;
useTarget = isObject(%target);
selfExecution = 0;
defaultTaskDelay = -1; //Defaults to instant
useDefaultDelay = 0;
};

return %mgr;
}

function SimpleTaskMgr::setTarget(%mgr, %target) {
%mgr.target = isObject(%target) ? %target.getID() : 0;
%mgr.useTarget = isObject(%target);
}
function SimpleTaskMgr::clearTarget(%mgr) {
%mgr.target = 0;
%mgr.useTarget = 0;
}
function SimpleTaskMgr::getTarget(%mgr) {
return %mgr.useTarget ? (isObject(%mgr.target) ? %mgr.target : 0) : 0;
}
function SimpleTaskMgr::setDefaultTaskDelay(%mgr, %delay) {
%mgr.defaultTaskDelay = %delay;
}

function SimpleTaskMgr::selfExecuteTasks(%mgr, %useDefaultDelay) {
%mgr.selfExecution = 1;
if(%useDefaultDelay !$= "") {
%mgr.useDefaultDelay = %useDefaultDelay ? 1 : 0;
}

if(%mgr.getCount() <= 0)
return;

%task = %mgr.getObject(0);
if(!isEventPending(%mgr.tickSch)) {
%time = %mgr.useDefaultDelay ? %mgr.defaultTaskDelay : %task.delay;
if(%time == -1) {
%mgr.executeNextTask(); //Instant execution
} else {
%mgr.tickSch = %mgr.schedule(%time, executeNextTask);
}
}
}
function SimpleTaskMgr::stopSelfExecution(%mgr) {
//Doesnt cancel the next function call
//Stops after the next function execution

%mgr.selfExecution = 0;
}


function SimpleTaskMgr::addTask(%mgr, %task, %recycleCount, %preempt, %taskDelay) {
%recycleCount = mFloor(%recycleCount); //Convert to int, just incase
if(%recycleCount == 0) //0 recycles (or left blank) executes once
%recycleCount = 1;
if(%taskDelay $= "") //Undefined time executes instantly
%taskDelay = -1;

%taskObj = new ScriptObject() {
class = EGTask; //I have no idea why its EGTask, just following the documentation

task = %task;
recycleCount = %recycleCount;
preempt = %preempt;
delay = %taskDelay;
};
%mgr.add(%taskObj);

if(%mgr.selfExecution && !isEventPending(%mgr.tickSch)) {
//Start the schedule again
%firstTask = %mgr.getObject(0);
if(!isEventPending(%mgr.tickSch)) {
%time = %mgr.useDefaultDelay ? %mgr.defaultTaskDelay : %firstTask.delay;
if(%time == -1) {
%mgr.executeNextTask(); //Instant execution
} else {
%mgr.tickSch = %mgr.schedule(%time, executeNextTask);
}
}
}

return %taskObj;
}
function SimpleTaskMgr::addTaskFront(%mgr, %task, %recycleCount, %preempt, %taskDelay) {
%task = %mgr.addTask(%task, %recycleCount, %preempt, %taskDelay); //Slightly less efficient, however less code duplication

%mgr.bringToFront(%task);

return %task;
}
function SimpleTaskMgr::clearTasks(%mgr) {
//Delete all tasks
while(%mgr.getCount() > 0) {
%mgr.getObject(0).delete();
}
}

function SimpleTaskMgr::executeNextTask(%mgr) {
if(%mgr.getCount() <= 0)
return "";

%task = %mgr.getObject(0);
%result = %task.execute();

if(!isObject(%mgr)) //If the manager was deleted during execution (eg with TERMINATE# token)
return "";

//If the LOCK# token is in the task, dont store the return value for current task
if(strPos(%task.task, "LOCK#") == -1)
%mgr.lastReturnVal = %result;

if(%task.recycleCount == -1 || %task.recycleCount-- > 0) {
if(%task.preempt) {
//Dont push to back, leave at front
} else {
%mgr.pushToBack(%task);
}
} else {
%mgr.pushToBack(%task); //This is to make sure the set keeps its order
%task.delete();
}

if(%mgr.selfExecution && %mgr.getCount() > 0) {
//Start the schedule for the next execution
%task = %mgr.getObject(0);

if(!isEventPending(%mgr.tickSch)) {
%time = %mgr.useDefaultDelay ? %mgr.defaultTaskDelay : %task.delay;
if(%time == -1) {
%mgr.executeNextTask(); //Instant execution
} else {
%mgr.tickSch = %mgr.schedule(%time, executeNextTask);
}
}
}

return %result;
}


function EGTask::execute(%task) {
%mgr = %task.getGroup();

%eval = %task.task;

//LOCK# is handled in SimpleTaskMgr::executeNextTask, but we still need to remove it
%eval = strReplace(%eval, "LOCK#", "");
%eval = strReplace(%eval, "LASTRET#", %task.getGroup() @ ".lastReturnVal"); //Replace with last return value
%eval = strReplace(%eval, "TASKMGR#", %task.getGroup()); //Replace with %mgr
%eval = strReplace(%eval, "TASK#", %task.getID()); //Replace with task.getID();

%eval = strReplace(%eval, "%this", %mgr.getID()); //Allows for "func(%this.val)"

switch$(%eval) {
case "TERMINATE#": //Delete mgr
%mgr.delete();
//echo("Terminate");
return "";
case "NULL#": //Empty task, used for delays
//echo("Null");
return "";
default:
//Need to use eval (unfortunately) to keep to documentation
if(%mgr.useTarget && strPos(%eval, "STMT#") == -1) {
if(isObject(%target = %mgr.target)) {
%result = eval(%mgr.target @ "." @ %eval);
//echo("eval(\"" @ %mgr.target @ "." @ %eval @ "\");");
}
} else {
//Execute as a stand alone function, not a method
%result = eval(strReplace(%eval, "STMT#", ""));
//echo("eval(\"" @ strReplace(%eval, "STMT#", "") @ "\");");
}

return %result;
}

}

function EGTask::setTaskDelay(%task, %delay) {
%task.delay = %delay;
}
task = %task;
recycleCount = %recycleCount;
preempt = %preempt;
delay = %taskDelay;
};
%mgr.add(%task);

if(%mgr.selfExecution && !isEventPending(%mgr.tickSch)) {
//Start the schedule again
%firstTask = %mgr.getObject(0);
if(!isEventPending(%mgr.tickSch)) {
%time = %mgr.useDefaultDelay ? %mgr.defaultTaskDelay : %firstTask.delay;
if(%time == -1) {
%mgr.executeNextTask(); //Instant execution
} else {
%mgr.tickSch = %mgr.schedule(%time, executeNextTask);
}
}
}

return %task;
}
function SimpleTaskMgr::addTaskFront(%mgr, %task, %recycleCount, %preempt, %taskDelay) {
%task = %mgr.addTask(%task, %recycleCount, %preempt, %taskDelay); //Slightly less efficient, however less code duplication

%mgr.bringToFront(%task);

return %task;
}
function SimpleTaskMgr::clearTasks(%mgr) {
//Delete all tasks
while(%mgr.getCount() > 0) {
%mgr.getObject(0).delete();
}
}

function SimpleTaskMgr::executeNextTask(%mgr) {
if(%mgr.getCount() <= 0)
return "";

%task = %mgr.getObject(0);
%result = %task.execute();

//If the LOCK# token is in the task, dont store the return value for current task
if(strPos(%task.task, "LOCK#") == -1)
%mgr.lastReturnVal = %result;

if(%task.recycleCount == -1 || %task.recycleCount-- > 0) {
if(%task.preempt) {
//Dont push to back, leave at front
} else {
%mgr.pushToBack(%task);
}
} else {
%mgr.pushToBack(%task); //This is to make sure the set keeps its order
%task.delete();
}

if(%mgr.selfExecution && %mgr.getCount() > 0) {
//Start the schedule for the next execution
%task = %mgr.getObject(0);

if(!isEventPending(%mgr.tickSch)) {
%time = %mgr.useDefaultDelay ? %mgr.defaultTaskDelay : %task.delay;
if(%time == -1) {
%mgr.executeNextTask(); //Instant execution
} else {
%mgr.tickSch = %mgr.schedule(%time, executeNextTask);
}
}
}

return %result;
}


function EGTask::execute(%task) {
%mgr = %task.getGroup();

//LOCK# is handled in SimpleTaskMgr::executeNextTask
%task.task = strReplace(%task.task, "LASTRET#", %task.getGroup() @ ".lastReturnVal;"); //Replace with last return value
%task.task = strReplace(%task.task, "TASKMGR#", %task.getGroup()); //Replace with %mgr
%task.task = strReplace(%task.task, "TASK#", %task.getID()); //Replace with task.getID();

%task.task = strReplace(%task.task, "%this.", %mgr.getID() @ "."); //Allows for "func(%this.val)"

switch$(%task.task) {
case "TERMINATE#": //Delete mgr
%mgr.delete();
return "";
case "NULL#": //Empty task, used for delays
return "";
default:
//Need to use eval (unfortunately) to keep to documentation
if(%mgr.useTarget && strPos(%task.task, "STMT#") == -1) {
if(isObject(%target = %mgr.target)) {
%result = eval(%mgr.target @ "." @ %task.task);
//echo("eval(\"" @ %mgr.target @ "." @ %task.task @ "\");");
}
} else {
//Execute as a stand alone function, not a method
%result = eval(strReplace(%task.task, "STMT#", ""));
//echo("eval(\"" @ strReplace(%task.task, "STMT#", "") @ "\");");
}

return %result;
}

}

function EGTask::setTaskDelay(%task, %delay) {
%task.delay = %delay;
}

112
Modification Help / Re: Hat Pack 3
« on: May 26, 2015, 02:46:11 PM »
Yeah, sorry. I've neglected hatmod for some time, and I've changed my coding standards a lot, so I want to rewrite it entirely from the ground up, which is a lot of work, which means I have less motivation for it. Ill try push for an update sometime, but no promises.

113
Add-Ons / Re: [Event] Fake Wand Brick
« on: May 26, 2015, 05:54:16 AM »
Perhaps add a bool, which when checked will only affect up Bricks?

114
To answer the why:
1. The client isn't saved with the brick, only the BL_ID.
2. 90% of the time the client doesn't exist when loading the brick, they could join later, or not at all.

You should never need to use .client unless you are doing things in onPlant or other functions where there already has to be a client. Otherwise, you should be using the brickgroup for this sort of thing. I mean that generically, not necessarily directed at you, TheBlackParrot

115
I'm not entirely sure what you're asking either, however I have a resource of some advanced vector math, including rotating, that you might find useful, here.

116
Modification Help / Re: Boodals' Untitled D&D-like RPG
« on: May 15, 2015, 11:15:48 AM »
Some new progress on the inventory GUIs. Still got a lot to rewrite with them, but I made them a lot easier to manage multiple inventories.






Much higher framerate MP4 version.


Do the GUIs take up too much screen space? Or are they okay?

117
I have very high standards for all the code I write. I will never do anything like assuming that %client.player exists, as it can cause console spam, and I always try to be fairly efficient, especially in functions that are called often.

I usually end up rewriting a lot of what I code at some point, though not so much now I have a set style and standard I follow. But rewriting code means that you will know of any difficulties you could run into, and you know how to avoid them, and you know how to do it efficiently.

I find I'm very good at thinking of bugs that could occur before even writing any code, which is great because I can then plan systems around bugs which I know I would otherwise run into, which saves me having to make inefficient and dirty patches.

While testing code as you go is good to do, I often find that I cant practically test anything until a good amount of the system is coded. To help avoid bugs when doing this, read through everything at some point, like every single statement. Make sure its all good. I've written files 2000 lines long and had them working without any tests (well, a few typos here and there, but nothing major). Definitely helps being able to work out all the bugs you'll get.

Testing things with friends is a great way to both motivate you and test things, and they'll often give you great ideas or help you design something new.

118
Modification Help / Re: Multi-line shapeName of sorts?
« on: May 04, 2015, 09:53:21 PM »
Also is there a way to offset the shape name a bit or create my own mount point on a player? There aren't really enough mount points for the shapes to line up nicely.

Perhaps scaling the player?

119
Modification Help / Re: I want to make my snipers more "responsive"
« on: May 04, 2015, 10:13:22 AM »
Post the scoping code.

120
Modification Help / Re: Brick Name Box : Child GUI Objects
« on: May 04, 2015, 03:02:48 AM »
You realize you're not passing findSubGUI any parameters, right?

Take a look in tree();

Pages: 1 ... 3 4 5 6 7 [8] 9 10 11 12 13 ... 66