PDA

View Full Version : Mys 1.3.4 Health and mood system + progress bars


Dinocanid
11-07-2016, 06:38 PM
-What we will do-
Create a health and mood system to make pets less static. Once finished, this can easily be added on to to create things like hunger, thirst, etc. After this initial post, you can read the post afterwards if you wish to include any addons, such as pets dying when health reaches 0.

-Step 0-
First we need to go to phpMyAdmin and add a new column in the owned_adoptables table:
Name: health
Type: int
Length/Values: 11
Default: As defined: 100
Not null
Afterwards, create another column with the same info, but name it mood.

-Step 1-
Now go to class_ownedadoptable and add these lines with all the other public and protected stuff:
public $health;
public $mood;

Now, with the other functions, add these lines:
public function getHealth(){
return $this->health;
}
public function getMood(){
return $this->mood;
}

public function setHealth($health, $assignMode = ""){
if($assignMode == Model::UPDATE) $this->save("health", $health);
$this->health = $health;
}
public function setMood($mood, $assignMode = ""){
if($assignMode == Model::UPDATE) $this->save("mood", $mood);
$this->mood = $mood;
}

-Step 2-
Here comes the fun part: Progress Bars! Percents and values can get so boring sometimes, so we're going to use progress bars.

Go to the css folder (located in the root folder, not your template css) and create a new file called "progress.css" Inside, paste this:
progress[value] {color:red} /* IE10 */
progress::-webkit-progress-bar-value {background:red}
progress::-webkit-progress-value {background:red}
progress::-moz-progress-bar {background:red;}
progress {
-webkit-appearance: none;
}
progress[value]::-webkit-progress-bar {
background-color: #eee;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25) inset;
}
progress[value]::-webkit-progress-value {
border-radius: 5px;
}

This is what makes the progress bar look nice. You can change the background and background colors to whatever you want. (For more information on styling progress bars, just google "HTML5 progress bar styling")

In order to see your new progress bar's style, you have to add this to your header.tpl:
{$header->loadStyle("{$home}{$css}/progress.css")}

Now that we have the css in place, we want to display the progress bars. For now, we'll put it on the manage page of your adoptable. (You can put it elsewhere if you want, just follow the instructions)

Go to myadoptsview.php and add these under "public function manage":
$health = $adopt->getHealth();
$mood = $adopt->getMood();
$addHealth = $adopt->getHealth() + 10;
$addMood = $adopt->getMood() + 10;
$subtractHealth = $adopt->getHealth() - 10;
$subtractMood = $adopt->getMood() - 10;

Afterwards, use this to display the progress bars:
$document->add(new Comment ("Health: <progress max='100' value='{$health}'></progress> <br></br>Mood: <progress max='100' value='{$mood}'></progress>"));

http://www.clipular.com/c/4745251696934912.png?k=wPlzTEU0b6T4d2eu56Uxm_pNsec
Aren't they spiffy?

-Adding and Removing Mood/Health-
How exactly you want to update the health and mood is up to you (Whether it's toys, medicine, clicks, etc.) But however you do it, you would do this to edit health:
$adopt->setHealth($addHealth, "update");
if ($health > 100){$adopt->setHealth(100, "update");
$document->add(new Comment("<br></br>{$adopt->getName()} has full health!"));
}

and this to edit mood:
$adopt->setMood($addMood, "update");
if ($mood > 100){$adopt->setMood(100, "update");
$document->add(new Comment("<br></br>{$adopt->getName()} has happy already!"));
}
The if statement makes sure that the health and mood are never above 100.

-Decrease needs daily-
Add this to your myadoptsview.php file, inside the manage function:

$today = date("d");
if ($mysidia->user->needschecked != $today) {
$adopt->setMood($subMood, "update");
if ($mood <= 0){$adopt->setHealth($subHealth, "update"); }
}
$mysidia->db->update("users", array("needschecked" => $today), "username = '{$mysidia->user->username}'");

Now go to phpMyAdmin, adopts_users, and make a new column like this:
http://www.clipular.com/c/5935895757979648.png?k=AsvZANyto7k5rMN8FdlOikyV5AM

And you're all set! Please note that the code above is assuming that you already have $subHealth and $subMood already defined. Just in case you don't:
$subMood = $adopt->getMood() - 10;
$subHealth = $adopt->getHealth() - 10;
(change 10 to whatever number you want)
So if the mood drops to 0, then the health begins to drop by 10 every day. The only issue with this code is that the user has to click on the pet and refresh the page/interact with it in some way in order for this to take effect, so pets' needs could be frozen if the user just doesn't click on them, sort of cheating the system. It works alright as a prototype system though, since I couldn't figure out a better way to get it working.

Dinocanid
11-07-2016, 06:39 PM
-Addons-
(Reserved)

Silver_Brick
11-07-2016, 10:25 PM
Good job (Y) i hope other user will found this usefull and i am also using this and its great ^^

Dinocanid
11-07-2016, 10:31 PM
Thanks! ^^
I decided to go ahead and post it since a lot of adoptables sites have some way of interacting with the pet, instead of just clicking and logging out.

Eagle9615
11-09-2016, 01:43 PM
I was literally just thinking of how I was going to add hunger/mood to my site right before I logged on. I'm not a programmer, so thank you for this!

Abronsyth
11-19-2016, 11:36 AM
Awesome! Thank you for sharing! This will blend splendidly with my battle and exploration features :D

Dinocanid
11-26-2016, 11:06 AM
Updated the OP since I forgot the part that allows you to see your progress bar's style; otherwise it will always be a blue rectangle or whatever the default look is for your browser.

parayna
12-19-2016, 04:10 PM
I have a little question :wiii: Does the mood/health automatically drop? I mean, I'm thinking of not having health (as I probably don't want to include battling... and can't really see much point of having it) but would like mood to drop a little either every day, or every hour/whenever. This way using items that increase mood (toys, etc) can increase it and be a good way of interacting with pets. And as I was typing this I thought it might be interesting to add hunger and thirst and if they both reach 0 it starts taking from health until that gets to 0, etc. (Then perhaps the pet dies, or 'runs away' for a more 'friendly' solution)

Also, a cool addon idea using the held items and pet companions mod could be that you set specific properties they can do. Perhaps holding a certain item, or having a certain companion can keep mood up (it decreases slower), perhaps health takes longer to drop, or heals your pet when they get hurt, or maybe they 'play' with the item once a day and mood increases. Maybe even 'trick' items that do the opposite and hurt your pet/decrease mood (great for Halloween, etc!)

Thank you ^_^

Dinocanid
12-19-2016, 07:47 PM
I'm working on finding a way to make it drop, but so far I've found nothing that works. Some people suggest cronjobs, which would be ideal for this since it would only run once every 24 hours, but I've yet to find any sort of guide as to how to set it up with mysidia script. Right now I'm testing this line I added:

$today = date(d);

if ($mysidia->user->lastday != $today) {
$adopt->setMood($subMood, "update");
}
$mysidia->db->update("users", array("lastday" => $today), "username = '{$mysidia->user->username}'");

Supposedly it could make the mood drop every day when you visit your pet's profile, but it's only been one day so I'm going to have to probably wait another to see if it's actually working.

I already mostly have a part done that makes a pet die when health reaches 0, but it also deletes the pet from the system so I have to do some pretty careful testing. I'm working on a less destructive alternative where the pet "dies" and you have a few days to revive them.

That sounds like a cool idea for an addon! Once I can actually get the bars to go down then I'll see about working on it.

Hall of Famer
12-19-2016, 07:55 PM
Well the issue with cronjobs is that you cannot make them easily without going to cpanel and doing something newbie unfriendly. For advanced users its the way to go, but for a Mod/Plugin doing cronjobs like this will confuse many people. A rule of thumb when making a Mod/Plugin is not to make the installation/modification process over-complicated.

Alternatively, you can set up something called scheduled tasks, or pseudo-cronjobs. All you need is to insert a script that runs whenever someone visits your site, it will check for scheduled tasks and will execute any tasks that are ready to run(or overdue). In an active site it will emulate real cronjobs very well, on an inactive or dev/demo site it may not work as expected though. Mysidia Adoptables v1.4.0 will introduce official scheduled tasks system, I am sure it will help many users who want time-based actions/events.

Dinocanid
12-19-2016, 08:24 PM
How would I do scheduled tasks? I don't know how to make a script run whenever someone just visits the site, unless it goes in index.php or something.

Hall of Famer
12-20-2016, 08:24 AM
First of all, you need to create a database table called adopts_tasks(assuming your database prefix is adopts_, change to whatever it is if not). This table should contain some useful data field such as task id, name, description, action to execute, last execution time, next execution time, time interval between each execution, etc.

Second, create a script file for each of your tasks, and find a way to link it to the data field 'action to execute' in your new database table(ie. mooddrop.php). A simple way is to just use include/require and the file being a procedural file. Or even better, write Task classes that will make it easier to inherit some parent properties/variables. Mysidia Adoptables v1.4.0 will use the latter approach, but if you just barely get a hang of programming the former procedural approach may be more feasible.

Next, add some code to index.php file, this way this code always runs whenever someone visits your site, even a search bot. The code will need to pull all the scheduled tasks ready to run from your new database table(current time is greater than or equal to the next execution time), and execute the script file each task links to. After the script is executed, increment the next execution time by the wait time, and update your database table so the tasks will not run again until it should.

For instance, if you have a scheduled task linking to file mooddrop.php, its next execution time is today at 8am and wait time is 3 hours. When you visit your site at 9am, it will load the scheduled task from database, execute the script inside mooddrop.php, and update the next execution time from 8am to 11am(3 hours interval). Then the task will not run again until someone visits your site again after 11am.

Now you see, it is a simple trick that will work well given you have an active site with visitors at least once per 3-5 minutes. If you are on a virtual machine/devbox, it will not function properly since you are the sole visitor. In fact, this is exactly how our forum software's scheduled task system works. It uses pseudo-cronjobs, and you dont have to manually set up all cronjobs from cpanel.

Of course, you may face some challenges such as how to write task files/classes, how to compare date, and how to store data values in database. Lemme know if you have any questions, I will try to explain and help you with this.

Dinocanid
12-22-2016, 07:12 PM
Finally on break so I can work on this. Would this be the correct setup for the table?
http://www.clipular.com/c/6039837629218816.png?k=QkFt7XqsoNZg0RzoNyxYyla8rhI
This is also what I have so far for my lowermood.php:
<?php

use Resource\Native\String;
use Resource\Collection\LinkedList;
class LowermoodController extends AppController{

public function index(){
$mysidia = Registry::get("mysidia");
$mysidia->db->insert("Table", array("Column" => $somevalue, "Column" => 'somevalue')); //not yet used
$lower = $mysidia->db->select("owned_adoptables", array("mood"))->fetchColumn();
$lower - 10;
}
}
?>

Silver_Brick
12-25-2016, 07:09 AM
While i was trying it i got error
Fatal error: Uncaught exception 'Exception' with message 'Database error 1054 - Unknown column 'aid' in 'field list'' in /home/dacankey/public_html/classes/class_database.php:213 Stack trace: #0 /home/dacankey/public_html/classes/class_database.php(142): Database->_query('owned_adoptable...', Array, 'select', '1 ORDER BY RAND...') #1 /home/dacankey/public_html/view/indexview.php(10): Database->select('owned_adoptable...', Array, '1 ORDER BY RAND...') #2 /home/dacankey/public_html/classes/class_frontcontroller.php(100): IndexView->index() #3 /home/dacankey/public_html/index.php(74): FrontController->render() #4 /home/dacankey/public_html/index.php(78): IndexController::main() #5 {main} thrown in /home/dacankey/public_html/classes/class_database.php on line 213

Dinocanid
12-25-2016, 07:21 AM
What does your code look like?

Silver_Brick
12-25-2016, 08:46 AM
which code

Dinocanid
12-25-2016, 09:12 AM
The one that's giving you the error.

Silver_Brick
12-25-2016, 11:11 AM
Can you show me your owned adopt table phpmyadmin screenshot of structure

Dinocanid
12-25-2016, 11:23 AM
http://www.clipular.com/c/5091632934551552.png?k=j6cbwI1tOyM4nEQwoQX95S6dYac

Silver_Brick
12-25-2016, 11:41 AM
I think its other problem which hall of fame can solve :( and merry christmas

ffsharriet
01-15-2017, 06:05 PM
Can items be used to increase health or mood?

Dinocanid
01-15-2017, 06:20 PM
It's definitely possible, but I've never attempted it so I don't know the code.

Dinocanid
01-21-2017, 02:17 PM
Still need help with scheduled tasks to make the bars go down, since I'm still lost on what to do.

IntoRain
01-21-2017, 05:03 PM
If your host allows cronjobs, you can just have a page with the tasks you want to perform and set it up through the cpanel ("I want this function from this file to run every day").

All the automatic tasks I've set up are basically like this:


class CronController extends AppController{

public function __construct(){

}

public function index(){

}

public function resetNotifs() {
$mysidia = Registry::get("mysidia");
$mysidia->db->delete("notifications", "Isread = '1'");
}

public function resetClicks() {
$mysidia = Registry::get("mysidia");
$now = new DateTime();
$mysidia->db->delete("vote_voters", "date != '{$now->format('Y-m-d')}'");
}

public function resetBiomes() {
$mysidia = Registry::get("mysidia");
$mysidia->db->delete("generatedadoptables", "1");
}

}


But this depends on if your host allows cronjobs.

To do it like HoF is saying, you can create a class file for each task you want. For example ResetClicksTask, LowerMoodTask, ... (which can extend a class Task, if you want inheritance)
Each task class has a function like executeTask() that does what you want. In this case it would be like


class ResetClicksTask extends Model{ //or extends Task

public function __construct(){
}

public function executeTask() {
$mysidia = Registry::get("mysidia");
$now = new DateTime();
$mysidia->db->delete("vote_voters", "date != '{$now->format('Y-m-d')}'");
}

}


Then from the index.php file, you can create a function that checks if any task from the database can run, like


$mysidia = Registry::get("mysidia");
$tasks = $mysidia->db->select("tasks", array("id", "name", "executiontime", "waittime"), "...");

while($task = $tasks->fetchObject()) {
if($currenttime >= $task->executiontime) {
$taskName = $task->name . "Task"; //so it looks like ResetClicksTask
$taskToRun = new $taskName();
$taskToRun->executeTask();//run the execute function
//update the next exe time
$newexetime = $task->executiontime + $task->waittime;
$mysidia->db->update("tasks", array("executiontime" => $newexetime), "id = '{$task->id}'");
}
}



So when anyone visits the index, the function calls all the tasks that need to run.

Dinocanid
01-21-2017, 05:10 PM
Thank you! I'll have to try it out right now. I'm using mysidiahost, so it allows cronjobs.

Dinocanid
01-21-2017, 05:57 PM
Okay, so this is what I have in cron.php within the root folder:
class CronController extends AppController{

public function __construct(){

}

public function index(){

}

public function lowerMood() {
$mysidia = Registry::get("mysidia");
$mysidia->db->update("owned_adoptables", array("mood" => -10));
}

public function lowerHealth() {
$mysidia = Registry::get("mysidia");
$mysidia->db->update("owned_adoptables", array("health" => -10));
}

}

And this is what my cronjob command is:
php -f /home/adopttes/public_html/cron.php
I'm not sure if my command or setup is correct though, since it doesn't work.

Dinocanid
04-02-2017, 03:50 PM
I added a section for having the needs to go down every day.

Dinocanid
04-15-2017, 09:43 AM
As a better alternative to my method above, would it be possible to have something like mySQL events (https://www.sitepoint.com/working-with-mysql-events/)? They're said to be able to be an alternative to cronjobs and I have seen options for this in phpMyAdmin, but I've never touched them. I'll try it and see how it works out.

EDIT: Nevermind, you would need super privileges in mySQL to make schedules (basically add permission), which I can't find a way to do.

KatFennec
04-28-2017, 04:16 AM
Just a heads up, if you haven't already done it for another mod et cetera, you'll need to define $adopt in public function manage. Copying it from the function above it seems to be enough.

KatFennec
05-02-2017, 11:54 PM
I can't seem to get the provided method for changing the health to work. It's all set in class_ownedadoptables, although I'm trying to do this outside the manage page.
EDIT: Never mind. I dug through my files and it turned out to be a typo in what I was using to track health.

KatFennec
05-03-2017, 04:47 AM
Can items be used to increase health or mood?

OK, so I'm trying to get this to work, and I would REALLY APPRECIATE if anyone in here could share whatever magic trick it takes to use an item to restore health. All I get is a white screen, every time.

Abronsyth
05-03-2017, 09:37 AM
Ok, I made my own health system so I cannot garauntee that this will work, but here is my item function for health increasing items:
function items_health($item, $adopt){
$mysidia = Registry::get("mysidia");
$health = $mysidia->db->select("owned_adoptables", array("health"), "aid ='{$adopt->aid}'")->fetchObject();
$addHealth = $adopt->health + $item->value;
//Check if the adoptable's health is already at maximum.
if($adopt->health >= 100){
$note = "Your pet is already fully healed! The {$item->itemname} was not used.";
}
//Not at maximum, but don't go overboard!
elseif($addHealth > 100){
$mysidia->db->update("owned_adoptables", array("health" => 100), "aid ='{$adopt->aid}' and owner='{$item->owner}'");
$note = "The {$item->itemname} fully healed your pet!";
$delitem = $item->remove();
}
//Not at maximum, won't go overboard. Proceed.
else{
$mysidia->db->update("owned_adoptables", array("health" => $addHealth), "aid ='{$adopt->aid}' and owner='{$item->owner}'");
$note = "The {$item->itemname} raised your pet's health by {$item->value}! Their health is now at {$addHealth}.";
$delitem = $item->remove();
}
return $note;
}

(also need to edit classes/class_privateitem, and add the function in the database)

kristhasirah
05-16-2017, 11:29 AM
just want to point out that the progress bar dont work in all the browsers, specially old ones, to "fix" this you need to create a div like progress bar :
https://css-tricks.com/html5-progress-element/ <-- there you will find the "fix" for that =)
in short you just need to add the css codes to your style.css and call them with the div:

<progress max='100' value='{$health}'>
<div class="progress-bar">
<span style='width: 80%;'>Progress: 80%</span>
</div>
</progress>
just replace the 80% with the {$health} or the status you created and you need to add max-width: 100px(or the max value of the status); to the .progress-bar > span {

you might need to remove 1 or 2px from the max-width... sometimes the filled bar gets out of the container by that.

Missy Master
07-19-2020, 10:05 PM
Epic Mod.

Thanks to all who worked so hard on this. I have it installed, so far so good, will make goodies to bring mood and health up tonight or tomorrow!