/* /lib/player.c
* from the Dead Souls LPC Library
* the player object
* created by Descartes of Borg 950321
* Version: @(#) player.c 1.26@(#)
* Last Modified: 97/01/03
*/
#include <lib.h>
#include <rooms.h>
#include <damage_types.h>
#include <message_class.h>
#include <daemons.h>
#include <config.h>
#include <vision.h>
#include <position.h>
#include "include/player.h"
inherit LIB_INTERACTIVE;
inherit LIB_LIVING;
private string *Titles;
string *Muffed = ({});
private class quest *Quests;
private mapping *Deaths;
private int TrainingPoints, TitleLength;
/* ***************** /lib/player.c driver applies ***************** */
static void create() {
interactive::create();
living::create();
Titles = ({});
TitleLength = 1;
Quests = ({});
}
static void heart_beat() {
if(!interactive(this_object())) {
set_heart_beat(0);
return;
}
interactive::heart_beat();
if( IDLE_TIMEOUT && query_idle(this_object()) >= IDLE_TIMEOUT && !creatorp(this_object()) && !present("testchar badge",this_object()) ) {
cmdQuit();
return;
}
living::heart_beat();
}
static void net_dead() {
interactive::net_dead();
set_heart_beat(0);
}
static int Destruct() {
CHARACTER_D->eventSaveTime();
living::Destruct();
return interactive::Destruct();
}
mixed eventAsk(object who, string what) {
if( what != "convert me" ) return 0;
if( !GetReligion(1) ) return 0;
who->SetProperty("converting", GetReligion(1));
return 1;
}
void eventKillEnemy(object ob) {
living::eventKillEnemy(ob);
STATISTICS_D->eventKill(ob);
}
void eventReconnect() {
interactive::eventReconnect();
living::eventReconnect();
set_heart_beat(GetHeartRate());
}
/************** player.c command functions *************/
varargs int eventShow(object who, string str) {
if( !living::eventShow(who, str) ) return 0;
if( this_player() != this_object() )
eventPrint((string)this_player()->GetName() + " looks you over.");
return 1;
}
/* ***************** /lib/player.c events *************** */
int eventDisplayStatus() {
string str;
int qp, xp, hp, mp, sp, max_hp, max_mp, max_sp;
hp = GetHealthPoints();
max_hp = GetMaxHealthPoints();
mp = GetMagicPoints();
max_mp = GetMaxMagicPoints();
sp = GetStaminaPoints();
max_sp = GetMaxStaminaPoints();
xp = GetExperiencePoints();
qp = GetQuestPoints();
if( percent(hp, max_hp) < 20.0 )
str = "%^YELLOW%^hp: %^RED%^" + hp + "%^RESET%^/" + max_hp;
else str = "%^YELLOW%^hp: %^RESET%^" + hp + "/" + max_hp;
if( percent(mp, max_mp) < 20.0 )
str += " %^BLUE%^mp: %^RED%^" + mp + "%^RESET%^/" + max_mp;
else str += " %^BLUE%^mp: %^RESET%^" + mp + "/" + max_mp;
if( percent(sp, max_sp) < 20.0 )
str += " %^GREEN%^sp: %^RED%^" + sp + "%^RESET%^/" + max_sp;
else str += " %^GREEN%^sp: %^RESET%^" + sp + "/" + max_sp;
str += " %^MAGENTA%^xp: %^RESET%^" + xp;
str += " %^CYAN%^qp: %^RESET%^" + qp;
message("status", str, this_object());
return 1;
}
static void eventDestroyUndead(object agent) {
}
varargs int eventDie(mixed agent) {
int x, expee, subexpee;
string agentname;
if(!agent) agent = previous_object();
if(!agent) agent = this_object();
if(stringp(agent)) agentname = agent;
else agentname = agent->GetName();
if( (x = living::eventDie(agent)) != 1 ) return x;
if(!Deaths || !sizeof(Deaths))
Deaths = ({([ "date" : ctime(time()), "enemy" : agentname ])});
else Deaths += ({ ([ "date" : ctime(time()), "enemy" : agentname ]) });
if( !GetUndead() ) {
eventDestroyUndead(agent);
}
else {
message("my_action", "Consciousness passes from you after one last "
"gasp for air.", this_object());
message("my_action", "You awake, but you find your body feels "
"different, and the world about you is unfamiliar.",
this_object());
if( agent ) {
message("other_action", GetName() + " drops dead by the hand "
"of " + agentname + ".",
environment(this_object()), ({ agent, this_object() }));
message("other_action", "You send " + GetName() + " into the "
"Underworld.", agent);
}
else message("other_action", GetName() + " drops dead.",
environment(), ({ this_object() }) );
NewBody(GetRace());
expee = this_object()->GetExperiencePoints();
subexpee = to_int(expee * 0.25);
eventCompleteHeal(GetMaxHealthPoints()/2);
AddMagicPoints(-(random(GetMagicPoints())));
this_object()->eventMove(ROOM_DEATH);
this_object()->AddExperiencePoints(-subexpee);
this_object()->save_player((string)this_object()->GetKeyName());
this_object()->eventForce("look");
}
flush_messages();
return 1;
}
mixed eventTurn(object who) {
if( !living::eventTurn(who) ) {
return 0;
}
eventDestroyUndead(who);
return 1;
}
void eventRevive() {
string skill;
this_object()->SetDead(0);
this_object()->SetDeathEvents(0);
if( !GetUndead() ) return;
SetUndead(0);
if(this_player()->GetPoison() > 0){
this_player()->AddPoison(0 - this_player()->GetPoison());
}
foreach(skill in GetSkills()) {
int x;
if( !random(4) ) {
continue;
}
if( newbiep(this_object()) ) {
x = 2;
}
else {
x = 10;
}
x = random(x - (2*GetSkillClass(skill)))/2;
if( x > 0 ) {
while( x-- ) {
AddSkillPoints(skill,
-GetMaxSkillPoints(skill,
GetBaseSkillLevel(skill)));
}
}
}
NewBody(GetRace());
eventCompleteHeal(GetMaxHealthPoints());
SetSpecialTarget( ({}) );
AddMagicPoints(-(GetMaxMagicPoints()/2));
AddStaminaPoints(-(GetMaxStaminaPoints()/2));
AddHealthPoints(-(GetMaxHealthPoints()/2));
if(creatorp()) interactive::SetShort("$N the reborn");
}
int eventMove(mixed dest) {
int ret;
object env = environment();
string location;
if(!env) location = ROOM_START;
else if(clonep(env)) location = file_name(env);
else location = base_name(env);
if(location) this_object()->SetProperty("LastLocation", location);
ret = interactive::eventMove(dest);
if( this_object() && environment(this_object())) eventMoveFollowers(environment(this_object()));
return ret;
}
varargs int eventMoveLiving(mixed dest, string omsg, string imsg) {
object *inv;
object prev;
string prevclim, newclim;
if( prev = environment() ) {
prevclim = (string)prev->GetClimate();
if( stringp(dest) ) {
if(dest[0] != '/') {
string *arr;
arr = explode(file_name(prev), "/");
dest = "/"+implode(arr[0..sizeof(arr)-2], "/")+"/"+dest;
}
}
if( !eventMove(dest) ) {
eventPrint("You remain where you are.", MSG_SYSTEM);
return 0;
}
inv = filter(all_inventory(prev), (: (!GetInvis($1) && living($1) &&
!GetProperty("stealthy") &&
($1 != this_object())) :));
if( !omsg || omsg == "" || query_verb() == "home" ) {
omsg = GetMessage("telout");
imsg = GetMessage("telin");
}
else if(GetPosition() == POSITION_SITTING ||
GetPosition() == POSITION_LYING ){
omsg = GetName()+" crawls "+omsg+".";
imsg = GetName()+" crawls in.";
}
else if(GetPosition() == POSITION_FLYING ){
omsg = GetName()+" flies "+omsg+".";
imsg = GetName()+" flies in.";
}
else {
omsg = GetMessage("leave", omsg);
imsg = GetMessage("come", imsg);
}
inv->eventPrint(omsg, MSG_ENV);
}
else if( !eventMove(dest) ) {
eventPrint("You remain where you are.", MSG_SYSTEM);
return 0;
}
inv = filter(all_inventory(environment()),
(: (!GetInvis($1) && !GetProperty("stealthy") &&
living($1) && ($1 != this_object())) :));
inv->eventPrint(imsg, MSG_ENV);
if(GetInvis()) {
if(!creatorp(this_object())) AddStaminaPoints(-(15-(GetSkillLevel("stealth")/10)));
AddSkillPoints("stealth", 30 + GetSkillLevel("stealth")*2);
eventPrint("%^RED%^You move along quietly....%^RESET%^\n");
}
if(GetProperty("stealthy")) {
if(!creatorp(this_object())) AddStaminaPoints(-3 - random(3));
AddSkillPoints("stealth", 10 + GetSkillLevel("stealth")*2);
}
eventDescribeEnvironment(GetBriefMode());
newclim = (string)environment()->GetClimate();
if( !GetUndead() ) switch( newclim ) {
case "arid":
if(!creatorp(this_object())) AddStaminaPoints(-0.3);
break;
case "tropical":
if(!creatorp(this_object())) AddStaminaPoints(-0.3);
break;
case "sub-tropical":
if(!creatorp(this_object())) AddStaminaPoints(-0.2);
break;
case "sub-arctic":
if(!creatorp(this_object())) AddStaminaPoints(-0.2);
break;
case "arctic":
if(!creatorp(this_object())) AddStaminaPoints(-0.3);
break;
default:
if(!creatorp(this_object())) AddStaminaPoints(-0.1);
break;
}
if( prevclim != newclim && prevclim != "indoors" && newclim != "indoors" ){
switch(prevclim) {
case "arid":
if( newclim == "tropical" || newclim == "sub-tropical" )
message("environment", "The air is much more humid.",
this_object());
else message("environment", "The air is getting a bit cooler.",
this_object());
break;
case "tropical":
if( newclim != "arid" )
message("environment", "The air is not quite as humid.",
this_object());
else message("environment", "The air has become suddenly dry.",
this_object());
break;
case "sub-tropical":
if( newclim == "arid" )
message("environment", "The air has become suddenly dry.",
this_object());
else if( newclim == "tropical" )
message("environment","The air has gotten a bit more humid.",
this_object());
else message("environment", "The air is not quite as humid.",
this_object());
break;
case "temperate":
if( newclim == "arid" )
message("environment", "The air is a bit drier and warmer.",
this_object());
else if( newclim == "tropical" )
message("environment", "The air is much more humid.",
this_object());
else if( newclim == "sub-tropical" )
message("environment", "The air is a bit more humid.",
this_object());
else message("environment", "The air is a bit colder now.",
this_object());
break;
case "sub-arctic":
if( newclim == "arid" || newclim == "tropical" ||
newclim == "sub-tropical" )
message("environment", "It has suddenly grown very hot.",
this_object());
else if( newclim == "arctic" )
message("environment", "It is a bit cooler than before.",
this_object());
else message("environment", "It is not quite as cold as "
"before.", this_object());
break;
case "arctic":
if( newclim == "sub-arctic" )
message("environment", "It is not quite as cold now.",
this_object());
else message("environment", "It is suddenly much warmer than "
"before.", this_object());
}
}
eventMoveFollowers(environment(this_object()));
return 1;
}
int eventReceiveObject(object foo) {
object ob;
ob = previous_object();
if( !ob || !interactive::eventReceiveObject() ) return 0;
AddCarriedMass((int)ob->GetMass());
if(environment()) environment()->AddCarriedMass((int)ob->GetMass());
return 1;
}
int eventReleaseObject(object foo) {
object ob;
ob = previous_object();
if( !ob || !interactive::eventReleaseObject() ) return 0;
if( ob->GetMass() ){
AddCarriedMass( -(ob->GetMass()) );
if(environment()) environment()->AddCarriedMass(-(ob->GetMass()));
}
return 1;
}
void eventLoadObject(mixed *value, int recurse) { }
static mixed eventUse(object used, string cmd) {
object old_agent;
mixed tmp;
string mess = "";
mess += "------\n";
mess += timestamp()+":\n";
mess += "/lib/player.c: eventUse() hit.\n";
mess += "stack: "+get_stack()+"\n";
mess += "previous: "+identify(previous_object(-1))+"\n";
mess += "------\n";
log_file("player_errors",mess);
return 0;
old_agent = this_agent(used);
tmp = parse_sentence(cmd);
this_agent(old_agent);
message("info", tmp, this_object());
if( stringp(tmp) ) message("error", tmp, this_object());
else return tmp;
}
/* ***************** /lib/player.c modal functions ***************** */
int CanReceive(object ob) { return CanCarry((int)ob->GetMass()); }
mixed CanUse() { return 1; }
/* ***************** /lib/player.c local functions ***************** */
int Setup() {
string classes;
if( !interactive::Setup() ) return 0;
if( !GetClass() ) SetClass("explorer");
if( GetClass() ) {
foreach(classes in (string array)CLASSES_D->GetClasses())
if( ClassMember(classes) && classes != GetClass() )
AddChannel(classes);
}
if(sizeof(GetExtraChannels())) AddChannel(GetExtraChannels());
set_heart_beat(GetHeartRate());
if(GetProperty("brand_spanking_new")){
object jeans, shirt, book;
if(ENGLISH_ONLY) this_object()->SetNativeLanguage("English");
PLAYERS_D->AddPlayerInfo(this_object());
foreach(classes in (string array)CLASSES_D->GetClasses())
if( ClassMember(classes) && classes != GetClass() )
AddChannel(classes);
if( avatarp() ) AddChannel(({ "avatar" }));
if( high_mortalp() ) AddChannel( ({ "newbie", "hm" }) );
if( newbiep() ) AddChannel( ({ "newbie" }) );
else {
RemoveChannel( ({ "newbie" }) );
}
AddChannel( ({ "gossip" }) );
if( councilp() ) AddChannel( ({ "council" }) );
AddChannel(GetClass());
jeans = new("/domains/default/armor/jeans");
shirt = new("/domains/default/armor/shirt");
book = new("/domains/default/obj/handbook");
if(jeans) jeans->eventMove(this_object());
if(shirt) shirt->eventMove(this_object());
if(book && !present("handbook",this_object())) book->eventMove(this_object());
else if(book) book->eventMove(ROOM_FURNACE);
if(jeans) this_object()->eventForce("wear jeans");
if(shirt) this_object()->eventForce("wear shirt");
SetProperty("brand_spanking_new",0);
}
if(this_object()->GetTown() == "FirstAdmin"){
object robe, hat, staff, book, book2;
string home;
this_object()->SetTown("World");
robe = new("/domains/default/armor/robe");
hat = new("/domains/default/armor/wizard_hat");
staff = new("/secure/obj/staff");
book = new("/domains/default/obj/guide");
book2 = new("/domains/default/obj/handbook");
if(robe) robe->eventMove(this_object());
if(hat) hat->eventMove(this_object());
if(staff) staff->eventMove(this_object());
if(book) book->eventMove(this_object());
if(book2) book2->eventMove(this_object());
if(robe) this_object()->eventForce("wear robe");
if(hat) this_object()->eventForce("wear hat");
home = "/realms/"+this_player()->GetKeyName()+"/workroom";
if(file_exists(home+".c"))
this_object()->eventMoveLiving(home);
this_object()->AddChannel( ({"admin", "error", "cre", "newbie", "gossip", "ds", "ds_test", "lpuni", "death", "connections","intercre","dchat","inews"}) );
SetShort("First Admin $N");
}
return 1;
}
/* ***************** /lib/player.c data functions ***************** */
int AddCurrency(string type, int amount) {
if( currency_value(amount, type) > 999 )
log_file("currency", GetCapName() + " received "+amount+" "+type+
" "+ctime(time())+"\n"+identify(previous_object(-1))+"\n");
return living::AddCurrency(type, amount);
}
int AddBank(string bank, string type, int amount) {
if( currency_value(amount, type) > 999 )
log_file("bank", GetCapName() + " deposited "+amount+" "+type+
" "+ctime(time())+" into bank: "+bank+"\n" +
identify(previous_object(-1))+"\n");
return living::AddBank(bank, type, amount);
}
string *GetMuffed(){
return Muffed;
}
string *SetMuffed(string *muffed){
if(sizeof(muffed)) Muffed = muffed;
else Muffed = ({});
return Muffed;
}
string *AddMuffed(string muffed){
string tmpstr;
if(!muffed || muffed == "" || !sizeof(muffed)) return Muffed;
if(grepp(muffed,"@")) {
tmpstr = INTERMUD_D->GetMudName(muffed[1..sizeof(muffed)-1]);
}
if(sizeof(tmpstr)) muffed = tmpstr;
muffed = lower_case(muffed);
if(member_array(muffed,Muffed) == -1) Muffed += ({ muffed });
return Muffed;
}
string *RemoveMuffed(string unmuffed){
string tmpstr;
if(!sizeof(unmuffed)) return Muffed;
if(grepp(unmuffed,"@")) {
tmpstr = INTERMUD_D->GetMudName(unmuffed[1..sizeof(unmuffed)-1]);
}
if(sizeof(tmpstr)) unmuffed = tmpstr;
unmuffed = lower_case(unmuffed);
if(member_array(unmuffed,Muffed) != -1) Muffed -= ({ unmuffed });
return Muffed;
}
string *SetTitles(string *titles) {
if( sizeof(distinct_array(titles)) != sizeof(titles) ) return Titles;
Titles = titles;
SetShort("whatever");
}
string *AddTitle(string title) {
if( !stringp(title) ) return Titles;
else if( member_array(title, Titles) != -1 ) return Titles;
else {
Titles = ({ title }) + Titles;
SetShort("whatever");
return Titles;
}
}
string *RemoveTitle(string title) {
if( !stringp(title) ) return Titles;
if( member_array(title, Titles) == -1 ) return Titles;
else {
Titles -= ({ title });
SetShort("whatever");
return Titles;
}
}
string *GetTitles() { return Titles; }
int SetTitleLength(int x) {
if( x > 2 ) x = 2;
return (TitleLength = x);
}
int GetTitleLength() { return TitleLength; }
void AddQuest(string title, string desc) {
class quest tmp;
object * PartyMember;
object ob;
string pname;
if( !title || !desc ) return;
if( (string)GetParty() ) {
pname = (string)GetParty();
PartyMember = "/daemon/party"->GetPartyMembers(pname) - ({ this_player() });;
foreach(ob in PartyMember) {
ob->AddPartyQuest(title,desc);
}
}
tmp = new(class quest);
tmp->Date = time();
tmp->Description = desc;
Quests += ({ tmp });
AddTitle(title);
}
void AddQuestSkillPoints(string skill, int amount) {
object * PartyMember;
object ob;
string pname;
if(!skill || !amount) return;
if( (string)GetParty() ) {
pname = (string)GetParty();
PartyMember = "/daemon/party"->GetPartyMembers(pname);
foreach(ob in PartyMember) {
ob->AddSkillPoints(skill, amount);
}
}
else AddSkillPoints(skill, amount);
}
void AddQuestStatPoints(string stat, int amount) {
object * PartyMember;
object ob;
string pname;
if(!stat || !amount) return;
if( (string)GetParty() ) {
pname = (string)GetParty();
PartyMember = "/daemon/party"->GetPartyMembers(pname);
foreach(ob in PartyMember) {
ob->AddStatPoints(stat, amount);
}
}
else AddStatPoints(stat, amount);
}
void AddQuestCurrency(string type, int amount) {
object * PartyMember;
object ob;
string pname;
if(!type || !amount) return;
if( (string)GetParty() ) {
pname = (string)GetParty();
PartyMember = "/daemon/party"->GetPartyMembers(pname);
foreach(ob in PartyMember) {
ob->AddCurrency(type, amount);
}
}
else AddCurrency(type, amount);
}
void AddPartyQuest(string title, string desc) {
class quest tmp;
if( !title || !desc ) return;
if( member_array(title, Titles) != -1 ) return;
tmp = new(class quest);
tmp->Date = time();
tmp->Description = desc;
Quests += ({ tmp });
AddTitle(title);
}
mixed *GetQuests() {
return map(Quests, (: ({ ((class quest)$1)->Date,
((class quest)$1)->Description }) :));
}
int GetQuest(string str){
foreach(mixed component in GetQuests()){
if(str == component[1]) return 1;
}
return 0;
}
string SetShort(string irrelevant) {
string title, tmp;
int i;
if( high_mortalp() ) title = "High mortal ";
else title = "";
if(title && title != "") title += " $N ";
else title = "$N ";
if( GetUndead() && (tmp = GetUndeadType()) )
return interactive::SetShort(title + "the " + tmp);
if( avatarp() || creatorp() ) {
return interactive::SetShort(irrelevant);
}
if( !(i = sizeof(Titles)) )
return interactive::SetShort(title + "the unaccomplished");
else title += Titles[0];
if( i > 1 && TitleLength > 1 ) title += " and " + Titles[1];
return interactive::SetShort(title);
}
int SetUndead(int x) {
x = living::SetUndead(x);
SetShort("nonsense");
return x;
}
string GetName() {
if(GetInvis()) return "A shadow";
else return interactive::GetName();
}
varargs string GetLong(string str) {
mapping counts;
string item;
string *affects = ({});
str = GetShort() + "\n";
str += interactive::GetLong() + "\n";
str += living::GetLong(nominative(this_object()));
foreach(item in map(all_inventory(),
(: (string)$1->GetAffectLong(this_object()) :))){
if(item && member_array(item,affects) == -1) affects += ({ item });
}
if(sizeof(affects)) str += implode(affects,"\n")+"\n";
if(this_object()->GetAffectLong()) str += this_object()->GetAffectLong();
counts = ([]);
foreach(item in map(
filter(all_inventory(), (: !((int)$1->GetInvis(this_object())) :)),
(: (string)$1->GetEquippedShort() :)))
if( item ) counts[item]++;
if( sizeof(counts) ) str += GetCapName() + " is carrying:\n";
foreach(item in keys(counts))
str += capitalize(consolidate(counts[item], item)) + "\n";
return str;
}
string GetCapName() { return interactive::GetCapName(); }
int ResetLevel() {
int x, y;
x = GetLevel();
if( x != (y = living::ResetLevel()) ) {
string file;
if( x > y ) file = "decline";
else file = "advance";
log_file(file, GetCapName() + " went from level " + x + " to "
"level " + y + " (" + ctime(time()) + ")\n");
if( x < y ) {
eventPrint("%^YELLOW%^You are now a more experienced " +
GetClass() + ".");
TrainingPoints += ( (y-x) * 4 );
}
else TrainingPoints -= ( (x-y) * 4 );
SetShort("whatever");
if( x > 49 && y < 50 ) RemoveChannel("avatar");
if( x > 24 && y < 25 ) RemoveChannel("hm");
}
return y;
}
string SetClass(string str) {
if( GetClass() != living::SetClass(str) ) {
int points = TrainingPoints;
string classes;
ResetLevel();
TrainingPoints = points; /* leave points alone */
AddChannel(GetClass());
foreach(classes in (string array)CLASSES_D->GetClasses())
if( ClassMember(classes) && classes != GetClass() )
AddChannel(classes);
}
return GetClass();
}
varargs mixed GetEffectiveVision(mixed location, int raw_score) {
if( newbiep(this_object()) ) return VISION_CLEAR;
else if(raw_score && location) return living::GetEffectiveVision(location,raw_score);
else if(location) return living::GetEffectiveVision(location);
else return living::GetEffectiveVision();
}
varargs static int AddHealthPoints(int x, string limb, object agent) {
int hp, ret, undead;
hp = GetHealthPoints();
undead = GetUndead();
ret = living::AddHealthPoints(x, limb, agent);
if( hp <= (hp = GetHealthPoints()) || undead != GetUndead() ) return ret;
eventDisplayStatus();
return ret;
}
int GetLanguageLevel(string lang) {
if( newbiep() ) return 100;
else return living::GetLanguageLevel(lang);
}
mapping *GetDeaths() {
if( !Deaths ) return ({});
return copy(Deaths);
}
int AddTrainingPoints(int x) {
log_file("TrainingPoints", GetName() + " received " + x + " training "
"points at " + ctime(time()) + "\ncall chain: " +
sprintf("%O\n", previous_object(-1)) );
return (TrainingPoints += x);
}
int RemoveTrainingPoints(int x) {
return (TrainingPoints -= x);
}
int GetTrainingPoints() { return TrainingPoints; }
varargs int eventTrain(string skill, int points) {
float x = 0;
mapping mp;
if( points < 1 ) points = 1;
if( !(mp = GetSkill(skill)) ) return 0;
if( TrainingPoints < points ) return 0;
while( points-- ) {
int max = GetMaxSkillPoints(skill, mp["level"]);
switch( mp["class"] ) {
case 1: x = 50.0; break;
case 2: x = 40.0; break;
case 3: x = 30.0; break;
case 4: x = 20.0; break;
default: return 0;
}
TrainingPoints--;
AddSkillPoints(skill, to_int( (max * x) / 100 ));
}
return 1;
}