4CGS-ItemGiver/ItemGiver.cs

321 lines
15 KiB
C#

// Sammelsystem - Giver v0.7.1
// "4CGS-Init" in die Objektbeschreibung eintragen, um ein Objekt zu initialsieren oder die Werte neu zu setzen
integer m_num_slots = 8; // ANzahl Slots, die der Spieler hat
integer m_max_slots = 8; // Anzahl mx. erreichbare Slots
key klicker = NULL_KEY; // Wer hat geklickt?
string m_itemName = "navi_wasserbeutel"; // Name für den Pfad, unter dem dieses Objekt auf dem Server verwaltet wird.
string m_displayName = "Na'vi Wasserbeutel"; // Angezeigter Name des Sammelobjektes
string m_desc = "Ein voller Na'vi Wasserbeutel."; // Kurzbeschreibung
string m_item_weight = "5.5"; // Gewicht des Gegenstandes (für max. Ztaglast benötigt)
string m_desc_long = "Wasserbeutel werden für den Transport von Flüssigkeiten benutzt. Sie fassen ca. 1/2 Liter Wasser. Die Na'vi stellen diese Behälter aus verschiednen Ledersorten, Riemen und Hölzern her. "; // Anschauen Text
string m_eat = "Trinken"; // Button-Text für Aktion
string m_watch = "Anschauen"; // Button-Text, um die lange Beschreibung zu lesen (Anschauen).
string m_use = "Anwenden"; // Button-Text, wenn Item auf jmd. angewendet wird,
string m_xp = "5"; // XP, die man fürs Benutzen bekommt.
string m_xp_collect = "2"; // XP, die man fürs Sammlen bekommt.
string m_hp = "5"; // Wieviel HP werde abgezogen? (Negative Werte addieren HP)
string m_food = "0"; // Wieviel Nahrung wird dazu addiert? (Negative Werte ziehen Nahrung ab)
string m_water = "50"; // Wieviel Wasser wird dazu addiert? (Negative Werte ziehen Wasser ab)
float m_range = 5.0; // Wie weit darf der Avatar vom Giver entfernt sein (1 ... 96m, 0 = Beliebig)
integer m_time_fix = 3; // Zeit, wie lange das Objekt unsichtbar ist (in Sekunden). Wenn 0 = Deaktiviert
integer m_time_rnd = 0; // Zufällige Zeit, die der Fixzeit hinzuaddiert wird und die zwischen 0 und dem hier angegebenen Wert liegt.
integer m_rnd = -3; // Wenn > 1, wird eine zufällige Anzahl von 1 ... m_rnd gesammelt. Wenn Wert negativ, dann diese Anzahl dazu rechnen.
integer m_minlevel = 0; // Wenn Sammler einen kleineren Level hat, entscheidet der Zufall, ob er das Itam bekommt.
integer m_isunique = FALSE; // Falls TRUE, wird beim "Entsorgen" abgefragt, ob man das möchte.
// ####################################################################################################################################
integer m_num = 0; // Anzahl gesammelter Items
float m_weight_total = 0; // Gesamtgewicht gesammelter Items
string m_toofar = "Du bist zu weit entfernt, um '{0}' zu sammeln.";
string m_lang_noslot = "Du hast keinen Inventar Slot mehr frei!";
string m_lang_collected = "Du hast {0} x {1} genommen und {2} Erfahrungspunkte (XP) dazu bekommen.";
string m_lang_used = "Du hast {0} benutzt und {1} Erfahrungspunkte (XP) dazu bekommen.";
string m_lang_wronggroup = "Entweder Du hast nicht die richtige Gruppe aktiviert oder '{0}' hat nicht die Landgruppe.";
string m_lang_init = "Das Objekt '{0}' [Itemname: '{1}'] ] wurde initialisiert.";
string m_lang_tooheavy = "Das ist zu noch schwer für Dich. Du kannst nur max. {0}kg tragen.";
string m_lang_level_too_low = "Um '{0}' zu sammlen, musst Du mindestens Level {1} erreichen. Du bekommst aber dennoch {2} Erfahrungspunkte (XP) dazu.";
default
{
state_entry()
{
llSetAlpha(255, ALL_SIDES);
if(llGetObjectDesc() == "4CGS-Init")
{
llSetObjectDesc("");
llOwnerSay(osFormatString(m_lang_init, [m_displayName, m_itemName]));
list _dataStorage = getDataListFromDataStorage("item." + m_itemName);
_dataStorage = setDataEntryInDataList(_dataStorage, "image", llGetInventoryKey(llGetInventoryName(INVENTORY_TEXTURE, 0)));
_dataStorage = setDataEntryInDataList(_dataStorage, "displayname", m_displayName);
_dataStorage = setDataEntryInDataList(_dataStorage, "beschreibung", m_desc);
_dataStorage = setDataEntryInDataList(_dataStorage, "unique", m_isunique);
_dataStorage = setDataEntryInDataList(_dataStorage, "weight", m_item_weight);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions", "eat;watch;futtern");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.eat.displayname", m_eat);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.eat.consume", "TRUE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.eat.setTarget", "FALSE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.eat.tasks", "addFood:" + (string)m_food + ";addWater:" + (string)m_water + ";addXP:" + (string)m_xp + ";addHP:" + (string)m_hp);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.watch.displayname", m_watch);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.watch.consume", "FALSE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.watch.setTarget", "FALSE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.watch.tasks", "say:" + m_desc_long);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.futtern.displayname", m_use);
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.futtern.consume", "TRUE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.futtern.setTarget", "TRUE");
_dataStorage = setDataEntryInDataList(_dataStorage, "actions.futtern.tasks", "addFood:" + (string)m_food + ";addWater:" + (string)m_water + ";addHP:" + (string)m_hp + ";addXP:" + (string)m_xp);
saveDataListToDataStorage(_dataStorage, "item." + m_itemName);
}
}
touch_start(integer i)
{
klicker = llDetectedKey(0);
list _dataStorage = getDataListFromDataStorage("game.hud.player." + llDetectedKey(0));
integer _slot = getNextFreeInventorySlot(_dataStorage, m_itemName);
integer _level = llList2Integer(calcLevelData(_dataStorage), 0);
integer m_num = 1;
if(m_rnd > 1)
m_num = (integer)(llFrand(m_rnd) + 1);
else if (m_rnd < 0)
m_num = - m_rnd;
m_weight_total = m_num * (float)m_item_weight;
if(!llSameGroup(klicker))
{
llRegionSayTo(klicker, 0, osFormatString(m_lang_wronggroup, [m_displayName]));
return;
}
if(getMaxPlayerWeight(_dataStorage) < calcPlayerWeight(_dataStorage) + m_weight_total)
{
llOwnerSay(osFormatString(m_lang_tooheavy, [llGetSubString((string)getMaxPlayerWeight(_dataStorage), 0, llSubStringIndex((string)getMaxPlayerWeight(_dataStorage), ".") + 2)]));
return;
}
if(_slot == 0)
{
llRegionSayTo(klicker, 0, m_lang_noslot);
return;
}
if(m_range != 0.0)
llSensor("",klicker, AGENT_BY_LEGACY_NAME, m_range, PI);
else
state sammeln;
}
sensor(integer x)
{
state sammeln;
}
no_sensor()
{
llInstantMessage(klicker, osFormatString(m_toofar, [m_displayName]));
}
timer()
{
llSetTimerEvent(0);
llResetScript();
}
changed(integer change)
{
if(change & (CHANGED_REGION_RESTART | CHANGED_INVENTORY))
llResetScript();
}
}
// ###################################################################################################
state sammeln
{
state_entry()
{
list _dataStorage = getDataListFromDataStorage("game.hud.player." + klicker);
integer _slot = getNextFreeInventorySlot(_dataStorage, m_itemName);
integer _level = llList2Integer(calcLevelData(_dataStorage), 0);
integer _xp = (integer)getDataEntryFromDataList(_dataStorage, "stats.xp");
if(_level >= (integer)m_minlevel)
{
llRegionSayTo(klicker, 0, osFormatString(m_lang_collected, [(string)m_num, m_displayName, (string)(m_num * (integer)m_xp_collect)]));
_dataStorage = setDataEntryInDataList(_dataStorage, "stats.xp", _xp + (m_num * (integer) m_xp_collect));
_dataStorage = setDataEntryInDataList(_dataStorage, "inventar.slot." + _slot, m_itemName);
_dataStorage = setDataEntryInDataList(_dataStorage, "inventar.slot." + _slot + ".count", getItemCountFromSlot(_dataStorage, _slot) + m_num);
}
else
{
//m_num = 0;
_dataStorage = setDataEntryInDataList(_dataStorage, "stats.xp", _xp + m_xp_collect);
llRegionSayTo(klicker, 0, osFormatString(m_lang_level_too_low, [m_displayName, _level, (string)m_xp_collect]));
}
_dataStorage = setDataEntryInDataList(_dataStorage, "stats.xp", _xp + (m_num * (integer) m_xp_collect));
_dataStorage = setDataEntryInDataList(_dataStorage, "inventar.slot." + _slot, m_itemName);
_dataStorage = setDataEntryInDataList(_dataStorage, "inventar.slot." + _slot + ".count", getItemCountFromSlot(_dataStorage, _slot) + m_num);
saveDataListToDataStorage(_dataStorage, ("game.hud.player." + klicker));
llSay((integer)getDataEntryFromDataList(_dataStorage, "channel"), "gamecommand;reload");
if(m_time_fix + m_time_rnd == 0)
state default;
else
{
llSetAlpha(0, ALL_SIDES);
llSetTimerEvent(m_time_fix + (integer)llFrand(m_time_rnd));
}
}
timer()
{
llSetTimerEvent(0);
llResetScript();
}
changed(integer change)
{
if(change & (CHANGED_REGION_RESTART | CHANGED_INVENTORY))
llResetScript();
}
}
// ###################################################################################################
integer getNextFreeInventorySlot(list _dataStorage, string _itemName)
{
integer _freeSlot = 0;
integer _currentSlot;
for(_currentSlot = 1; _currentSlot <= m_num_slots; ++_currentSlot)
{
if(getDataEntryFromDataList(_dataStorage, "inventar.slot." + _currentSlot) == _itemName)
return _currentSlot;
if(getDataEntryFromDataList(_dataStorage, "inventar.slot." + _currentSlot) == "")
if(_freeSlot == 0)
_freeSlot = _currentSlot;
}
return _freeSlot;
}
integer getItemCountFromSlot(list _dataStorage, integer _slot)
{
return (integer)getDataEntryFromDataList(_dataStorage, "inventar.slot." + _slot + ".count");
}
list getDataListFromDataStorage(string _storage)
{
return llCSV2List(osGetDataValue(_storage));
}
saveDataListToDataStorage(list _dataList, string _storage)
{
string _csv = llList2CSV(_dataList);
osSetDataValue(_storage, _csv);
}
integer checkDataEntryInDataList(list _dataList, string _key)
{
integer _inListPosition = llListFindList(_dataList, [_key]);
if(_inListPosition == -1)
return FALSE;
return TRUE;
}
string getDataEntryFromDataList(list _dataList, string _key)
{
integer _inListPosition = llListFindList(_dataList, [_key]);
if(_inListPosition == -1)
return "";
return llList2String(_dataList, _inListPosition + 1);
}
list setDataEntryInDataList(list _dataList, string _key, string _value)
{
integer _inListPosition = llListFindList(_dataList, [_key]);
if(_inListPosition == -1)
{
_dataList += [_key, _value];
return _dataList;
}
return llListReplaceList(_dataList, [_value], _inListPosition + 1, _inListPosition + 1);
}
integer calcPlayerWeight(list _userStorage)
{
integer _currentSlot;
integer _currentWeight = 0;
for(_currentSlot = 1; _currentSlot <= m_num_slots; ++_currentSlot)
{
if(getDataEntryFromDataList(_userStorage, "inventar.slot." + _currentSlot) != "")
{
string _itemName = getDataEntryFromDataList(_userStorage, "inventar.slot." + _currentSlot);
list _itemData = getDataListFromDataStorage("item." +_itemName);
integer _itemCount = getItemCountFromSlot(_userStorage, _currentSlot);
integer _itemWeight = (integer)getDataEntryFromDataList(_itemData, "weight");
_currentWeight = _currentWeight + (_itemCount * _itemWeight);
}
}
return _currentWeight;
}
list calcLevelData(list _dataStorage)
{
list _dataStore = getDataListFromDataStorage("game.hud");
integer _xpLevelStep = (integer)getDataEntryFromDataList(_dataStore, "stats.levels.firstStep");
integer _maxlevel = (integer)getDataEntryFromDataList(_dataStore, "stats.levels.maxlevel");
float _xpLevelStepMultiplier = (float)getDataEntryFromDataList(_dataStore, "stats.levels.multiplier");
integer _currentXP = (integer)getDataEntryFromDataList(_dataStorage, "stats.xp");
integer _currentLevel = 0;
integer _xpNeedForNextLevel = _xpLevelStep * _xpLevelStepMultiplier;
while(_currentXP > _xpNeedForNextLevel)
{
if(_currentLevel <= _maxlevel)
{
_currentLevel = _currentLevel + 1;
_currentXP = _currentXP - _xpNeedForNextLevel;
_xpNeedForNextLevel = (_xpNeedForNextLevel * _xpLevelStepMultiplier);
}
}
return [_currentLevel, (integer)_currentXP, _xpNeedForNextLevel];
}
float getMaxPlayerWeight(list _dataStorage)
{
list _dataStore = getDataListFromDataStorage("game.hud");
integer _maxweight = (integer)getDataEntryFromDataList(_dataStore, "stats.levels.maxweight");
float _xpMultiplier = (float)getDataEntryFromDataList(_dataStore, "stats.levels.multiplier");
list _levelData = calcLevelData(_dataStorage);
integer _playerLevel = llList2Integer(_levelData, 0) + 1;
float _playerMaxWight = _maxweight * (_playerLevel * _xpMultiplier);
return _playerMaxWight;
}