Author Topic: A modified generic race  (Read 11164 times)

Alchemion

  • Guest
A modified generic race
« on: August 31, 2008, 03:15:10 pm »
Hi,

I am trying to implement a generic race into my installed +nb engine and I got a little issue :

I am trying to have a buff with this generic race, so that, when player's attack is equal to the player's defense this result into a racial buff that doubles the attack and defense of the player...


Code: [Select]
<?php

// 26th July 2006
// SaucyWench -at- gmail *dot* com

// Written for servers that do not wish to have races.
// The character will have "Human" set, but it will not be shown
// in the character stats.

// Make sure you disable Cedrik's Transmutation potion in the Inn
// and uninstall all other races before you begin.

// Some areas will still list the race as "human". It is not
// possible to know all the modules and files that display the race.
// Home City defaults to Degolburg. If you have renamed your
// Capital, change the setting in this file to the new name.

// uses some code from racefelyne and racehuman, by Eric Stevens

function racegeneric_getmoduleinfo(){
$info = array(
"name"=>"Race - Generic Human",
"version"=>"1.0",
"author"=>"Shannon Brown",
"category"=>"Theming",
"download"=>"http://gemdust.com/module_download/",
"settings"=>array(
"Generic Race Settings,title",
"minedeathchance"=>"Percent chance for Generic Humans to die in the mine,range,0,100,1|40"
),
);
return $info;
}

function 
racegeneric_install(){
module_addhook("racenames");
module_addhook("raceminedeath");
module_addhook("chooserace");
module_addhook("newday");
return true;
}

function 
racegeneric_uninstall(){
global $session;
$sql "UPDATE  " db_prefix("accounts") . " SET race='" RACE_UNKNOWN "' WHERE race='Human'";
db_query($sql);
if ($session['user']['race'] == 'Human')
$session['user']['race'] = RACE_UNKNOWN;
return true;
}

function 
racegeneric_dohook($hookname,$args){
global $session,$resline;
$city getsetting("villagename"LOCATION_FIELDS);
$race "Human";
switch($hookname){
case "racenames":
$args[$race] = $race;
break;
case "raceminedeath":
if ($session['user']['race'] == $race) {
$args['chance'] = get_module_setting("minedeathchance");
$args['racesave'] = "Fortunately you make it out in time.`n";
$args['schema']="module-racegeneric";
}
break;
case "chooserace":
$session['user']['race']="Human";
redirect("newday.php");
break;
case "newday":
if ($session['user']['race']==$race){
racegeneric_checkcity();
apply_buff("racialbenefit",array(
"name"=>"`#Flawless Energy`0",
"atkmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"defmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"allowinpvp"=>1,
"allowintrain"=>1,
"rounds"=>-1,
"schema"=>"module-racegeneric",
)
);

output("`n`bAlways remember this great secret : balancing your attack and defense strengths will grant you Grace and Godly Powers...`b`n");
}
break;

}
return $args;
}

function 
racegeneric_checkcity(){
global $session;
$race="Human";
$city getsetting("villagename"LOCATION_FIELDS);

if ($session['user']['race']==$race && is_module_active("cities")){
if (get_module_pref("homecity","cities")!=$city){ 
set_module_pref("homecity",$city,"cities");
}
}
return true;
}

function 
racegeneric_run(){
}

?>


I have some code inserted to the newday hook case, but it seems that it affects (doubles) the stats no matter if the attack and defense are equal...

Please, Nightborn, have a glance on the code and point out what should be corrected so that the buff would work only when the two stats are equal ...

Thank you very much.

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #1 on: August 31, 2008, 03:57:15 pm »
Apart from the fact that doubling stats is a BAD idea...

"atkmod" => "(<attack> == <defense> ? 2.0 : 1.0)",


<--note that in +nb the attack and defense are calculated through attributes - the former attack/defense are ONLY bonus stats (like from weapons/training).

you start (now) with 1 atk and 1 defense, and ZERO attack and ZERO defense based on bonuses.

In your case, you will have right from the start double attack and double defense.

you can only put the correct values in there if you

Code: [Select]
require_once("lib/playerfunctions.php");
$atk=get_player_attack();

in your buff (it gets eval()'d), so you need to generate a numeric statement there...
It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Alchemion

  • Guest
Re: A modified generic race
« Reply #2 on: August 31, 2008, 09:48:57 pm »
I have added the code, but i might have done it incorrectly...

Code: [Select]
case "newday":
if ($session['user']['race']==$race){
racegeneric_checkcity();
require_once("lib/playerfunctions.php");
$atk=get_player_attack($user['attack']);
$def=get_player_defense($user['defense']);
if $atk=$def {
apply_buff("racialbenefit",array(
"name"=>"`#Flawless Energy`0",
"atkmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"defmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"allowinpvp"=>1,
"allowintrain"=>1,
"rounds"=>-1,
"schema"=>"module-racegeneric",
)
);
output("`n`bAlways remember this great secret : balancing your attack and defense strengths will grant you Grace and Godly Powers...`b`n");
           }
       }
          break;

I guess the problem is here, at the newday hook... and I don't get it working... maybe is still more from old dp source I have to adapt to fit with +nb ?...

I am getting an error :

Code: [Select]
Parse error: syntax error, unexpected T_VARIABLE, expecting '(' in .../modules/racegeneric.php on line 79
the 79 line is in the racegeneric module the following, stated in the newday case:

Code: [Select]
79 if $atk=$def {
Thank you very much for your help.

Iori

  • Guest
Re: A modified generic race
« Reply #3 on: September 01, 2008, 02:39:23 am »
if ($atk==$def) {

BTW, you're confusing what nightborn said from his previous posts.

I do not believe you can make this possible as a dynamic buff. For this to be dynamic, you will need to place all calculations inside the buff fields (in some form or other). Which I do not think is possible in this case (unless you manually replicate get_player_attack and get_player_defense in the correct syntax for dynamic buffs).
« Last Edit: September 01, 2008, 02:47:55 am by Iori »

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #4 on: September 01, 2008, 08:17:12 am »
Yes, he is.

The calculation has to be *inside*  the buff, which is bad, not only performance wise.

You have to know, a buff is calculated *EVERY SINGLE PAGEHIT* ... which is pretty bad (and subject why I need to re-do that system, too, to be at least cacheable) as the buffs get interpreted on runtime -_-

You need to put that INSIDE the atkmod/defmod field.
and as Iori indicated, it might not be possible (I have not given this further thought)
It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Alchemion

  • Guest
Re: A modified generic race
« Reply #5 on: September 01, 2008, 08:21:06 am »
I got the code scrambled cause I didn't know at first about the modified attack and defense bonuses in nb+ and I "tested" different alternatives :D ...

The corrected code (I think...  at least I tested and gives no errors... :D ) for the buff is now:

Code: [Select]
case "newday":
if ($session['user']['race']==$race){
racegeneric_checkcity();

require_once("lib/playerfunctions.php");
$atk=get_player_attack();
$def=get_player_defense();

if ($atk==$def) {
apply_buff("racialbenefit",array(
"name"=>"`#Flawless Energy`0",
"atkmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"defmod" => "(<attack> == <defense> ? 2.0 : 1.0)",
"allowinpvp"=>1,
"allowintrain"=>1,
"rounds"=>-1,
"schema"=>"module-racegeneric",
)
);

output("`n`bAlways remember this great secret : balancing your attack and defense strengths will grant you Grace and Godly Powers...`b`n");
}
}
break;


"You need to put that INSIDE the atkmod/defmod field." - What did you mean by that, Nightborn ?... you mean the buff does not apply as intended ?... does not apply in battles ?... please enlight here a bit...

Thank you.
« Last Edit: September 01, 2008, 08:27:33 am by Alchemion »

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #6 on: September 01, 2008, 11:53:35 am »
Please re-read my post.

To put it into formulas:

The attack of the user = attack based on stat values + misc. attack bonus (given by weapons, training, "you gain 1 attack point" and what not)

get_player_attack() does exactly that calculation for you.

This is how +nb works.

Dp Edition:

The attack of the user = $session['user']['attack'];

Your buff will be applied if he has the same attack and def stats ON NEWDAY.
Else he gets no buff at all. WITHIN your buff you still check ONLY the "misc. attack bonus" to be equal.

I recommend against checking in a buff each round both full attack/defense values.

You can live with this solution possibly =)
It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Alchemion

  • Guest
Re: A modified generic race
« Reply #7 on: September 01, 2008, 03:23:27 pm »
I have seen the formula in the lib file you sent me to...

That was the idea... with your formula easy changeable stats is very difficult to maintain equality between the resulted attack and defense... so, whenever this "harmony" is maintained, the user is rewarded in my game scenario...

Indeed, you have well remarked that the buff is adjusting only at newday, based only on stats... in fact I would rather apply it instantaneously only in battles and I would rather test the idea at work when ALL attack and defense INCLUDING misc. attack/defense bonus, INCLUDING positive and negative BUFFS would have been checked before a battle... after all these +buffs checked, only then I would apply the extra buff, the "Chi Awakening" aka "Flawless Energy" buff...

How do I include all the misc. atk/def. bonus and buffs (+/-) gathered by the user, till every new battle, in my $atk and $def equality check, and apply the extra Chi buff when new battle occurs, the message about the "Secret" being shown in the battle page, not in the newday page... ?

Thank you very much.
« Last Edit: September 01, 2008, 03:32:13 pm by Alchemion »

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #8 on: September 02, 2008, 06:09:28 am »
Let's say for now: You cannot do that.

And also, the opposite is the truth: the stats give it a lot more flexibility and you CAN calculate easily... also balancing gets easier.

I mean Oo I should know, I run two servers and all things are going well =)
It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Iori

  • Guest
Re: A modified generic race
« Reply #9 on: September 02, 2008, 09:33:59 am »
A workaround is to hook onto the "battle" hook and do all the calculations, then apply a buff there. It is what Dycedarg academy does. Granted, it isn't elegant, but it will do what you need.

As for core development, a feature for buffs to run an optional script reach round would make them much much more flexible, and can replace the current dynamic functionality entirely.

What I have on my game is this:

file lib/battle-buffs.php
function activate_buffs
Quote
   foreach ($session['bufflist'] as $key => $buff) {
      if (!empty($buff['suspended'])) continue;
      if ($buff['schema']) tlschema($buff['schema']);
      if (!empty($buff['buffscript']) && $session['user']['alive']) {
         eval($buff['buffscript']);
      }

The additions are in red. This is NOT idiot-proof, so make sure the people who code stuff that use this knows what they're doing, or errors will be known out.

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #10 on: September 02, 2008, 11:02:53 am »
=) I am against buff calculations (or ANY non used that can be cached) on every page.

Once (2009?) I am done with the battle system, we can talk about the rest.
The companions are hacked in ... there is no other way to describe it =) I have to reduce 4 lines of global vars GOD-KNOWS-WHO touches them. =)

And then bring it into a bright nice OOP way.

It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Iori

  • Guest
Re: A modified generic race
« Reply #11 on: September 02, 2008, 11:35:29 am »
=) I am against buff calculations (or ANY non used that can be cached) on every page.

Once (2009?) I am done with the battle system, we can talk about the rest.
The companions are hacked in ... there is no other way to describe it =) I have to reduce 4 lines of global vars GOD-KNOWS-WHO touches them. =)

And then bring it into a bright nice OOP way.



The calcs above will run once everytime activate_buffs() is called, which is only during battles where the buff actually runs. If no scripts are present, they are just an additional if statement.

Some of the things you can do with it:
- make buffs that are target specific e.g. in multi battles, modifiers that only affect a particular target instead of every target.
- timed buffs e.g. an attack buff that lasts 5 minutes since it is applied.
- buffs that increase/decrease effectiveness every round
- strip a buff based on condition, and can strip itself as well.
- keep track of things on a round by round basis during battle without needing a hook.
- all functionality of the current dynamic buffs system, with less load (they only calc during battles where the buff ticks, and never any other time).
- summon monsters, change stats, summon companions, display pictures, animations, etc, etc. Anything that is possible code-wise is possible with this. The global variables present in activate_buffs() allows you to modify the current buff, the user's bufflist, the current badguy, session, among other things. Any function can be used as long as you include them (cannot do this with dynamic buffs).


It is 3 extra lines of code that do not have any backward compatibility issues at all.

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #12 on: September 02, 2008, 12:30:17 pm »
Okay.

My first line was not directed towards your code.

But the buffs themselves get calculated every pagehit. (for instance, any <attack> in a buff gets preg_replaced every page hit - in the chat, the village square, each shop, whatnot)

 I intend to change that.

As to your modification - hm.

You generate something hazardous - a second level of hook-like functions.
In your case you let a buff do as it pleases at that location... means it breaks the concept of encapsulation completely.

Your changes will most likely not work in 1.2.0 final... because you might not get access to the battle object there. A buff does not need to re-arrange combat as it likes. It has to use standard interfaces.

It's only intended to interfere with combat at specific interfaces - else we could forget about modules and do modifications again.

I'd rather place a hook with heavy load there, as a buff who gets eval()d ... you can never track anything in there - people report errors somewhere and until you find that a BUFF is causing it - well.

Your idea is flexible, I agree, you can do anything.
It's great for a single server with specialized modules.

On the large scope, however, I plan to do it differently.
If there are hooks to ensure interoperability, they should be used.


It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro

Iori

  • Guest
Re: A modified generic race
« Reply #13 on: September 03, 2008, 07:34:45 am »
Of course, security would be an issue, but I see it is no different to other script functions - creature a.i. scripts come to mind. The only difference there is that the eval() happens in a separate function that gets called - an extra step that forces the coder to declare all the globals that they require for the script. Essentially, not a lot is different.

And I tend to disagree that it is similar to modifications... all it does is add flexibility - you do not modify anything in the core each time you want to use it for a different effect. It works well in conjunction with modules - afterall, the buff still needs to be applied from somewhere.

The same can be said of the item system - the scripts that each server has makes their items unique - I am of the opinions that the more varied servers are, the better it is for the whole of lotgd.

Nightborn

  • Administrator
  • Sr. Member
  • *****
  • Posts: 318
  • Karma: +20/-0
    • View Profile
    • Shinobilegends
Re: A modified generic race
« Reply #14 on: September 03, 2008, 03:01:17 pm »
I know they are not different from creatures - except in exactly one point.
Normal forest creatures have their AI script hardcoded in /scripts lying idle, non-changeable except by somebody who can access and change files.

I know that this is also poor, and ai can be applied dynamically (same issues).

So it's my job to make it more sensible ... for instance make access safer.

You have plenty of items with unique eval()d code? Well, I don't, and you have to see that the item system intends to only set variables (that are standardized) and then does standardized actions. You can put anything in - and execute again code globally.

Item creators have bascially SU_MEGAUSER privileges =) great. =)

As said - first all variables that are now global like $session, $badguy and so on need to be replaced with objects where I can do

- logging of access
- restriction of access
- filtering of access
- alterations

It should be fixed, but it won't be easy and it won't be fast. If you want
to help - wonderful. But keep in mind that it will take months of wading
through the ugliest code we have in the tree. If you've got a weak stomach -
stay out. I've been there and it's not a nice place.

   - Al Viro