faethor33

26/02/2007 18:13:19

Hola a todos, os pongo lo que estoy haciendo a ver si alguien sabe que está mal.
Estoy intentando para mi modulo, gestionar los tesoros usando el sistema xp1 (x0_i0_treasure), creo que viene por defecto en el juego con algunas de las ampliaciones. Creo un contenedor base donde pongo los tesoros que quiero que aparezcan en todo el modulo, luego pongo cofres con la misma etiqueta del anterior y hasta ahi perfecto, dentro de los cofres aparece los regalos que yo habia seleccionado.
El problema es cuando intento hacer que esos cofres se regerenen.
Estoy usando este script:

[b:4a89b4fc8f]#include "NW_O2_CONINCLUDE"
#include "x0_i0_treasure"
#include "mo_mdj_tiempo"

void main()
{
object oPC=GetLastOpenedBy();//El ultimo pj que abrió el cofre
object oTarget=OBJECT_SELF;//El cofre

int iHor=GetHourTimeZero();//La hora actual del server (la recoge del script mo_mdj_tiempo)
int iTie=GetLocalInt(oTarget,"tesoro");//REcoge la hora que se habrio por ultima vez el cofre
iTie=iHor-iTie;//Comprobamos que halla pasado el tiempo necesario para generar el tesoro

if(iTie<0)return;//Si no ha pasado el tiempo, paramos el script
iHor=iHor+1;//Si ha pasado el tiempo (en este caso 10h) se lo sumamos a la hora actual. Aqui es donde se regula el tiempo de regeneracion
SetLocalInt(oTarget,"tesoro",iHor);//Guardamos la hora a la que debe volver a crear tesoro este cofre

int iNum=Random(3);//Marcamos un valor aleatorio de tesoros que saldran en el cofre el minimo es 1, el maximo es el numero entre parentesis +1
while(iNum>=0)//Creamos el tesoro
{
GenerateHighTreasure(oPC,oTarget);//Generamos el tesoro en este caso un tesoro pobre
iNum-=1;
}
/* Para generar otro tipo de tesoros se usan estas lineas sustituyendo a la otra:
GenerateMediumTreasure(oPC,oTarget); <--- Para un tesoro medio
GenerateHighTreasure(oPC,oTarget); <--- Para un tesoro alto
GenerateBossTreasure(oPC,oTarget); <--- Para un tesoro unico
*/
}[/b:4a89b4fc8f]

y el que mide el tiempo (mo_mdj_tiempo)=

[b:4a89b4fc8f]int GetHourTimeZero(int iYear = 99999, int iMonth = 99, int iDay = 99, int iHour = 99)
{
if (iYear > 30000)
iYear = GetCalendarYear();
if (iMonth > 12)
iMonth = GetCalendarMonth();
if (iDay > 28)
iDay = GetCalendarDay();
if (iHour > 23)
iHour = GetTimeHour();

int iHourTimeZero = (iYear)*12*28*24 + (iMonth-1)*28*24 + (iDay-1)*24 + iHour;
return iHourTimeZero;
}[/b:4a89b4fc8f]

Pero no funciona, los cofres no se regeneran pasado "x" tiempo. He probado a cambiar la ultima linea: GenerateHighTreasure(oPC,oTarget); por esta otra: CTG_CreateTreasure(TREASURE_TYPE_HIGH, oPC,oTarget); pero tampoco funciona.

Alguna idea de que hago mal?
Gracias!

AlthorDeMalavir

26/02/2007 20:39:42

yo no veo ningun fallo en el script, yo de ti comentaria el GenerateHighTreasure(oPC,oTarget); para que no lo usase y lo sustituiria por un CreateItemOnObject para generar cualquier objeto fijo asi nos aseguramos que efectivamente todo el script funciona y se puede crear el objeto. Por ejemplo podemos utilizar un CreateItemOnObject("nw_wswls001", oTarget); asi creamos una espada cutre.

Entonces el script principal quedaria asi:



[code:1:27d0f24b8a]
#include "NW_O2_CONINCLUDE"
#include "x0_i0_treasure"
#include "mo_mdj_tiempo"

void main()
{
object oPC=GetLastOpenedBy();//El ultimo pj que abrió el cofre
object oTarget=OBJECT_SELF;//El cofre

int iHor=GetHourTimeZero();//La hora actual del server (la recoge del script mo_mdj_tiempo)
int iTie=GetLocalInt(oTarget,"tesoro");//REcoge la hora que se habrio por ultima vez el cofre
iTie=iHor-iTie;//Comprobamos que halla pasado el tiempo necesario para generar el tesoro

if(iTie<0)return;//Si no ha pasado el tiempo, paramos el script
iHor=iHor+1;//Si ha pasado el tiempo (en este caso 10h) se lo sumamos a la hora actual. Aqui es donde se regula el tiempo de regeneracion
SetLocalInt(oTarget,"tesoro",iHor);//Guardamos la hora a la que debe volver a crear tesoro este cofre

int iNum=Random(3);//Marcamos un valor aleatorio de tesoros que saldran en el cofre el minimo es 1, el maximo es el numero entre parentesis +1
while(iNum>=0)//Creamos el tesoro
{
//GenerateHighTreasure(oPC,oTarget); Generamos el tesoro en este caso un tesoro pobre
CreateItemOnObject("nw_wswls001", oTarget);
iNum-=1;
}
/* Para generar otro tipo de tesoros se usan estas lineas sustituyendo a la otra:
GenerateMediumTreasure(oPC,oTarget); <--- Para un tesoro medio
GenerateHighTreasure(oPC,oTarget); <--- Para un tesoro alto
GenerateBossTreasure(oPC,oTarget); <--- Para un tesoro unico
*/
}
[/code:1:27d0f24b8a]

sino aparecen las espadas es que hay algo mal pero yo desde luego no veo el que, si aparecen es la funcion generadora de tesoros.

faethor33

26/02/2007 22:00:51

Al ver tu respuesta Althor me he dado cuenta que me he explicado mal. Ese script si que funciona el problema es que me está regenerando los cofres siguiendo la tabla NW_02_CONINCLUDE, osea usando el sistema de niveles y clases. Y lo que busco es que el cofre se rellene con el sistema X0_i0_treasure(viene con el juego), esto es, un cofre generico para todo el modulo inaccesible para los jugadores, del cual los demás cofres solo van a generar objetos que este contiene. Para eso pongo este script en el onOpen del cofre:(para el caso de un cofre de tesoro alto)

[b:69527941ef]//::///////////////////////////////////////////////////
//:: X0_O2_ANYHIGH.NSS
//:: OnOpened/OnDeath script for a treasure container.
//:: Treasure type: Any, random selection from whatever is in base container
//:: Treasure level: TREASURE_TYPE_HIGH
//::
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 11/21/2002
//::///////////////////////////////////////////////////

#include "x0_i0_treasure"

void main()
{

CTG_CreateTreasure(TREASURE_TYPE_HIGH, GetLastOpener(), OBJECT_SELF);

}[/b:69527941ef]

Este es el que quiero hacer persistente, que se regenere cada "x" tiempo.
Pero no se como hacer que utilice los scripts del anterior post para que pueda rellenarse. He probado a sustituir este por el otro de mi anterior post en el open del objeto, pero me regenera tesoros con el sistemaNW_02_CONINCLUDE.
He pensado que me está haciendo eso porque la instrucción que pone es: GenerateHighTreasure(oPc,oTarget),y debería de compilarlo con CTG_CreateTreasure, pero haciendolo asi, sale solo una vez y no se vuelve a regenerar.
En fin no se si me he explicado mejor o ya definitivamente la he terminado de liar.
Gracias por responder, a ver si ahora puedes ver que falla.

AlthorDeMalavir

28/02/2007 12:33:05

El problema del sistema que has escogido es que la funcion CTG_CreateTreasure solo genera un tesoro por cofre, porque el sistema lo diseñaron asi y ademas no pensaron que podia quererse que se regenerase como es tu caso, y no pusieron nada para habilitar la regeneracion, asi que lo unico que puedes hacer es modificar el sistema creado por los programadores de bioware para que no saque solo un tesoro por cofre, o sea, modificar el script x0_i0_treasure

Yo no tengo puesto el sistema que usas tu, yo me programe uno propio que usa 3 areas con 6 cofres cada una, con objetos organizados por nivel y tipo, bastante mas complicado, asi que no puedo ayudarte mucho con el sistema ese que lleva el juego.

Guardando este script con el nombre x0_i0_treasure para sustituir al antiguo deberia funcionarte. Pero generara un tesoro de los de tu cofre de tesoros siempre que se abra el cofre, habria que hacer unos cambios tambien en el script X0_O2_ANYHIGH del cofre para que esto no sucediese, pruebalo y dime genera el tesoro que quieres al menos.

[code:1:5c295631a6]
//:://////////////////////////////////////////////////
//:: X0_I0_TREASURE

/*
Include library for XP1 treasure generation system.

--------------------------------------------------

MAIN CONCEPT:

The module builder creates some base containers and fills them
with instances of the treasure items that s/he wants to appear
randomly. The actual treasure containers then randomly pick from
the contents of these base containers to generate their own
contents.

--------------------------------------------------

SETUP:

Create four module-wide base containers (for low, medium, high,
and unique treasure items) and place them anywhere in your
module. Make sure that they are in locations inaccessible to the
players, though!

Give these module-wide base containers these tags (or just use the
blueprints):

X0_MOD_TREASURE_LOW - low-level treasure
X0_MOD_TREASURE_MED - medium-level treasure
X0_MOD_TREASURE_HIGH - high-level treasure
X0_MOD_TREASURE_UNIQ - unique treasure items

Fill the instances of these base containers with appropriate treasure
for your module.

For any areas where you want finer control over the treasure,
simply create additional base containers (you don't need all four
-- any one that you skip will fall back to the module-wide version)
and place them in the area. Give them these tags (same just without
the "MOD"):

X0_TREASURE_LOW - low-level treasure
X0_TREASURE_MED - medium-level treasure
X0_TREASURE_HIGH - high-level treasure
X0_TREASURE_UNIQ - unique treasure items

For any treasure container, use one of the following scripts
as BOTH the OnOpen/OnDeath handler:

Any Treasure: x0_o2_any{low,med,high,uniq}
Books (book, scroll): x0_o2_book{low,med,high,uniq}
Potions: x0_o2_potn{low,med,high,uniq}
Armor (armor, shield, helm, boots, etc): x0_o2_arm{low,med,high,uniq}
Weapon: x0_o2_weap{low,med,high,uniq}
Gold: x0_o2_gold{low,med,high,uniq}

Others may also be added.

MONSTER/NPC TREASURE
--------------------
If you would like to have special monster treasure (monster treasure
defaults to low treasure otherwise), you can also add any of these
base chests:

X0_TREASURE_MONSTER_<monster tag> - treasure found on monsters with
the given tag. This will strip off
any trailing digits, so for instance,
NW_KOBOLD1, NW_KOBOLD2, NW_KOBOLD005
would all end up checking the chest
X0_TREASURE_MONSTER_NW_KOBOLD.

X0_TREASURE_MONSTER_<racialtype> - treasure found on monsters of the given
racialtype. Ex:
X0_TREASURE_MONSTER_ELF
X0_TREASURE_MONSTER_UNDEAD
The spelling matches that used in the
RACIALTYPE_* constants.

X0_TREASURE_MONSTER - generic treasure found on all monsters/NPCs
in the module.

To use monster treasure, use the default OnSpawn script nw_c2_default9
or modify the OnSpawn script as follows:

- Replace #include "nw_o2_coninclude" with #include "x0_i0_treasure"
- Replace GenerateNPCTreasure(); with CTG_GenerateNPCTreasure();
- If you prefer to generate monster treasure from the general chests,
you can also add a parameter to CTG_GenerateNPCTreasure(); to
specify whether the treasure generated should be low/medium/high/uniq.
See the comments to that function for details.

--------------------------------------------------

DETAILS:

Each treasure container has a script that looks for the
nearest object with the tag matching the type of
treasure.

When the treasure-generating scripts look for a container,
they will take the nearest container in the local area, then
fall back to the module-wide container. If no container can
be found, they will fall back on the standard random treasure
generation system.

The treasure generation system will randomly select from
1-3 items from whatever items are in the nearest container.
Each item has a 50/50 chance of being replaced by a random
amount of coin based on the standard treasure generation
system.

IMPORTANT NOTE ON PROBABILITY:
Each item in the chest has an equal probability of being
selected. To control the probability of any given item
appearing, simply place multiple copies of it in the container.

Because of the stacking rules, there is a slight modification
to this. Ammunition/throwing weapons will have a probability
equal to the number of stacks in the chest, since the max stack
size is the default stack size. Potions, scrolls, and gems, however,
will be counted individually to determine the probability even if
they are stacked, since their default stack size is 1.

To control the size of the stack that actually gets created, you
should create a blueprint that has the appropriate stack size.
You can adjust the stack size of the instance you stuff into the
base container to whatever you want afterwards; the blueprint's
stack size will control what

There are scripts that will cause only specific types of items
to be selected from the container of the specified level --
eg, only books/scrolls, or only weapons or armor, etc -- useful
for bookcases or for weapon racks, & so on.

The unique treasure chest will only place each item in the
chest once, will never place more than one item, and will
never replace the item with coin.

Advantages of this system:
- Complete control over which items can appear in a
module or in an area.

- Thematically-appropriate treasure can be placed in each
area.

- Easy for module builders to set up.

- Trivial to add new items to the treasure distribution.

- Trivial to adjust probabilities of items appearing.

- Easy to have unique treasure items showing up randomly.

Disadvantages of this system:
- No level-specific treasure generation. This system is thus
NOT appropriate for an area that is intended to scale to
radically-different levels. Rather, it is appropriate for
use where the levels of the characters are roughly known
to the module designer and the treasure can be designed to
match.

- No class-specific treasure generation planned for now.
(However, I may add something to increase probability of
certain items popping up, optionally. TBD.)

For XP1, we feel this is a good tradeoff, but this should
be kept in mind when deciding whether to use this system or
the original treasure generation system in user-made modules.

-- NN

*/
//:://////////////////////////////////////////////////
//:: Copyright (c) 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 11/16/2002
//:://////////////////////////////////////////////////

// For legacy treasure generation
#include "nw_o2_coninclude"

/**********************************************************************
* CONSTANTS
**********************************************************************/

// * this is the percent chance that no treasure will be spawned by a creature dying
const int BK_CHANCE_OF_N0_MONSTERTREASURE = 80;


// Tags for the module-wide containers
string sModContLow = "X0_MOD_TREASURE_LOW";
string sModContMed = "X0_MOD_TREASURE_MED";
string sModContHigh = "X0_MOD_TREASURE_HIGH";
string sModContUniq = "X0_MOD_TREASURE_UNIQ";

// Tags for the area-specific containers
string sContLow = "X0_TREASURE_LOW";
string sContMed = "X0_TREASURE_MED";
string sContHigh = "X0_TREASURE_HIGH";
string sContUniq = "X0_TREASURE_UNIQ";

// Tag for the monster-specific containers
string sContMonster = "X0_TREASURE_MONSTER";

// Gold item ResRef
string sGoldResRef = "NW_IT_GOLD001";

// Varname holding the number of treasure items
string sNumTreasureItemsVarname = "X0_NUM_TREASURE_ITEMS";

// Varname holding the base type of each treasure item
string sBaseTypeVarname = "X0_BASE_TYPE_TREASURE";

// Varname holding a reference to each treasure item
string sTreasureItemVarname = "X0_TREASURE_ITEM";

// Varname indicating that the treasure container has been filled
string sTreasureGeneratedVarname = "X0_TREASURE_HAS_BEEN_GENERATED";


// Major treasure categories

int TREASURE_TYPE_LOW = 1;
int TREASURE_TYPE_MED = 2;
int TREASURE_TYPE_HIGH = 3;
int TREASURE_TYPE_UNIQUE = 4;
int TREASURE_TYPE_MONSTER = 5;


// Special generalized base types.
// Giving these large values to make sure they never
// conflict with the actual base type values -- that
// would cause those base types to be non-specifiable.
int TREASURE_BASE_TYPE_WEAPON = 13000;
int TREASURE_BASE_TYPE_WEAPON_NOAMMO = 13001;
int TREASURE_BASE_TYPE_WEAPON_RANGED = 13002;
int TREASURE_BASE_TYPE_WEAPON_MELEE = 13003;
int TREASURE_BASE_TYPE_ARMOR = 13004;
int TREASURE_BASE_TYPE_CLOTHING = 13005;

// Probability of a single item being generated,
// in percentage
int TREASURE_PROBABILITY_1 = 70;

// Probability of two items being generated,
// in percentage
int TREASURE_PROBABILITY_2 = 20;

// Probability of an item being converted to gold
int TREASURE_GOLD_PROBABILITY = 35;

// Multiplier to use on the value of an item to convert it to gold
float X0_GOLD_MODIFIER = 0.50;

/**********************************************************************
* FUNCTION PROTOTYPES
*
* All functions prefixed with CTG for "container treasure generation".
**********************************************************************/

// Get the number of items to generate
// Returns an integer from 1-3, probabilities
// determined by the values of the constants
// TREASURE_PROBABILITY_1 & _2.
int CTG_GetNumItems();

// Get the number of items in a base container.
int CTG_GetNumItemsInBaseContainer(object oBaseCont);

// Determine whether an item should actually just be gold.
// Returns TRUE or FALSE.
// Probability controlled by constant TREASURE_GOLD_PROBABILITY
int CTG_IsItemGold();

// Find and return the right monster container, if
// available.
object CTG_GetMonsterBaseContainer(object oSource=OBJECT_SELF);

// Locate the base container of the appropriate type closest to
// oSource.
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
object CTG_GetNearestBaseContainer(int nTreasureType, object oSource=OBJECT_SELF);

// Get the module-wide base container of the appropriate type.
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
object CTG_GetModuleBaseContainer(int nTreasureType);

// Get the specified item out of the given base container's inventory
object CTG_GetTreasureItem(object oBaseCont, int nItemNum);

// Test if treasure has been generated in the given object
int CTG_GetIsTreasureGenerated(object oCont);

// Set whether treasure has been generated
void CTG_SetIsTreasureGenerated(object oCont, int bGenerated=TRUE);

// Create random treasure items of the appropriate type
// in the specified container. Will typically be called
// by a script on a treasure container.
//
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
void CTG_CreateTreasure(int nTreasureType, object oAdventurer, object oCont=OBJECT_SELF);

// Starting from the specified item position, return the first
// item that matches one of the three base types.
//
// nBaseType1 may also be passed in as a special custom type,
// which will OVERRIDE any other specified base types:
//
// TREASURE_BASE_TYPE_WEAPON (for any weapon type)
// TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)
// TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)
// TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)
// TREASURE_BASE_TYPE_ARMOR (for armor, shields)
// TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,
// cloaks, helms, gloves)
object CTG_GetSpecificBaseTypeTreasureItem(object oBaseCont, int nItemNum, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);


// Create treasure of the appropriate treasure level and matching one
// of up to three different base types in the specified container.
//
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
//
// Possible values for nBaseType1/2/3: any BASE_ITEM_* constant.
//
// If nBaseType1 is passed in as invalid, NO TYPE CHECKING WILL BE DONE.
//
// nBaseType1 may also be passed in as a special custom type,
// which will OVERRIDE any other specified base types:
//
// TREASURE_BASE_TYPE_WEAPON (for any weapon type)
// TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)
// TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)
// TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)
// TREASURE_BASE_TYPE_ARMOR (for armor, shields)
// TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,
// cloaks, helms, gloves)
//
void CTG_CreateSpecificBaseTypeTreasure(int nTreasureType, object oAdventurer, object oCont, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);

// Create gold treasure in the specified container.
void CTG_CreateGoldTreasure(int nTreasureType, object oAdventurer, object oCont=OBJECT_SELF);

// Create treasure on an NPC.
// This function will typically be called from within the
// NPC's OnSpawn handler.
// Note that this defaults to TREASURE_TYPE_MONSTER, which uses
// the monster-specific treasure chests and falls back to low-
// level treasure if none exist.
void CTG_GenerateNPCTreasure(int nTreasureType=5, object oNPC=OBJECT_SELF);

// Check if the item's base type is of the given base type
int CTG_GetIsBaseType(int nItemBaseType, int nBaseType1=BASE_ITEM_INVALID, int nBaseType2=BASE_ITEM_INVALID, int nBaseType3=BASE_ITEM_INVALID);

// Check if the item's base type is a weapon
int CTG_GetIsWeapon(int nItemBaseType);

// Check if the item's base type is a weapon but not ammunition
int CTG_GetIsWeaponNoammo(int nItemBaseType);

// Check if the item's base type is a ranged weapon
int CTG_GetIsRangedWeapon(int nItemBaseType);

// Check if the item's base type is a melee weapon
int CTG_GetIsMeleeWeapon(int nItemBaseType);

// Check if the item's base type is armor
int CTG_GetIsArmor(int nItemBaseType);

// Check if the item's base type is clothing
int CTG_GetIsClothing(int nItemBaseType);

// Tack on the appropriate racialtype suffix
string CTG_GetRacialtypeChestTag(string sBaseTag, object oSource);

/**********************************************************************
* PRIVATE FUNCTION DEFINITIONS
* These functions are deliberately not prototyped and not intended
* for use outside this library.
**********************************************************************/

// This function deliberately not prototyped. Should not be used
// outside this library.
// Test whether a treasure container has been initialized for
// specific base treasure type use.
int CTG_GetIsContainerInitialized(object oBaseCont)
{
return GetLocalInt(oBaseCont, "X0_CONTAINER_INITIALIZED");
}

// This function deliberately not prototyped. Should not be used
// outside this library.
// Set whether a treasure container has been initialized for
// specific base treasure type use.
void CTG_SetIsContainerInitialized(object oBaseCont, int bInit=TRUE)
{
SetLocalInt(oBaseCont, "X0_CONTAINER_INITIALIZED", bInit);
}

// This function deliberately not prototyped. Should not be used
// outside this library.
// Initialize a treasure container to store the items contained
// inside as local variables on the container.
void CTG_InitContainer(object oBaseCont)
{
// don't do this twice
if (CTG_GetIsContainerInitialized(oBaseCont)) {return;}

// initialize
int nItems = CTG_GetNumItemsInBaseContainer(oBaseCont);

int i;
object oTmp = OBJECT_INVALID;
oTmp = GetFirstItemInInventory(oBaseCont);
for (i=0; i < nItems && GetIsObjectValid(oTmp); i++) {
// Store the item and its base type as local vars on
// the container object itself.
string sIndex = IntToString(i);
string sVar = sBaseTypeVarname + sIndex;
SetLocalInt(oBaseCont, sVar, GetBaseItemType(oTmp));
sVar = sTreasureItemVarname + sIndex;
SetLocalObject(oBaseCont, sVar, oTmp);

oTmp = GetNextItemInInventory(oBaseCont);
}

// mark as initialized
CTG_SetIsContainerInitialized(oBaseCont);
}


/**********************************************************************
* FUNCTION DEFINITIONS
**********************************************************************/

// Get the number of items to generate
// Returns an integer from 1-3, probabilities
// determined by the values of the constants
// TREASURE_PROBABILITY_1 & _2.
int CTG_GetNumItems()
{
int nRoll = d100();

if (nRoll < TREASURE_PROBABILITY_1) {
return 1;
} else if (nRoll < (TREASURE_PROBABILITY_1 + TREASURE_PROBABILITY_2)) {
return 2;
}
return 3;
}


// Get the number of items in a base container
int CTG_GetNumItemsInBaseContainer(object oBaseCont)
{
int nItems = GetLocalInt(oBaseCont, sNumTreasureItemsVarname);
if (nItems != 0) {
return nItems;
}

// Haven't initialized the number of items yet
object oTmp = GetFirstItemInInventory(oBaseCont);
while (GetIsObjectValid(oTmp)) {
nItems++;
oTmp = GetNextItemInInventory(oBaseCont);
}
SetLocalInt(oBaseCont, sNumTreasureItemsVarname, nItems);
return nItems;
}


// Determine whether an item should actually just be gold.
// Returns TRUE or FALSE.
// Probability controlled by constant TREASURE_GOLD_PROBABILITY
int CTG_IsItemGold()
{
int nRoll = d100();
if (nRoll < TREASURE_GOLD_PROBABILITY)
return TRUE;
return FALSE;
}

int GetIsInteger(string sChar)
{
return (sChar == "0"
|| sChar == "1"
|| sChar == "2"
|| sChar == "3"
|| sChar == "4"
|| sChar == "5"
|| sChar == "6"
|| sChar == "7"
|| sChar == "8"
|| sChar == "9");
}

// Find and return the right monster container, if
// available.
object CTG_GetMonsterBaseContainer(object oSource=OBJECT_SELF)
{
object oCont = OBJECT_INVALID;
string sContTag = "";

// For monster treasure, we first check for
// a chest with a tag matching the specific
// monster.
// We strip numbers off the end of the tag first
string sCreatureTag = GetTag(oSource);
while ( GetIsInteger(GetStringRight(sCreatureTag, 1)) ) {
sCreatureTag = GetStringLeft(sCreatureTag,
GetStringLength(sCreatureTag)-1);
}

sContTag = sContMonster + "_" + sCreatureTag;
oCont = GetObjectByTag(sContTag);
if (GetIsObjectValid(oCont)) {
return oCont;
}

// Didn't find that -- check for a chest for the
// appropriate racialtype.
sContTag = CTG_GetRacialtypeChestTag(sContMonster, oSource);
oCont = GetObjectByTag(sContTag);
if (GetIsObjectValid(oCont)) {
return oCont;
}

// Didn't find that -- check for a module-wide
// monster chest
oCont = GetObjectByTag(sContMonster);
return oCont;
}


// Locate the nearest base container of the appropriate type.
// Possible values for nTreasureType:
// TREASURE_TYPE_MONSTER
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
object CTG_GetNearestBaseContainer(int nTreasureType,
object oSource=OBJECT_SELF)
{
object oCont = OBJECT_INVALID;
int nType = nTreasureType;
string sContTag = "";

if (nType == TREASURE_TYPE_MONSTER) {
oCont = CTG_GetMonsterBaseContainer(oSource);
if (GetIsObjectValid(oCont))
return oCont;

// no monster-specific treasure set up
nType = TREASURE_TYPE_LOW;
}

if (nType == TREASURE_TYPE_LOW) {
sContTag = sContLow;
} else if (nType == TREASURE_TYPE_MED) {
sContTag = sContMed;
} else if (nType == TREASURE_TYPE_HIGH) {
sContTag = sContHigh;
} else if (nType == TREASURE_TYPE_UNIQUE) {
sContTag = sContUniq;
} else {
// Invalid treasure type
return oCont;
}

oCont = GetNearestObjectByTag(sContTag);
if (!GetIsObjectValid(oCont)) {
// No area chest -- return the module-wide one
return CTG_GetModuleBaseContainer(nType);
}
return oCont;
}

// Get the module-wide base container of the appropriate type.
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
object CTG_GetModuleBaseContainer(int nTreasureType)
{
object oCont = OBJECT_INVALID;
string sContTag = "";

if (nTreasureType == TREASURE_TYPE_LOW) {
sContTag = sModContLow;
} else if (nTreasureType == TREASURE_TYPE_MED) {
sContTag = sModContMed;
} else if (nTreasureType == TREASURE_TYPE_HIGH) {
sContTag = sModContHigh;
} else if (nTreasureType == TREASURE_TYPE_UNIQUE) {
sContTag = sModContUniq;
} else {
// Invalid treasure type
return oCont;
}

oCont = GetObjectByTag(sContTag);
return oCont;
}


// Generate treasure using default method.
// Not prototyped -- this function should not be used outside
// this library.
void CTG_CreateDefaultTreasure(int nTreasureType, object oAdventurer, object oCont)
{
// generate treasure using default method from nw_o2_coninclude
if (nTreasureType == TREASURE_TYPE_LOW) {
GenerateLowTreasure(oAdventurer, oCont);
} else if (nTreasureType == TREASURE_TYPE_MED) {
GenerateMediumTreasure(oAdventurer, oCont);
} else if (nTreasureType == TREASURE_TYPE_HIGH) {
GenerateHighTreasure(oAdventurer, oCont);
} else if (nTreasureType == TREASURE_TYPE_UNIQUE) {
GenerateBossTreasure(oAdventurer, oCont);
}
}

// Get the specified item out of the given base container's inventory
object CTG_GetTreasureItem(object oBaseCont, int nItemNum)
{
if (!GetIsObjectValid(oBaseCont)) {return OBJECT_INVALID;}

// initialize the container -- this will automatically
// only happen once.
CTG_InitContainer(oBaseCont);

// Refs to the items are stored on the container itself
string sVar = sTreasureItemVarname + IntToString(nItemNum);
return GetLocalObject(oBaseCont, sVar);
}

// Starting from the specified item position, return the first
// item that matches one of the three base types.
// If nBaseType1 is passed in as invalid, NO TYPE CHECKING WILL BE DONE.
// nBaseType1 may also be passed in as a special custom type:
// TREASURE_BASE_TYPE_WEAPON (for any weapon type)
// TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)
// TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)
// TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)
// TREASURE_BASE_TYPE_ARMOR (for armor, shields)
// TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,
// cloaks, helms, gloves)
object CTG_GetSpecificBaseTypeTreasureItem(object oBaseCont,
int nItemNum,
int nBaseType1=BASE_ITEM_INVALID,
int nBaseType2=BASE_ITEM_INVALID,
int nBaseType3=BASE_ITEM_INVALID)
{
if (!GetIsObjectValid(oBaseCont)) {return OBJECT_INVALID;}

// initialize the container -- this will automatically
// only happen once.
CTG_InitContainer(oBaseCont);

int nRollOverNum = CTG_GetNumItemsInBaseContainer(oBaseCont);

// If there are no items in the container, no chance of finding a matching one!
if (nRollOverNum == 0) return OBJECT_INVALID;

int i;
string sVar;
int nItemBaseType;
int nLooped = 0;
for (i=nItemNum; i != nItemNum || !nLooped ; i++) {

// The base type of each item is stored on the container itself
sVar = sBaseTypeVarname + IntToString(i);
nItemBaseType = GetLocalInt(oBaseCont, sVar);

// Check to see if the type matches our desired type.
if (
// Check for a weapon
(nBaseType1 == TREASURE_BASE_TYPE_WEAPON
&&
CTG_GetIsWeapon(nItemBaseType))
||
// non-ammo weapon
(nBaseType1 == TREASURE_BASE_TYPE_WEAPON_NOAMMO
&&
CTG_GetIsWeaponNoammo(nItemBaseType))
||
// ranged weapon
(nBaseType1 == TREASURE_BASE_TYPE_WEAPON_RANGED
&&
CTG_GetIsRangedWeapon(nItemBaseType))
||
// melee weapon
(nBaseType1 == TREASURE_BASE_TYPE_WEAPON_MELEE
&&
CTG_GetIsMeleeWeapon(nItemBaseType))
||
// armor
(nBaseType1 == TREASURE_BASE_TYPE_ARMOR
&&
CTG_GetIsArmor(nItemBaseType))
||
// clothing
(nBaseType1 == TREASURE_BASE_TYPE_CLOTHING
&&
CTG_GetIsClothing(nItemBaseType))
||
// other specific item type
( CTG_GetIsBaseType(nItemBaseType,
nBaseType1,
nBaseType2,
nBaseType3))
) // end of if statement
{
// we found a matching item -- return it
return CTG_GetTreasureItem(oBaseCont, i);
}

// Handle the wrap-around case
if ( (i+1) == nRollOverNum ) {
// set i back to 0
i = -1;
nLooped = 1;
}
}

// No matching item was found -- return null
return OBJECT_INVALID;
}

// Test if treasure has been generated in the given object
int CTG_GetIsTreasureGenerated(object oCont)
{
return GetLocalInt(oCont, sTreasureGeneratedVarname);
}

// Set whether treasure has been generated
void CTG_SetIsTreasureGenerated(object oCont, int bGenerated=TRUE)
{
SetLocalInt(oCont, sTreasureGeneratedVarname, bGenerated);
}

// Create random treasure items of the appropriate type
// in the specified container. Should be called
// by a script on a treasure container.
//
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
void CTG_CreateTreasure(int nTreasureType,
object oAdventurer,
object oCont=OBJECT_SELF)
{
// To avoid code duplication, this actually just uses the specific
// version and passes an invalid item type
CTG_CreateSpecificBaseTypeTreasure(nTreasureType, oAdventurer, oCont);
}



// Create treasure of the appropriate treasure level and matching one
// of up to three different base types in the specified container.
//
// Possible values for nTreasureType:
// TREASURE_TYPE_LOW
// TREASURE_TYPE_MED
// TREASURE_TYPE_HIGH
// TREASURE_TYPE_UNIQUE
//
// Possible values for nBaseType1/2/3: any BASE_ITEM_* constant.
// Can also use these special values:
// TREASURE_BASE_TYPE_WEAPON (for any weapon type)
// TREASURE_BASE_TYPE_WEAPON_NOAMMO (for any weapon but ammunition)
// TREASURE_BASE_TYPE_WEAPON_RANGED (for any ranged weapon)
// TREASURE_BASE_TYPE_WEAPON_MELEE (for any melee weapon)
// TREASURE_BASE_TYPE_ARMOR (for armor, shields)
// TREASURE_BASE_TYPE_CLOTHING (for belts, boots, bracers,
// cloaks, helms, gloves)
//
void CTG_CreateSpecificBaseTypeTreasure(int nTreasureType,
object oAdventurer,
object oCont,
int nBaseType1=BASE_ITEM_INVALID,
int nBaseType2=BASE_ITEM_INVALID,
int nBaseType3=BASE_ITEM_INVALID)
{
// Prevent duplicate treasure generation
//if (CTG_GetIsTreasureGenerated(oCont)) {return;}
CTG_SetIsTreasureGenerated(oCont);

// Locate the base container
object oBaseCont = CTG_GetNearestBaseContainer(nTreasureType,
oCont);

// Make sure we have a valid base container
if (!GetIsObjectValid(oBaseCont)) {
// if not, generate treasure using default method
if (nBaseType1 == BASE_ITEM_BOOK
|| nBaseType1 == BASE_ITEM_SPELLSCROLL)
{
// Make book treasure
GenerateBookTreasure(oAdventurer, oCont);
} else {
// Generate default treasure
CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);
}
return;
}

// Get the number of available items
int nItemsInBaseCont = CTG_GetNumItemsInBaseContainer(oBaseCont);

// Special case: unique treasure items
if (nTreasureType == TREASURE_TYPE_UNIQUE) {
// only give one item and only give it once
int nRandom = Random(nItemsInBaseCont);

object oItem;
if (nBaseType1 == BASE_ITEM_INVALID) {
// we're not checking base types
oItem = CTG_GetTreasureItem(oBaseCont, nRandom);
} else {
oItem = CTG_GetSpecificBaseTypeTreasureItem(oBaseCont,
nRandom,
nBaseType1,
nBaseType2,
nBaseType3);
}

if (!GetIsObjectValid(oItem)) {
CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);
} else {

// Copy the item
// CreateItemOnObject(GetResRef(oItem), oCont);
// * do an actual copy BK Feb 2003. Less chance of resref errors
CopyObject(oItem, GetLocation(oItem), oCont);
// Destroy the original
DestroyObject(oItem);
}

return;
}

// Otherwise, we generate 1-3 items, possibly convert some
// to gold.
int nItems = CTG_GetNumItems();
int nItemsCreated = 0;
object oItem = OBJECT_INVALID;

// Keep track of items handed out to avoid dupes
object oItem1 = OBJECT_INVALID;
object oItem2 = OBJECT_INVALID;

// Random number -- position of item to hand out
int nRandom = 0;

while (nItemsCreated < nItems) {
nItemsCreated++;
if (nBaseType1 == BASE_ITEM_INVALID && CTG_IsItemGold() )
{
CTG_CreateGoldTreasure(nTreasureType, oAdventurer, oCont);
}
else
{
nRandom = Random(nItemsInBaseCont);

if (nBaseType1 == BASE_ITEM_INVALID)
{
// we're not checking base types
oItem = CTG_GetTreasureItem(oBaseCont, nRandom);
}
else
{
oItem = CTG_GetSpecificBaseTypeTreasureItem(oBaseCont,
nRandom,
nBaseType1,
nBaseType2,
nBaseType3);
}

if (!GetIsObjectValid(oItem))
{
// Ugh, no matching item found!
// Bad module designer, no cookie.
CTG_CreateDefaultTreasure(nTreasureType, oAdventurer, oCont);
}
else if ( nItemsCreated > 1 &&
(GetTag(oItem) == GetTag(oItem1) || GetTag(oItem) == GetTag(oItem2)) )
{
// Ugh, duplicate item. Make gold instead.
CTG_CreateGoldTreasure(nTreasureType, oAdventurer, oCont);
}
else
{
// Make the item
CopyItem(oItem, oCont);
if (nItemsCreated == 1) {
oItem1 = oItem;
} else {
// if this is the third item, it doesn't matter
// anyway, so we might as well save the conditional.
oItem2 = oItem;
}
}
}
}
}

// Create gold treasure in the specified container.
void CTG_CreateGoldTreasure(int nTreasureType,
object oAdventurer,
object oCont=OBJECT_SELF)
{
// Just use the default generation scripts
CreateGold(oCont, oAdventurer, nTreasureType);
}


// Create treasure on an NPC.
// This function will typically be called from within the
// NPC's OnSpawn handler.
// Note that this defaults to TREASURE_TYPE_MONSTER, which uses
// the monster-specific treasure chests and falls back to low-
// level treasure if none exist.
void CTG_GenerateNPCTreasure(int nTreasureType=5, object oNPC=OBJECT_SELF)
{

// Locate the base container
object oBaseCont = CTG_GetNearestBaseContainer(nTreasureType,
oNPC);

// Make sure we have a valid base container
if (!GetIsObjectValid(oBaseCont)) {
// if not, generate treasure using default method from
// nw_o2_coninclude.
if (nTreasureType == TREASURE_TYPE_MONSTER)
GenerateNPCTreasure(TREASURE_TYPE_LOW, oNPC);
else
GenerateNPCTreasure(nTreasureType, oNPC);
return;
}

// Now we determine whether we put treasure on the NPC
int nRacialType = GetRacialType(oNPC);
switch (nRacialType) {
case RACIAL_TYPE_ANIMAL:
case RACIAL_TYPE_BEAST:
case RACIAL_TYPE_MAGICAL_BEAST:
case RACIAL_TYPE_VERMIN:
// No treasure, sorry.
return;
}

if (nTreasureType == TREASURE_TYPE_MONSTER) {

if (d100() < BK_CHANCE_OF_N0_MONSTERTREASURE) {
return;
}
}

// Otherwise, generate as usual
CTG_CreateTreasure(nTreasureType, oNPC, oNPC);
}



/**********************************************************************
* Boring type-checking functions.
**********************************************************************/


// Check if the item's base type is of the given base type
int CTG_GetIsBaseType(int nItemBaseType,
int nBaseType1=BASE_ITEM_INVALID,
int nBaseType2=BASE_ITEM_INVALID,
int nBaseType3=BASE_ITEM_INVALID)
{
return ( (nItemBaseType != BASE_ITEM_INVALID)
&& (
nItemBaseType == nBaseType1
|| nItemBaseType == nBaseType2
|| nItemBaseType == nBaseType3) );
}

// Check if the item's base type is a weapon
int CTG_GetIsWeapon(int nItemBaseType)
{
return (
nItemBaseType == BASE_ITEM_ARROW
|| nItemBaseType == BASE_ITEM_BASTARDSWORD
|| nItemBaseType == BASE_ITEM_BATTLEAXE
|| nItemBaseType == BASE_ITEM_BOLT
|| nItemBaseType == BASE_ITEM_BULLET
|| nItemBaseType == BASE_ITEM_CBLUDGWEAPON
|| nItemBaseType == BASE_ITEM_CLUB
|| nItemBaseType == BASE_ITEM_CPIERCWEAPON
|| nItemBaseType == BASE_ITEM_CSLASHWEAPON
|| nItemBaseType == BASE_ITEM_CSLSHPRCWEAP
|| nItemBaseType == BASE_ITEM_DAGGER
|| nItemBaseType == BASE_ITEM_DART
|| nItemBaseType == BASE_ITEM_DIREMACE
|| nItemBaseType == BASE_ITEM_DOUBLEAXE
|| nItemBaseType == BASE_ITEM_GREATAXE
|| nItemBaseType == BASE_ITEM_GREATSWORD
|| nItemBaseType == BASE_ITEM_GRENADE
|| nItemBaseType == BASE_ITEM_HALBERD
|| nItemBaseType == BASE_ITEM_HANDAXE
|| nItemBaseType == BASE_ITEM_HEAVYCROSSBOW
|| nItemBaseType == BASE_ITEM_HEAVYFLAIL
|| nItemBaseType == BASE_ITEM_KAMA
|| nItemBaseType == BASE_ITEM_KATANA
|| nItemBaseType == BASE_ITEM_KUKRI
|| nItemBaseType == BASE_ITEM_LIGHTCROSSBOW
|| nItemBaseType == BASE_ITEM_LIGHTFLAIL
|| nItemBaseType == BASE_ITEM_LIGHTHAMMER
|| nItemBaseType == BASE_ITEM_LIGHTMACE
|| nItemBaseType == BASE_ITEM_LONGBOW
|| nItemBaseType == BASE_ITEM_LONGSWORD
|| nItemBaseType == BASE_ITEM_MORNINGSTAR
|| nItemBaseType == BASE_ITEM_QUARTERSTAFF
|| nItemBaseType == BASE_ITEM_RAPIER
|| nItemBaseType == BASE_ITEM_SCIMITAR
|| nItemBaseType == BASE_ITEM_SCYTHE
|| nItemBaseType == BASE_ITEM_SHORTBOW
|| nItemBaseType == BASE_ITEM_SHORTSPEAR
|| nItemBaseType == BASE_ITEM_SHORTSWORD
|| nItemBaseType == BASE_ITEM_SHURIKEN
|| nItemBaseType == BASE_ITEM_SICKLE
|| nItemBaseType == BASE_ITEM_SLING
|| nItemBaseType == BASE_ITEM_THROWINGAXE
|| nItemBaseType == BASE_ITEM_TWOBLADEDSWORD
|| nItemBaseType == BASE_ITEM_WARHAMMER);
}

// Check if the item's base type is a weapon but not ammunition
int CTG_GetIsWeaponNoammo(int nItemBaseType)
{
return ( CTG_GetIsWeapon(nItemBaseType)
&& (nItemBaseType != BASE_ITEM_ARROW
|| nItemBaseType != BASE_ITEM_BOLT
|| nItemBaseType != BASE_ITEM_BULLET)
);
}

// Check if the item's base type is a ranged weapon
int CTG_GetIsRangedWeapon(int nItemBaseType)
{
return (nItemBaseType == BASE_ITEM_DART
|| nItemBaseType == BASE_ITEM_GRENADE
|| nItemBaseType == BASE_ITEM_HEAVYCROSSBOW
|| nItemBaseType == BASE_ITEM_LIGHTCROSSBOW
|| nItemBaseType == BASE_ITEM_LONGBOW
|| nItemBaseType == BASE_ITEM_SHORTBOW
|| nItemBaseType == BASE_ITEM_SHURIKEN
|| nItemBaseType == BASE_ITEM_SLING
|| nItemBaseType == BASE_ITEM_THROWINGAXE);
}

// Check if the item's base type is a melee weapon
int CTG_GetIsMeleeWeapon(int nItemBaseType)
{
return (
nItemBaseType == BASE_ITEM_BASTARDSWORD
|| nItemBaseType == BASE_ITEM_BATTLEAXE
|| nItemBaseType == BASE_ITEM_CLUB
|| nItemBaseType == BASE_ITEM_DAGGER
|| nItemBaseType == BASE_ITEM_DIREMACE
|| nItemBaseType == BASE_ITEM_DOUBLEAXE
|| nItemBaseType == BASE_ITEM_GREATAXE
|| nItemBaseType == BASE_ITEM_GREATSWORD
|| nItemBaseType == BASE_ITEM_HALBERD
|| nItemBaseType == BASE_ITEM_HANDAXE
|| nItemBaseType == BASE_ITEM_HEAVYFLAIL
|| nItemBaseType == BASE_ITEM_KAMA
|| nItemBaseType == BASE_ITEM_KATANA
|| nItemBaseType == BASE_ITEM_KUKRI
|| nItemBaseType == BASE_ITEM_LIGHTFLAIL
|| nItemBaseType == BASE_ITEM_LIGHTHAMMER
|| nItemBaseType == BASE_ITEM_LIGHTMACE
|| nItemBaseType == BASE_ITEM_LONGSWORD
|| nItemBaseType == BASE_ITEM_MORNINGSTAR
|| nItemBaseType == BASE_ITEM_QUARTERSTAFF
|| nItemBaseType == BASE_ITEM_RAPIER
|| nItemBaseType == BASE_ITEM_SCIMITAR
|| nItemBaseType == BASE_ITEM_SCYTHE
|| nItemBaseType == BASE_ITEM_SHORTSPEAR
|| nItemBaseType == BASE_ITEM_SHORTSWORD
|| nItemBaseType == BASE_ITEM_SICKLE
|| nItemBaseType == BASE_ITEM_TWOBLADEDSWORD
|| nItemBaseType == BASE_ITEM_WARHAMMER);
}

// Check if the item's base type is armor
int CTG_GetIsArmor(int nItemBaseType)
{
return (nItemBaseType == BASE_ITEM_ARMOR
|| nItemBaseType == BASE_ITEM_LARGESHIELD
|| nItemBaseType == BASE_ITEM_SMALLSHIELD
|| nItemBaseType == BASE_ITEM_TOWERSHIELD);
}

// Check if the item's base type is clothing
int CTG_GetIsClothing(int nItemBaseType)
{
return (nItemBaseType == BASE_ITEM_BELT
|| nItemBaseType == BASE_ITEM_BOOTS
|| nItemBaseType == BASE_ITEM_BRACER
|| nItemBaseType == BASE_ITEM_CLOAK
|| nItemBaseType == BASE_ITEM_GLOVES);
}

// Tack on the appropriate racialtype suffix
string CTG_GetRacialtypeChestTag(string sBaseTag, object oSource)
{
string sCont = sBaseTag + "_";
switch (GetRacialType(oSource)) {
case RACIAL_TYPE_INVALID: return "";
case RACIAL_TYPE_ABERRATION: sCont = sCont + "ABERRATION"; break;
case RACIAL_TYPE_ANIMAL: sCont = sCont + "ANIMAL"; break;
case RACIAL_TYPE_BEAST: sCont = sCont + "BEAST"; break;
case RACIAL_TYPE_CONSTRUCT: sCont = sCont + "CONSTRUCT"; break;
case RACIAL_TYPE_DRAGON: sCont = sCont + "DRAGON"; break;
case RACIAL_TYPE_DWARF: sCont = sCont + "DWARF"; break;
case RACIAL_TYPE_ELEMENTAL: sCont = sCont + "ELEMENTAL"; break;
case RACIAL_TYPE_ELF: sCont = sCont + "ELF"; break;
case RACIAL_TYPE_FEY: sCont = sCont + "FEY"; break;
case RACIAL_TYPE_GIANT: sCont = sCont + "GIANT"; break;
case RACIAL_TYPE_GNOME: sCont = sCont + "GNOME"; break;
case RACIAL_TYPE_HALFELF: sCont = sCont + "HALFELF"; break;
case RACIAL_TYPE_HALFLING: sCont = sCont + "HALFLING"; break;
case RACIAL_TYPE_HALFORC: sCont = sCont + "HALFORC"; break;
case RACIAL_TYPE_HUMAN: sCont = sCont + "HUMAN"; break;
case RACIAL_TYPE_HUMANOID_GOBLINOID: sCont = sCont + "GOBLINOID"; break;
case RACIAL_TYPE_HUMANOID_MONSTROUS: sCont = sCont + "MONSTROUS"; break;
case RACIAL_TYPE_HUMANOID_ORC: sCont = sCont + "ORC"; break;
case RACIAL_TYPE_HUMANOID_REPTILIAN: sCont = sCont + "REPTILIAN"; break;
case RACIAL_TYPE_MAGICAL_BEAST: sCont = sCont + "MAGICAL_BEAST"; break;
case RACIAL_TYPE_OUTSIDER: sCont = sCont + "OUTSIDER"; break;
case RACIAL_TYPE_SHAPECHANGER: sCont = sCont + "SHAPECHANGER"; break;
case RACIAL_TYPE_UNDEAD: sCont = sCont + "UNDEAD"; break;
case RACIAL_TYPE_VERMIN: sCont = sCont + "VERMIN"; break;
}

return sCont;
}


/*
void main() {}
/* */
[/code:1:5c295631a6]

faethor33

28/02/2007 20:34:52

Por fin funciona. Sustituí el script que pusiste por el que había. Solo que no modifiqué el script que tiene asociado "x0_o2_anyhigh", en su lugar modifiqué este otro:

"mo_mdj_tesoro1"

#include "NW_O2_CONINCLUDE"
#include "x0_i0_treasure"
#include "mo_mdj_tiempo"

void main()
{
object oPC=GetLastOpenedBy();//El ultimo pj que abrió el cofre
object oTarget=OBJECT_SELF;//El cofre

int iHor=GetHourTimeZero();//La hora actual del server (la recoge del script mo_mdj_tiempo)
int iTie=GetLocalInt(oTarget,"tesoro");//REcoge la hora que se abrió por ultima vez el cofre
iTie=iHor-iTie;//Comprobamos que haya pasado el tiempo necesario para generar el tesoro

if(iTie<0)return;//Si no ha pasado el tiempo, paramos el script
iHor=iHor+10;//Si ha pasado el tiempo (en este caso 10h) se lo sumamos a la hora actual. Aqui es donde se regula el tiempo de regeneracion
SetLocalInt(oTarget,"tesoro",iHor);//Guardamos la hora a la que debe volver a crear tesoro este cofre

int iNum=Random(3);//Marcamos un valor aleatorio de tesoros que saldran en el cofre el minimo es 1, el maximo es el numero entre parentesis +1
while(iNum>=0)//Creamos el tesoro
{
CTG_CreateTreasure(TREASURE_TYPE_HIGH, GetLastOpener(), OBJECT_SELF);
iNum-=1;
}
/* Para generar otro tipo de tesoros se usan estas lineas sustituyendo a la otra:
GenerateMediumTreasure(oPC,oTarget); <--- Para un tesoro medio
GenerateHighTreasure(oPC,oTarget); <--- Para un tesoro alto
GenerateBossTreasure(oPC,oTarget); <--- Para un tesoro unico
*/
}

La alegria que me dió cuando vi que regeneraba en el tiempo marcado.

Muchisimas gracias Althor.

Saludos!

AlthorDeMalavir

28/02/2007 23:14:22

Me alegra de que te funcione, ves, haciendo un buen uso del foro todo va mejor ;)

faethor33

01/03/2007 19:39:15

Ya te digo. Me tenía comida la moral el tema ese.
Amenazo con volver con más dudas Althor :D
Gracias de nuevo.

ppmateos

25/05/2007 23:54:50

Yo estoy intentando hacer un sistema de regeneracion de cofres pero no doy bien con ello.

EDITO:

Ya he modificado el X0_i0_treasure

Ahora me va todo bien, salen los objetos que yo kiero de 4 cofres base que tengo.

El problema es que no se como hacer que estos cofres regeneren, en los eventos de los cofres que abriran los pj´s estan puestos en OnDeath y en OnUsed los x0_o2_anylow, hig, med y uniq.

¿Tengo que modificar estos códigos para que los cofres regeneren el tesoro?

¿Alguien me podría echar una manita? es que he probado a poner los codigos de feathor33 pero no me van, esos lo que me hacen es regenerar los cofres, pero solo me dan objetos cutres (vamos ke no son los ke pongo yo en los cofres base)

Sólo me falta eso, hacer ke mis cofres puedan regenerar el tesoro pasado x tiempo

AlthorDeMalavir

27/05/2007 02:29:49

Pues segun parece has de usar este script en el onUsed y en el onDeath del cofre, llamado por ejemplo mo_mdj_teshigh porque es para tesoros altos.

[code:1:5718938aab]
#include "NW_O2_CONINCLUDE"
#include "x0_i0_treasure"
#include "mo_mdj_tiempo"

void main()
{
object oPC=GetLastOpenedBy();//El ultimo pj que abrió el cofre
object oTarget=OBJECT_SELF;//El cofre

int iHor=GetHourTimeZero();//La hora actual del server (la recoge del script mo_mdj_tiempo)
int iTie=GetLocalInt(oTarget,"tesoro");//REcoge la hora que se abrió por ultima vez el cofre
iTie=iHor-iTie;//Comprobamos que haya pasado el tiempo necesario para generar el tesoro

if(iTie<0)return;//Si no ha pasado el tiempo, paramos el script
iHor=iHor+10;//Si ha pasado el tiempo (en este caso 10h) se lo sumamos a la hora actual. Aqui es donde se regula el tiempo de regeneracion
SetLocalInt(oTarget,"tesoro",iHor);//Guardamos la hora a la que debe volver a crear tesoro este cofre

int iNum=Random(3);//Marcamos un valor aleatorio de tesoros que saldran en el cofre el minimo es 1, el maximo es el numero entre parentesis +1
while(iNum>=0)//Creamos el tesoro
{
CTG_CreateTreasure(TREASURE_TYPE_HIGH, GetLastOpener(), OBJECT_SELF);
iNum-=1;
}
/* Para generar otro tipo de tesoros se usan estas lineas sustituyendo a la otra:
GenerateMediumTreasure(oPC,oTarget); <--- Para un tesoro medio
GenerateHighTreasure(oPC,oTarget); <--- Para un tesoro alto
GenerateBossTreasure(oPC,oTarget); <--- Para un tesoro unico
*/
}
[/code:1:5718938aab]

y luego crear otro script a parte sin meterlo en ningun evento llamado mo_mdj_tiempo y con el siguiente codigo

[code:1:5718938aab]
int GetHourTimeZero(int iYear = 99999, int iMonth = 99, int iDay = 99, int iHour = 99)
{
if (iYear > 30000)
iYear = GetCalendarYear();
if (iMonth > 12)
iMonth = GetCalendarMonth();
if (iDay > 2
iDay = GetCalendarDay();
if (iHour > 23)
iHour = GetTimeHour();

int iHourTimeZero = (iYear)*12*28*24 + (iMonth-1)*28*24 + (iDay-1)*24 + iHour;
return iHourTimeZero;
}
[/code:1:5718938aab]

Eso creo entender yo, ademas de meter el script que habia dicho yo para sustituir el que lleva el juego

ppmateos

27/05/2007 12:25:53

Ese ultimo codigo sería el mo_mdj tiempo, no? es que ese lo intento compilar pero me da fallo de compilación.

Respecto al codigo que hay justo encima de ese, o sea el que se supone que es el mo_medj_tesoro1, ¿qué tendria que cambiar para que me diera por ejemplo algo del cofre que tiene cosas para level altos?

¿en el OnDeath sigo dejando los x0_o2_anylow, hig, med y uniq y los quito del OnUsed para meter los de mo_medj_tesoro?

Es que ya te digo, ahoramismo los cofres me dan lo que quiero, lo único que no regeneran y cuando he probado a meter esos codigos los codigos me regeneran pero no me dan lo que quiero de los cofres base y por eso pensé que modificando los x0_o2_any(low,med,hig o uniq) o incluirlos en algun script...

jeje vaya lio

PD: llega un momento en el que al meter objetos en un cofre ya no puedo meter más, me sale una pantalla de esas de fallo del aurora, algo del toolset, hay algún cupo para los cofres?

AlthorDeMalavir

27/05/2007 13:36:08

jeje si, me he rayado, ya esta corregido el post, si quieres cambiar el tipo de tesoro pues creas otro igual y le cambias el

CTG_CreateTreasure(TREASURE_TYPE_HIGH, GetLastOpener(), OBJECT_SELF);

y en vez de TREASURE_TYPE_HIGH pones TREASURE_TYPE_MED y lo llamas mo_mdj_tesmed y lo pones en el ondeath y en el onused del cofre, asi de simple

Otras posibilidades son:

TREASURE_TYPE_LOW
TREASURE_TYPE_MED
TREASURE_TYPE_HIGH
TREASURE_TYPE_UNIQUE

Aunque yo no uso ese sistema pero debe de funcionar asi :P

faethor33

27/05/2007 17:58:04

Si, así lo tengo yo y funciona :)

Saludos.

ppmateos

28/05/2007 00:41:21

Ok colegas, me funciona pero tengo unas dudas:

1.- El script "mo_mdj_tiempo" sigue dandome fallo al compilar, me sale una ventana que me dice: no se ha encontrado la funcion void mai() en la secuencia de comandos, ¿deseas compilarla en su lugar como secuencia de comandos condicional?

Si le respondo "si" me dice ke no se compila y que falta la funcion startingconditional () en la secuencia de comandos. Si le digo "no" tampoco se me compila bien y me dice: falta función main () en la secuencia de comandos.

Así, que habrá algun fallo, he puesto un parentesis a ver si se arreglaba en la linea:

if (iDay > 2

pero nada, pongo if (iDay > 2) y sigue sin compilar bien.

Por cierto, si al principio del script pongo:
void main()
{

si lo compilo asi me da fallo en la linea 3 de error analizando las variables




2.- Por cierto, llega un momento, al meter objetos en los cofres base que me da fallo el aurora y no puedo meter mas o se me puede llegar a petar, sabes si no se puede meter mas de un numero determinado de objetos en los cofres base?

ppmateos

28/05/2007 02:20:57

EDITO

kowalevskaya

28/05/2007 10:36:14

[quote:6fb3447b66="ppmateos"]1.- El script "mo_mdj_tiempo" sigue dandome fallo al compilar, me sale una ventana que me dice: no se ha encontrado la funcion void mai() en la secuencia de comandos, ¿deseas compilarla en su lugar como secuencia de comandos condicional?
Esto es porque el script void main ()

ppmateos

28/05/2007 12:02:19

EDITO

ppmateos

30/05/2007 16:00:41

Ya he conseguido hacer funcionar el script bastante bien, no es el mismo sistema de cuando empecé a realizarlo, al final quedó mucho más sencillo, es sólo ir metiendo resref de los objetos que quieres que salgan y saldrán 2 o 3 de toda la lista de las resref que se haya especificado.

Gracias a todos por la ayuda.

El_Vara

27/10/2014 17:03:23

Esto sirve para criaturas?

AlthorDeMalavir

27/10/2014 22:12:17

Si

El_Vara

31/10/2014 13:30:35

¿Tengo una duda, se le podría añadir a cada nivel de cofres por ejemplo otros dos cofres?

Por ejemplo: Cofre nivel alto tiene un cofre donde meter objetos ahora mismo, se podría hacer que tuviera dos?

AlthorDeMalavir

31/10/2014 20:13:22

Se podría, pero no se lo complicado que podría ser, no se si valdría solo modificando que cuente los cofres nuevos y añadiendo esos cofres al script de configuración, o habría que modificar mas cosas.

Ese sistema es bastante antiguo y en su primera versión y no lo he vuelto a tocar, el que tengo programado ahora usa el mismo sistema de cofres pero el resto no se parece en nada.